LLVM: lib/MC/WinCOFFObjectWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

40#include

41#include

42#include

43#include

44#include

45#include

46#include

47

48using namespace llvm;

50

51#define DEBUG_TYPE "WinCOFFObjectWriter"

52

53namespace {

54

55constexpr int OffsetLabelIntervalBits = 20;

56

58

59enum AuxiliaryType { ATWeakExternal, ATFile, ATSectionDefinition };

60

61struct AuxSymbol {

62 AuxiliaryType AuxType;

64};

65

66class COFFSection;

67

68class COFFSymbol {

69public:

71

73

75 int Index = 0;

76 AuxiliarySymbols Aux;

77 COFFSymbol *Other = nullptr;

78 COFFSection *Section = nullptr;

79 int Relocations = 0;

81

82 COFFSymbol(StringRef Name) : Name(Name) {}

83

85

86 int64_t getIndex() const { return Index; }

87 void setIndex(int Value) {

89 if (MC)

91 }

92};

93

94

95struct COFFRelocation {

97 COFFSymbol *Symb = nullptr;

98

99 COFFRelocation() = default;

100

102};

103

104using relocations = std::vector;

105

106class COFFSection {

107public:

109

110 std::string Name;

113 COFFSymbol *Symbol = nullptr;

114 relocations Relocations;

115

116 COFFSection(StringRef Name) : Name(std::string(Name)) {}

117

119};

120}

121

126

127 using symbols = std::vector<std::unique_ptr>;

128 using sections = std::vector<std::unique_ptr>;

129

132

134

135

137 sections Sections;

138 symbols Symbols;

140

141

142 section_map SectionMap;

143 symbol_map SymbolMap;

144

145 symbol_list WeakDefaults;

146

147 bool UseBigObj;

148 bool UseOffsetLabels = false;

149

150public:

156

158 DwoMode Mode);

159

167

168private:

170 COFFSymbol *createSymbol(StringRef Name);

171 COFFSymbol *getOrCreateCOFFSymbol(const MCSymbol &Sym);

172 COFFSection *createSection(StringRef Name);

173

175

176 COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);

177 void defineSymbol(const MCSymbolCOFF &Symbol);

178

179 void SetSymbolName(COFFSymbol &S);

180 void SetSectionName(COFFSection &S);

181

182 bool isUninitializedData(const COFFSection &S);

183

184

185 void WriteFileHeader(const COFF::header &Header);

186 void WriteSymbol(const COFFSymbol &S);

187 void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);

188 void writeSectionHeaders();

191 void writeSection(const COFFSection &Sec);

192

193 void createFileSymbols();

194 void setWeakDefaultNames();

195 void assignSectionNumbers();

196 void assignFileOffsets();

197};

198

200 std::unique_ptr MOTW, raw_pwrite_stream &OS)

201 : TargetObjectWriter(std::move(MOTW)),

205 std::unique_ptr MOTW, raw_pwrite_stream &OS,

207 : TargetObjectWriter(std::move(MOTW)),

212

216

217

218

219

220

221

222

223void COFFSymbol::set_name_offset(uint32_t Offset) {

226}

227

228

229

230

234 Header.Machine = OWriter.TargetObjectWriter->getMachine();

235

236

237

238

240}

241

242COFFSymbol *WinCOFFWriter::createSymbol(StringRef Name) {

243 Symbols.push_back(std::make_unique(Name));

244 return Symbols.back().get();

245}

246

247COFFSymbol *WinCOFFWriter::getOrCreateCOFFSymbol(const MCSymbol &Sym) {

248 COFFSymbol *&Ret = SymbolMap[&Sym];

249 if (!Ret)

250 Ret = createSymbol(Sym.getName());

251 return Ret;

252}

253

254COFFSection *WinCOFFWriter::createSection(StringRef Name) {

255 Sections.emplace_back(std::make_unique(Name));

256 return Sections.back().get();

257}

258

261 case 1:

263 case 2:

265 case 4:

267 case 8:

269 case 16:

271 case 32:

273 case 64:

275 case 128:

277 case 256:

279 case 512:

281 case 1024:

283 case 2048:

285 case 4096:

287 case 8192:

289 }

291}

292

293

294

295void WinCOFFWriter::defineSection(const MCSectionCOFF &MCSec) {

296 COFFSection *Section = createSection(MCSec.getName());

297 COFFSymbol *Symbol = createSymbol(MCSec.getName());

302

303

306 COFFSymbol *COMDATSymbol = getOrCreateCOFFSymbol(*S);

307 if (COMDATSymbol->Section)

309 COMDATSymbol->Section = Section;

310 }

311 }

312

313

314 Symbol->Aux.resize(1);

316 Symbol->Aux[0].AuxType = ATSectionDefinition;

317 Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();

318

319

322

323

324 Section->MCSection = &MCSec;

325 SectionMap[&MCSec] = Section;

326

327 if (UseOffsetLabels) {

328 const uint32_t Interval = 1 << OffsetLabelIntervalBits;

329 uint32_t N = 1;

330 for (uint32_t Off = Interval, E = Asm->getSectionAddressSize(MCSec);

332 auto Name = ("$L" + MCSec.getName() + "_" + Twine(N++)).str();

333 COFFSymbol *Label = createSymbol(Name);

337 Section->OffsetSymbols.push_back(Label);

338 }

339 }

340}

341

344 if (Symbol.isCommon() && Symbol.isExternal())

345 return Symbol.getCommonSize();

346

348 if (!Asm.getSymbolOffset(Symbol, Res))

349 return 0;

350

351 return Res;

352}

353

354COFFSymbol *WinCOFFWriter::getLinkedSymbol(const MCSymbol &Symbol) {

355 if (Symbol.isVariable())

356 return nullptr;

357

359 if (!SymRef)

360 return nullptr;

361

362 auto &Aliasee = static_cast<const MCSymbolCOFF &>(SymRef->getSymbol());

363 if (Aliasee.isUndefined() || Aliasee.isExternal())

364 return getOrCreateCOFFSymbol(Aliasee);

365 else

366 return nullptr;

367}

368

369

370

371void WinCOFFWriter::defineSymbol(const MCSymbolCOFF &MCSym) {

372 const MCSymbol *Base = Asm->getBaseSymbol(MCSym);

373 COFFSection *Sec = nullptr;

374 MCSectionCOFF *MCSec = nullptr;

375 if (Base && Base->getFragment()) {

376 MCSec = static_cast<MCSectionCOFF *>(Base->getFragment()->getParent());

377 Sec = SectionMap[MCSec];

378 }

379

381 return;

382

383 COFFSymbol *Sym = getOrCreateCOFFSymbol(MCSym);

384 COFFSymbol *Local = nullptr;

385 if (static_cast<const MCSymbolCOFF &>(MCSym)

386 .getWeakExternalCharacteristics()) {

388 Sym->Section = nullptr;

389

390 COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);

391 if (!WeakDefault) {

392 std::string WeakName = (".weak." + MCSym.getName() + ".default").str();

393 WeakDefault = createSymbol(WeakName);

394 if (!Sec)

396 else

397 WeakDefault->Section = Sec;

398 WeakDefaults.insert(WeakDefault);

399 Local = WeakDefault;

400 }

401

402 Sym->Other = WeakDefault;

403

404

406 memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));

407 Sym->Aux[0].AuxType = ATWeakExternal;

408 Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;

409 Sym->Aux[0].Aux.WeakExternal.Characteristics =

410 static_cast<const MCSymbolCOFF &>(MCSym)

411 .getWeakExternalCharacteristics();

412 } else {

415 else

416 Sym->Section = Sec;

418 }

419

422

423 auto &SymbolCOFF = static_cast<const MCSymbolCOFF &>(MCSym);

424 Local->Data.Type = SymbolCOFF.getType();

425 Local->Data.StorageClass = SymbolCOFF.getClass();

426

427

429 bool IsExternal =

431

434 }

435 }

436

437 Sym->MC = &MCSym;

438}

439

440void WinCOFFWriter::SetSectionName(COFFSection &S) {

442 std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());

443 return;

444 }

445

446 uint64_t StringTableEntry = Strings.getOffset(S.Name);

449}

450

451void WinCOFFWriter::SetSymbolName(COFFSymbol &S) {

453 S.set_name_offset(Strings.getOffset(S.Name));

454 else

455 std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());

456}

457

458bool WinCOFFWriter::isUninitializedData(const COFFSection &S) {

460 0;

461}

462

463

464

465

466void WinCOFFWriter::WriteFileHeader(const COFF::header &Header) {

467 if (UseBigObj) {

469 W.write<uint16_t>(0xFFFF);

471 W.write<uint16_t>(Header.Machine);

472 W.write<uint32_t>(Header.TimeDateStamp);

474 W.write<uint32_t>(0);

475 W.write<uint32_t>(0);

476 W.write<uint32_t>(0);

477 W.write<uint32_t>(0);

478 W.write<uint32_t>(Header.NumberOfSections);

479 W.write<uint32_t>(Header.PointerToSymbolTable);

480 W.write<uint32_t>(Header.NumberOfSymbols);

481 } else {

482 W.write<uint16_t>(Header.Machine);

483 W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));

484 W.write<uint32_t>(Header.TimeDateStamp);

485 W.write<uint32_t>(Header.PointerToSymbolTable);

486 W.write<uint32_t>(Header.NumberOfSymbols);

487 W.write<uint16_t>(Header.SizeOfOptionalHeader);

488 W.write<uint16_t>(Header.Characteristics);

489 }

490}

491

492void WinCOFFWriter::WriteSymbol(const COFFSymbol &S) {

494 W.write<uint32_t>(S.Data.Value);

495 if (UseBigObj)

497 else

498 W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));

499 W.write<uint16_t>(S.Data.Type);

502 WriteAuxiliarySymbols(S.Aux);

503}

504

505void WinCOFFWriter::WriteAuxiliarySymbols(

506 const COFFSymbol::AuxiliarySymbols &S) {

507 for (const AuxSymbol &i : S) {

508 switch (i.AuxType) {

509 case ATWeakExternal:

510 W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);

511 W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);

512 W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));

513 if (UseBigObj)

515 break;

516 case ATFile:

517 W.OS.write(reinterpret_cast<const char *>(&i.Aux),

519 break;

520 case ATSectionDefinition:

521 W.write<uint32_t>(i.Aux.SectionDefinition.Length);

522 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);

523 W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);

524 W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);

525 W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));

526 W.OS << char(i.Aux.SectionDefinition.Selection);

527 W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));

528 W.write<uint16_t>(

529 static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));

530 if (UseBigObj)

532 break;

533 }

534 }

535}

536

537

538void WinCOFFWriter::writeSectionHeaders() {

539

540

541

542 std::vector<COFFSection *> Arr;

543 for (auto &Section : Sections)

544 Arr.push_back(Section.get());

545 llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {

546 return A->Number < B->Number;

547 });

548

549 for (auto &Section : Arr) {

550 if (Section->Number == -1)

551 continue;

552

553 COFF::section &S = Section->Header;

554 if (Section->Relocations.size() >= 0xffff)

566 }

567}

568

569void WinCOFFWriter::WriteRelocation(const COFF::relocation &R) {

570 W.write<uint32_t>(R.VirtualAddress);

571 W.write<uint32_t>(R.SymbolTableIndex);

572 W.write<uint16_t>(R.Type);

573}

574

575

576

577

578uint32_t WinCOFFWriter::writeSectionContents(const MCSection &MCSec) {

579

580

581 SmallVector<char, 128> Buf;

582 raw_svector_ostream VecOS(Buf);

583 Asm->writeSectionData(VecOS, &MCSec);

584

585

586 W.OS << Buf;

587

588

589

590 JamCRC JC(0);

591 JC.update(ArrayRef(reinterpret_cast<uint8_t *>(Buf.data()), Buf.size()));

592 return JC.getCRC();

593}

594

595void WinCOFFWriter::writeSection(const COFFSection &Sec) {

596 if (Sec.Number == -1)

597 return;

598

599

602 "Section::PointerToRawData is insane!");

603

604 uint32_t CRC = writeSectionContents(*Sec.MCSection);

605

606

607 COFFSymbol::AuxiliarySymbols &AuxSyms = Sec.Symbol->Aux;

608 assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);

609 AuxSymbol &SecDef = AuxSyms[0];

611 } else if (isUninitializedData(Sec)) {

612

613 writeSectionContents(*Sec.MCSection);

614 }

615

616

617 if (Sec.Relocations.empty()) {

619 "Section::PointerToRelocations is insane!");

620 return;

621 }

622

624 "Section::PointerToRelocations is insane!");

625

626 if (Sec.Relocations.size() >= 0xffff) {

627

628

629 COFF::relocation R;

630 R.VirtualAddress = Sec.Relocations.size() + 1;

631 R.SymbolTableIndex = 0;

632 R.Type = 0;

633 WriteRelocation(R);

634 }

635

636 for (const auto &Relocation : Sec.Relocations)

637 WriteRelocation(Relocation.Data);

638}

639

640

641void WinCOFFWriter::createFileSymbols() {

642 for (const std::pair<std::string, size_t> &It : OWriter.getFileNames()) {

643

644 const std::string &Name = It.first;

646 unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;

647

648 COFFSymbol *File = createSymbol(".file");

652

655 for (auto &Aux : File->Aux) {

656 Aux.AuxType = ATFile;

657

658 if (Length > SymbolSize) {

659 memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);

661 } else {

663 memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);

664 break;

665 }

666

667 Offset += SymbolSize;

668 }

669 }

670}

671

672void WinCOFFWriter::setWeakDefaultNames() {

673 if (WeakDefaults.empty())

674 return;

675

676

677

678

679

680

681

682

683 COFFSymbol *Unique = nullptr;

684 for (bool AllowComdat : {false, true}) {

685 for (auto &Sym : Symbols) {

686

687 if (WeakDefaults.count(Sym.get()))

688 continue;

689

691 continue;

692

694 continue;

695 if (!AllowComdat && Sym->Section &&

697 continue;

698 Unique = Sym.get();

699 break;

700 }

701 if (Unique)

702 break;

703 }

704

705 if (!Unique)

706 return;

707 for (auto *Sym : WeakDefaults) {

708 Sym->Name.append(".");

709 Sym->Name.append(Unique->Name);

710 }

711}

712

714 return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==

716}

717

718void WinCOFFWriter::assignSectionNumbers() {

719 size_t I = 1;

722 Section.Symbol->Data.SectionNumber = I;

723 Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;

724 ++I;

725 };

726

727

728

729

730 for (const std::unique_ptr &Section : Sections)

733 for (const std::unique_ptr &Section : Sections)

736}

737

738

739void WinCOFFWriter::assignFileOffsets() {

740 unsigned Offset = W.OS.tell();

741

744

745 for (const auto &Section : *Asm) {

746 COFFSection *Sec = SectionMap[&Section];

747

748 if (!Sec || Sec->Number == -1)

749 continue;

750

751 Sec->Header.SizeOfRawData = Asm->getSectionAddressSize(Section);

752

753 if (!isUninitializedData(*Sec)) {

756 }

757

758 if (!Sec->Relocations.empty()) {

759 bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;

760

761 if (RelocationsOverflow) {

762

763

765 } else {

767 }

769

770 if (RelocationsOverflow) {

771

773 }

774

776

777 for (auto &Relocation : Sec->Relocations) {

778 assert(Relocation.Symb->getIndex() != -1);

781 Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();

782 }

783 }

784 }

785

786 assert(Sec->Symbol->Aux.size() == 1 &&

787 "Section's symbol must have one aux!");

788 AuxSymbol &Aux = Sec->Symbol->Aux[0];

789 assert(Aux.AuxType == ATSectionDefinition &&

790 "Section's symbol's aux symbol must be a Section Definition!");

796 }

797

798 Header.PointerToSymbolTable = Offset;

799}

800

802 memset(&Header, 0, sizeof(Header));

803 Header.Machine = OWriter.TargetObjectWriter->getMachine();

804 Sections.clear();

805 Symbols.clear();

806 Strings.clear();

807 SectionMap.clear();

808 SymbolMap.clear();

809 WeakDefaults.clear();

810}

811

813

814

815 for (const auto &Section : *Asm) {

818 continue;

819 defineSection(static_cast<const MCSectionCOFF &>(Section));

820 }

821

823 for (const MCSymbol &Symbol : Asm->symbols()) {

824 auto &Sym = static_cast<const MCSymbolCOFF &>(Symbol);

825

827 defineSymbol(Sym);

828 }

829 }

830

832 Header.NumberOfSections = Sections.size();

833 Header.NumberOfSymbols = 0;

834 if (Sections.size() > INT32_MAX)

836 "PE COFF object files can't have more than 2147483647 sections");

837

838 assignSectionNumbers();

839}

840

843 assert(Target.getAddSym() && "Relocation must reference a symbol!");

844

846 if (A.isRegistered()) {

847 getContext().reportError(Fixup.getLoc(), Twine("symbol '") + A.getName() +

848 "' can not be undefined");

849 return;

850 }

851 if (A.isTemporary() && A.isUndefined()) {

852 getContext().reportError(Fixup.getLoc(), Twine("assembler label '") +

853 A.getName() +

854 "' can not be undefined");

855 return;

856 }

857

859

860

861 assert(SectionMap.contains(MCSec) &&

862 "Section must already have been defined in executePostLayoutBinding!");

863

864 COFFSection *Sec = SectionMap[MCSec];

866 if (B->getFragment()) {

867 getContext().reportError(

869 Twine("symbol '") + B->getName() +

870 "' can not be undefined in a subtraction expression");

871 return;

872 }

873

874

875 int64_t OffsetOfB = Asm->getSymbolOffset(*B);

876

877

878 int64_t OffsetOfRelocation = Asm->getFragmentOffset(F) + Fixup.getOffset();

879

880 FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();

881 } else {

882 FixedValue = Target.getConstant();

883 }

884

885 COFFRelocation Reloc;

886

887 Reloc.Data.SymbolTableIndex = 0;

888 Reloc.Data.VirtualAddress = Asm->getFragmentOffset(F);

889

890

891 if (A.isTemporary() && !SymbolMap[&A]) {

892 MCSection *TargetSection = &A.getSection();

894 SectionMap.contains(TargetSection) &&

895 "Section must already have been defined in executePostLayoutBinding!");

896 COFFSection *Section = SectionMap[TargetSection];

897 Reloc.Symb = Section->Symbol;

898 FixedValue += Asm->getSymbolOffset(A);

899

900

901

902

903 if (UseOffsetLabels && !Section->OffsetSymbols.empty()) {

904 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;

905 if (LabelIndex > 0) {

906 if (LabelIndex <= Section->OffsetSymbols.size())

907 Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1];

908 else

909 Reloc.Symb = Section->OffsetSymbols.back();

910 FixedValue -= Reloc.Symb->Data.Value;

911 }

912 }

913 } else {

915 SymbolMap.contains(&A) &&

916 "Symbol must already have been defined in executePostLayoutBinding!");

917 Reloc.Symb = SymbolMap[&A];

918 }

919

920 ++Reloc.Symb->Relocations;

921

922 Reloc.Data.VirtualAddress += Fixup.getOffset();

923 Reloc.Data.Type = OWriter.TargetObjectWriter->getRelocType(

924 getContext(), Target, Fixup, Target.getSubSym(), Asm->getBackend());

925

926

927

936 FixedValue += 4;

937

939 switch (Reloc.Data.Type) {

946 break;

949

950

951

955

956

957

958

959

961 break;

963 break;

967

968

969

970

971 FixedValue = FixedValue + 4;

972 break;

973 }

974 }

975

976

978 FixedValue = 0;

979

980 if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {

981 Sec->Relocations.push_back(Reloc);

985

986

987 auto RelocPair = Reloc;

989 Sec->Relocations.push_back(RelocPair);

990 }

991 }

992}

993

995 std::time_t Now = time(nullptr);

997 return UINT32_MAX;

998 return Now;

999}

1000

1002 uint64_t StartOffset = W.OS.tell();

1003

1004 setWeakDefaultNames();

1006 createFileSymbols();

1007

1008 for (auto &Symbol : Symbols) {

1009

1010 if (Symbol->Section)

1011 Symbol->Data.SectionNumber = Symbol->Section->Number;

1012 Symbol->setIndex(Header.NumberOfSymbols++);

1013

1014 Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();

1015 Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;

1016 }

1017

1018

1019 for (const auto &S : Sections)

1021 Strings.add(S->Name);

1022 for (const auto &S : Symbols)

1024 Strings.add(S->Name);

1025 Strings.finalize();

1026

1027

1028 for (const auto &S : Sections)

1029 SetSectionName(*S);

1030 for (auto &S : Symbols)

1031 SetSymbolName(*S);

1032

1033

1034 for (auto &Symbol : Symbols) {

1035 if (Symbol->Other) {

1036 assert(Symbol->getIndex() != -1);

1037 assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");

1038 assert(Symbol->Aux[0].AuxType == ATWeakExternal &&

1039 "Symbol's aux symbol must be a Weak External!");

1040 Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();

1041 }

1042 }

1043

1044

1045 for (auto &Section : Sections) {

1046 if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=

1048 continue;

1049

1050 const MCSectionCOFF &MCSec = *Section->MCSection;

1053

1054

1055

1057 getContext().reportError(

1059 Twine(" associative with sectionless symbol ") +

1061 continue;

1062 }

1063

1064 const auto *AssocMCSec =

1066 assert(SectionMap.count(AssocMCSec));

1067 COFFSection *AssocSec = SectionMap[AssocMCSec];

1068

1069

1070 if (AssocSec->Number == -1)

1071 continue;

1072

1073 Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;

1074 }

1075

1076

1077 if (Mode != DwoOnly && OWriter.getEmitAddrsigSection()) {

1080 for (const MCSymbol *S : OWriter.AddrsigSyms) {

1082 continue;

1085 continue;

1086 }

1087

1089 assert(SectionMap.contains(TargetSection) &&

1090 "Section must already have been defined in "

1091 "executePostLayoutBinding!");

1092 encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);

1093 }

1094 auto *Sec = getContext().getCOFFSection(".llvm_addrsig",

1096 Sec->curFragList()->Tail->setVarContents(OS.str());

1097 }

1098

1099

1100 if (Mode != DwoOnly && !OWriter.getCGProfile().empty()) {

1103 for (const auto &CGPE : OWriter.getCGProfile()) {

1104 uint32_t FromIndex = CGPE.From->getSymbol().getIndex();

1105 uint32_t ToIndex = CGPE.To->getSymbol().getIndex();

1109 }

1110 auto *Sec = getContext().getCOFFSection(".llvm.call-graph-profile",

1112 Sec->curFragList()->Tail->setVarContents(OS.str());

1113 }

1114

1115 assignFileOffsets();

1116

1117

1118

1119 if (OWriter.IncrementalLinkerCompatible) {

1120 Header.TimeDateStamp = getTime();

1121 } else {

1122

1123 Header.TimeDateStamp = 0;

1124 }

1125

1126

1127 WriteFileHeader(Header);

1128 writeSectionHeaders();

1129

1130#ifndef NDEBUG

1131 sections::iterator I = Sections.begin();

1132 sections::iterator IE = Sections.end();

1133 auto J = Asm->begin();

1134 auto JE = Asm->end();

1135 for (; I != IE && J != JE; ++I, ++J) {

1138 ++J;

1139 assert(J != JE && (**I).MCSection == &*J && "Wrong bound MCSection");

1140 }

1141#endif

1142

1143

1144 for (std::unique_ptr &Sec : Sections)

1145 writeSection(*Sec);

1146

1147 assert(W.OS.tell() == Header.PointerToSymbolTable &&

1148 "Header::PointerToSymbolTable is insane!");

1149

1150

1151 for (auto &Symbol : Symbols)

1152 if (Symbol->getIndex() != -1)

1153 WriteSymbol(*Symbol);

1154

1155

1156 Strings.write(W.OS);

1157

1158 return W.OS.tell() - StartOffset;

1159}

1160

1162 return SectionMap.at(&Section)->Number;

1163}

1164

1165

1166

1167

1168

1169

1170

1172 IncrementalLinkerCompatible = false;

1173 ObjWriter->reset();

1174 if (DwoWriter)

1175 DwoWriter->reset();

1177}

1178

1181 ObjWriter->setAssembler(Asm);

1182 if (DwoWriter)

1183 DwoWriter->setAssembler(Asm);

1184}

1185

1188 bool IsPCRel) const {

1189

1190

1191

1192

1193

1194

1197 return false;

1199}

1200

1202 ObjWriter->executePostLayoutBinding();

1203 if (DwoWriter)

1204 DwoWriter->executePostLayoutBinding();

1205}

1206

1213

1215

1216

1218 return 0;

1219

1220 uint64_t TotalSize = ObjWriter->writeObject();

1221 if (DwoWriter)

1222 TotalSize += DwoWriter->writeObject();

1223 return TotalSize;

1224}

1225

1227 return ObjWriter->getSectionNumber(Section);

1228}

1229

1231 : Machine(Machine_) {}

1232

1233

1234void MCWinCOFFObjectTargetWriter::anchor() {}

1235

1236

1237

1238

1240 std::unique_ptr MOTW, raw_pwrite_stream &OS) {

1241 return std::make_unique(std::move(MOTW), OS);

1242}

1243

1245 std::unique_ptr MOTW, raw_pwrite_stream &OS,

1247 return std::make_unique(std::move(MOTW), OS, DwoOS);

1248}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static const Function * getParent(const Value *V)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file defines the DenseMap class.

This file defines the DenseSet and SmallDenseSet classes.

std::pair< uint64_t, uint64_t > Interval

PowerPC TLS Dynamic Call Fixup

This file defines the SmallString class.

This file defines the SmallVector class.

static SymbolRef::Type getType(const Symbol *Sym)

static uint64_t getSymbolValue(const MCSymbolCOFF &Symbol, const MCAssembler &Asm)

Definition WinCOFFObjectWriter.cpp:342

void write32le(void *P, uint32_t V)

static uint32_t getAlignment(const MCSectionCOFF &Sec)

Definition WinCOFFObjectWriter.cpp:259

static bool isAssociative(const COFFSection &Section)

Definition WinCOFFObjectWriter.cpp:713

static bool isDwoSection(const MCSection &Sec)

Definition WinCOFFObjectWriter.cpp:213

static std::time_t getTime()

Definition WinCOFFObjectWriter.cpp:994

Implements a dense probed hash-table based set.

Context object for machine code objects.

Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...

MCSection * getParent() const

virtual void setAssembler(MCAssembler *A)

virtual void reset()

lifetime management

MCContext & getContext() const

This represents a section on Windows.

MCSymbol * getCOMDATSymbol() const

unsigned getCharacteristics() const

Instances of this class represent a uniqued identifier for a section in the current translation unit.

StringRef getName() const

MCSymbol * getBeginSymbol()

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

bool isInSection() const

isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).

StringRef getName() const

getName - Get the symbol name.

bool isVariable() const

isVariable - Check if this is a variable symbol.

bool isRegistered() const

void setIndex(uint32_t Value) const

Set the (implementation defined) index.

uint32_t getIndex() const

Get the (implementation defined) index.

MCSection & getSection() const

Get the section associated with a defined, non-absolute symbol.

bool isTemporary() const

isTemporary - Check if this is an assembler temporary symbol.

MCFragment * getFragment() const

uint64_t getOffset() const

MCWinCOFFObjectTargetWriter(unsigned Machine_)

Definition WinCOFFObjectWriter.cpp:1230

Represents a location in source code.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

pointer data()

Return a pointer to the vector's buffer, even if empty().

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

bool ends_with(StringRef Suffix) const

Check if this string ends with the given Suffix.

Utility for building string tables with deduplicated suffixes.

Target - Wrapper for Target specific information.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

void recordRelocation(const MCFragment &F, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override

Record a relocation entry.

Definition WinCOFFObjectWriter.cpp:1207

void reset() override

lifetime management

Definition WinCOFFObjectWriter.cpp:1171

int getSectionNumber(const MCSection &Section) const

Definition WinCOFFObjectWriter.cpp:1226

void setAssembler(MCAssembler *Asm) override

Definition WinCOFFObjectWriter.cpp:1179

WinCOFFObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)

Definition WinCOFFObjectWriter.cpp:199

void executePostLayoutBinding() override

Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...

Definition WinCOFFObjectWriter.cpp:1201

friend class WinCOFFWriter

uint64_t writeObject() override

Write the object file and returns the number of bytes written.

Definition WinCOFFObjectWriter.cpp:1214

bool isSymbolRefDifferenceFullyResolvedImpl(const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override

Definition WinCOFFObjectWriter.cpp:1186

void executePostLayoutBinding()

Definition WinCOFFObjectWriter.cpp:812

WinCOFFWriter(WinCOFFObjectWriter &OWriter, raw_pwrite_stream &OS, DwoMode Mode)

Definition WinCOFFObjectWriter.cpp:231

enum llvm::WinCOFFWriter::DwoMode Mode

void reset()

Definition WinCOFFObjectWriter.cpp:801

uint64_t writeObject()

Definition WinCOFFObjectWriter.cpp:1001

void recordRelocation(const MCFragment &F, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)

Definition WinCOFFObjectWriter.cpp:841

void setAssembler(MCAssembler *A)

Definition WinCOFFObjectWriter.cpp:161

DwoMode

Definition WinCOFFObjectWriter.cpp:151

@ DwoOnly

Definition WinCOFFObjectWriter.cpp:154

@ NonDwoOnly

Definition WinCOFFObjectWriter.cpp:153

@ AllSections

Definition WinCOFFObjectWriter.cpp:152

int getSectionNumber(const MCSection &Section) const

Definition WinCOFFObjectWriter.cpp:1161

An abstract base class for streams implementations that also support a pwrite operation.

A raw_ostream that writes to an SmallVector or SmallString.

StringRef str() const

Return a StringRef for the vector contents.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ IMAGE_REL_MIPS_SECRELHI

@ IMAGE_FILE_MACHINE_UNKNOWN

@ IMAGE_FILE_MACHINE_AMD64

@ IMAGE_FILE_MACHINE_R4000

@ IMAGE_FILE_MACHINE_I386

@ IMAGE_FILE_MACHINE_ARMNT

@ IMAGE_SCN_ALIGN_64BYTES

@ IMAGE_SCN_ALIGN_128BYTES

@ IMAGE_SCN_ALIGN_256BYTES

@ IMAGE_SCN_ALIGN_1024BYTES

@ IMAGE_SCN_ALIGN_512BYTES

@ IMAGE_SCN_CNT_UNINITIALIZED_DATA

@ IMAGE_SCN_ALIGN_4096BYTES

@ IMAGE_SCN_ALIGN_8192BYTES

@ IMAGE_SCN_LNK_NRELOC_OVFL

@ IMAGE_SCN_ALIGN_16BYTES

@ IMAGE_SCN_ALIGN_32BYTES

@ IMAGE_SCN_ALIGN_2048BYTES

bool isAnyArm64(T Machine)

@ IMAGE_SYM_CLASS_EXTERNAL

External symbol.

@ IMAGE_SYM_CLASS_LABEL

Label.

@ IMAGE_SYM_CLASS_FILE

File name.

@ IMAGE_SYM_CLASS_NULL

No symbol.

@ IMAGE_SYM_CLASS_WEAK_EXTERNAL

Duplicate tag.

@ IMAGE_SYM_CLASS_STATIC

Static.

LLVM_ABI bool encodeSectionName(char *Out, uint64_t Offset)

Encode section name based on string table offset.

@ IMAGE_COMDAT_SELECT_ASSOCIATIVE

@ IMAGE_REL_ARM_BRANCH20T

@ IMAGE_REL_ARM_BRANCH24T

const int32_t MaxNumberOfSections16

static const char BigObjMagic[]

@ IMAGE_SYM_DTYPE_FUNCTION

A function that returns a base type.

@ SCT_COMPLEX_TYPE_SHIFT

Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))

void write32le(void *P, uint32_t V)

void write(void *memory, value_type value, endianness endian)

Write a value to memory with a particular endianness.

This is an optimization pass for GlobalISel generic memory operations.

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

std::unique_ptr< MCObjectWriter > createWinCOFFDwoObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS)

Definition WinCOFFObjectWriter.cpp:1244

FunctionAddr VTableAddr Count

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

std::unique_ptr< MCObjectWriter > createWinCOFFObjectWriter(std::unique_ptr< MCWinCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)

Construct a new Win COFF writer instance.

Definition WinCOFFObjectWriter.cpp:1239

@ FK_SecRel_2

A two-byte section relative fixup.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

ArrayRef(const T &OneElt) -> ArrayRef< T >

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.

Implement std::hash so that hash_code can be used in STL containers.

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.

uint16_t NumberOfRelocations

uint16_t NumberOfLinenumbers

uint32_t PointerToRelocations

uint16_t NumberOfLineNumbers

uint32_t PointerToRawData

uint16_t NumberOfRelocations

uint32_t PointerToLineNumbers

uint8_t NumberOfAuxSymbols

Adapter to write values to a stream in a particular byte order.

AuxiliarySectionDefinition SectionDefinition