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

1

2

3

4

5

6

7

8

9

10

11

12

41#include

42#include

43#include

44#include

45#include

46#include

47#include

48

49using namespace llvm;

51

52#define DEBUG_TYPE "WinCOFFObjectWriter"

53

54namespace {

55

56constexpr int OffsetLabelIntervalBits = 20;

57

59

60enum AuxiliaryType { ATWeakExternal, ATFile, ATSectionDefinition };

61

62struct AuxSymbol {

65};

66

67class COFFSection;

68

69class COFFSymbol {

70public:

72

74

76 int Index = 0;

77 AuxiliarySymbols Aux;

78 COFFSymbol *Other = nullptr;

79 COFFSection *Section = nullptr;

80 int Relocations = 0;

82

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

84

86

87 int64_t getIndex() const { return Index; }

88 void setIndex(int Value) {

90 if (MC)

92 }

93};

94

95

96struct COFFRelocation {

98 COFFSymbol *Symb = nullptr;

99

100 COFFRelocation() = default;

101

103};

104

105using relocations = std::vector;

106

107class COFFSection {

108public:

110

111 std::string Name;

114 COFFSymbol *Symbol = nullptr;

115 relocations Relocations;

116

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

118

120};

121}

122

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

144

146

147 bool UseBigObj;

148 bool UseOffsetLabels = false;

149

150public:

156

159

167

168private:

170 COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);

172

174

175 COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);

177

178 void SetSymbolName(COFFSymbol &S);

179 void SetSectionName(COFFSection &S);

180

181 bool IsPhysicalSection(COFFSection *S);

182

183

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

185 void WriteSymbol(const COFFSymbol &S);

187 void writeSectionHeaders();

190 void writeSection(MCAssembler &Asm, const COFFSection &Sec);

191

192 void createFileSymbols(MCAssembler &Asm);

193 void setWeakDefaultNames();

194 void assignSectionNumbers();

195 void assignFileOffsets(MCAssembler &Asm);

196};

197

199 std::unique_ptr MOTW, raw_pwrite_stream &OS)

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

204 std::unique_ptr MOTW, raw_pwrite_stream &OS,

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

211

214}

215

216

217

218

219

220

221

225}

226

227

228

229

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

234

235

236

237

239}

240

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

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

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

244}

245

246COFFSymbol *WinCOFFWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {

247 COFFSymbol *&Ret = SymbolMap[Symbol];

248 if (!Ret)

249 Ret = createSymbol(Symbol->getName());

250 return Ret;

251}

252

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

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

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

256}

257

260 case 1:

262 case 2:

264 case 4:

266 case 8:

268 case 16:

270 case 32:

272 case 64:

274 case 128:

276 case 256:

278 case 512:

280 case 1024:

282 case 2048:

284 case 4096:

286 case 8192:

288 }

290}

291

292

293

294void WinCOFFWriter::defineSection(const MCAssembler &Asm,

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) {

330 for (uint32_t Off = Interval, E = Asm.getSectionAddressSize(MCSec); Off < E;

333 COFFSymbol *Label = createSymbol(Name);

337 Section->OffsetSymbols.push_back(Label);

338 }

339 }

340}

341

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

344 return Symbol.getCommonSize();

345

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

348 return 0;

349

350 return Res;

351}

352

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

354 if (Symbol.isVariable())

355 return nullptr;

356

358 dyn_cast(Symbol.getVariableValue());

359 if (!SymRef)

360 return nullptr;

361

364 return GetOrCreateCOFFSymbol(&Aliasee);

365 else

366 return nullptr;

367}

368

369

370

371void WinCOFFWriter::defineSymbol(const MCAssembler &Asm,

374 COFFSection *Sec = nullptr;

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

377 MCSec = cast(Base->getFragment()->getParent());

378 Sec = SectionMap[MCSec];

379 }

380

382 return;

383

384 COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);

385 COFFSymbol *Local = nullptr;

386 if (cast(MCSym).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

405 Sym->Aux.resize(1);

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 cast(MCSym).getWeakExternalCharacteristics();

411 } else {

414 else

415 Sym->Section = Sec;

417 }

418

421

422 const MCSymbolCOFF &SymbolCOFF = cast(MCSym);

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

425

426

428 bool IsExternal =

430

433 }

434 }

435

436 Sym->MC = &MCSym;

437}

438

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

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

442 return;

443 }

444

448}

449

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

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

453 else

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

455}

456

457bool WinCOFFWriter::IsPhysicalSection(COFFSection *S) {

459 0;

460}

461

462

463

464

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

466 if (UseBigObj) {

480 } else {

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

488 }

489}

490

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

494 if (UseBigObj)

496 else

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

499 W.OS << char(S.Data.StorageClass);

500 W.OS << char(S.Data.NumberOfAuxSymbols);

501 WriteAuxiliarySymbols(S.Aux);

502}

503

504void WinCOFFWriter::WriteAuxiliarySymbols(

506 for (const AuxSymbol &i : S) {

507 switch (i.AuxType) {

508 case ATWeakExternal:

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

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

512 if (UseBigObj)

514 break;

515 case ATFile:

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

518 break;

519 case ATSectionDefinition:

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

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

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

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

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

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

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

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

529 if (UseBigObj)

531 break;

532 }

533 }

534}

535

536

537void WinCOFFWriter::writeSectionHeaders() {

538

539

540

541 std::vector<COFFSection *> Arr;

542 for (auto &Section : Sections)

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

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

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

546 });

547

548 for (auto &Section : Arr) {

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

550 continue;

551

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

565 }

566}

567

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

572}

573

574

575

576

579

580

583 Asm.writeSectionData(VecOS, &MCSec);

584

585

586 W.OS << Buf;

587

588

589

590 JamCRC JC(0);

592 return JC.getCRC();

593}

594

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

596 if (Sec.Number == -1)

597 return;

598

599

600 if (Sec.Header.PointerToRawData != 0) {

601 assert(W.OS.tell() == Sec.Header.PointerToRawData &&

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

603

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

605

606

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

609 AuxSymbol &SecDef = AuxSyms[0];

610 SecDef.Aux.SectionDefinition.CheckSum = CRC;

611 }

612

613

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

615 assert(Sec.Header.PointerToRelocations == 0 &&

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

617 return;

618 }

619

620 assert(W.OS.tell() == Sec.Header.PointerToRelocations &&

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

622

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

624

625

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

628 R.SymbolTableIndex = 0;

629 R.Type = 0;

630 WriteRelocation(R);

631 }

632

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

634 WriteRelocation(Relocation.Data);

635}

636

637

638void WinCOFFWriter::createFileSymbols(MCAssembler &Asm) {

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

640

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

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

644

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

648 File->Aux.resize(Count);

649

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

653 Aux.AuxType = ATFile;

654

655 if (Length > SymbolSize) {

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

658 } else {

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

661 break;

662 }

663

664 Offset += SymbolSize;

665 }

666 }

667}

668

669void WinCOFFWriter::setWeakDefaultNames() {

670 if (WeakDefaults.empty())

671 return;

672

673

674

675

676

677

678

679

680 COFFSymbol *Unique = nullptr;

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

682 for (auto &Sym : Symbols) {

683

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

685 continue;

686

688 continue;

689

691 continue;

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

694 continue;

695 Unique = Sym.get();

696 break;

697 }

698 if (Unique)

699 break;

700 }

701

702 if (!Unique)

703 return;

704 for (auto *Sym : WeakDefaults) {

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

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

707 }

708}

709

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

713}

714

715void WinCOFFWriter::assignSectionNumbers() {

716 size_t I = 1;

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

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

721 ++I;

722 };

723

724

725

726

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

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

733}

734

735

736void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) {

738

741

742 for (const auto &Section : Asm) {

743 COFFSection *Sec = SectionMap[&Section];

744

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

746 continue;

747

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

749

750 if (IsPhysicalSection(Sec)) {

751 Sec->Header.PointerToRawData = Offset;

752 Offset += Sec->Header.SizeOfRawData;

753 }

754

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

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

757

758 if (RelocationsOverflow) {

759

760

761 Sec->Header.NumberOfRelocations = 0xffff;

762 } else {

763 Sec->Header.NumberOfRelocations = Sec->Relocations.size();

764 }

765 Sec->Header.PointerToRelocations = Offset;

766

767 if (RelocationsOverflow) {

768

770 }

771

773

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

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

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

779 }

780 }

781 }

782

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

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

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

786 assert(Aux.AuxType == ATSectionDefinition &&

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

788 Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;

789 Aux.Aux.SectionDefinition.NumberOfRelocations =

790 Sec->Header.NumberOfRelocations;

791 Aux.Aux.SectionDefinition.NumberOfLinenumbers =

792 Sec->Header.NumberOfLineNumbers;

793 }

794

795 Header.PointerToSymbolTable = Offset;

796}

797

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

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

801 Sections.clear();

802 Symbols.clear();

804 SectionMap.clear();

805 SymbolMap.clear();

806 WeakDefaults.clear();

807}

808

810

811

812 for (const auto &Section : Asm) {

815 continue;

816 defineSection(Asm, static_cast<const MCSectionCOFF &>(Section));

817 }

818

820 for (const MCSymbol &Symbol : Asm.symbols())

821

822 if (!Symbol.isTemporary() ||

824 defineSymbol(Asm, Symbol);

825

827 Header.NumberOfSections = Sections.size();

828 Header.NumberOfSymbols = 0;

829 if (Sections.size() > INT32_MAX)

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

832

833 assignSectionNumbers();

834}

835

840 assert(Target.getSymA() && "Relocation must reference a symbol!");

841

843 if (A.isRegistered()) {

844 Asm.getContext().reportError(Fixup.getLoc(), Twine("symbol '") +

845 A.getName() +

846 "' can not be undefined");

847 return;

848 }

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

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

851 A.getName() +

852 "' can not be undefined");

853 return;

854 }

855

857

858

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

861

862 COFFSection *Sec = SectionMap[MCSec];

864

865 if (SymB) {

867 if (B->getFragment()) {

868 Asm.getContext().reportError(

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

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

872 return;

873 }

874

875

876 int64_t OffsetOfB = Asm.getSymbolOffset(*B);

877

878

879 int64_t OffsetOfRelocation =

880 Asm.getFragmentOffset(*Fragment) + Fixup.getOffset();

881

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

883 } else {

884 FixedValue = Target.getConstant();

885 }

886

887 COFFRelocation Reloc;

888

889 Reloc.Data.SymbolTableIndex = 0;

890 Reloc.Data.VirtualAddress = Asm.getFragmentOffset(*Fragment);

891

892

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

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

896 SectionMap.contains(TargetSection) &&

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

898 COFFSection *Section = SectionMap[TargetSection];

899 Reloc.Symb = Section->Symbol;

900 FixedValue += Asm.getSymbolOffset(A);

901

902

903

904

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

906 uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;

907 if (LabelIndex > 0) {

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

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

910 else

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

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

913 }

914 }

915 } else {

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

919 Reloc.Symb = SymbolMap[&A];

920 }

921

922 ++Reloc.Symb->Relocations;

923

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

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

926 Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());

927

928

929

938 FixedValue += 4;

939

941 switch (Reloc.Data.Type) {

948 break;

951

952

953

957

958

959

960

961

963 break;

965 break;

969

970

971

972

973 FixedValue = FixedValue + 4;

974 break;

975 }

976 }

977

978

980 FixedValue = 0;

981

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

983 Sec->Relocations.push_back(Reloc);

987

988

989 auto RelocPair = Reloc;

991 Sec->Relocations.push_back(RelocPair);

992 }

993 }

994}

995

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

998 if (Now < 0 || !isUInt<32>(Now))

999 return UINT32_MAX;

1000 return Now;

1001}

1002

1005

1006 setWeakDefaultNames();

1008 createFileSymbols(Asm);

1009

1010 for (auto &Symbol : Symbols) {

1011

1012 if (Symbol->Section)

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

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

1015

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

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

1018 }

1019

1020

1021 for (const auto &S : Sections)

1024 for (const auto &S : Symbols)

1028

1029

1030 for (const auto &S : Sections)

1031 SetSectionName(*S);

1032 for (auto &S : Symbols)

1033 SetSymbolName(*S);

1034

1035

1036 for (auto &Symbol : Symbols) {

1037 if (Symbol->Other) {

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

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

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

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

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

1043 }

1044 }

1045

1046

1047 for (auto &Section : Sections) {

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

1050 continue;

1051

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

1055

1056

1057

1059 Asm.getContext().reportError(

1061 Twine(" associative with sectionless symbol ") +

1063 continue;

1064 }

1065

1066 const auto *AssocMCSec = cast(&AssocMCSym->getSection());

1068 COFFSection *AssocSec = SectionMap[AssocMCSec];

1069

1070

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

1072 continue;

1073

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

1075 }

1076

1077

1079 auto *Sec = Asm.getContext().getCOFFSection(

1081 auto *Frag = cast(Sec->curFragList()->Head);

1085 continue;

1088 continue;

1089 }

1090

1093 "Section must already have been defined in "

1094 "executePostLayoutBinding!");

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

1096 }

1097 }

1098

1099

1101 auto *Sec = Asm.getContext().getCOFFSection(

1103 auto *Frag = cast(Sec->curFragList()->Head);

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

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

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

1111 }

1112 }

1113

1114 assignFileOffsets(Asm);

1115

1116

1117

1118 if (OWriter.IncrementalLinkerCompatible) {

1119 Header.TimeDateStamp = getTime();

1120 } else {

1121

1122 Header.TimeDateStamp = 0;

1123 }

1124

1125

1126 WriteFileHeader(Header);

1127 writeSectionHeaders();

1128

1129#ifndef NDEBUG

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

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

1132 auto J = Asm.begin();

1133 auto JE = Asm.end();

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

1137 ++J;

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

1139 }

1140#endif

1141

1142

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

1144 writeSection(Asm, *Sec);

1145

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

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

1148

1149

1150 for (auto &Symbol : Symbols)

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

1152 WriteSymbol(*Symbol);

1153

1154

1156

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

1158}

1159

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

1162}

1163

1164

1165

1166

1167

1168

1169

1171 IncrementalLinkerCompatible = false;

1172 ObjWriter->reset();

1173 if (DwoWriter)

1174 DwoWriter->reset();

1176}

1177

1180 bool InSet, bool IsPCRel) const {

1181

1182

1183

1184

1185

1186

1187 uint16_t Type = cast(SymA).getType();

1189 return false;

1191}

1192

1194 ObjWriter->executePostLayoutBinding(Asm);

1195 if (DwoWriter)

1196 DwoWriter->executePostLayoutBinding(Asm);

1197}

1198

1204 "No relocation in Dwo sections");

1205 ObjWriter->recordRelocation(Asm, Fragment, Fixup, Target, FixedValue);

1206}

1207

1209

1210

1211 if (Asm.getContext().hadError())

1212 return 0;

1213

1214 uint64_t TotalSize = ObjWriter->writeObject(Asm);

1215 if (DwoWriter)

1216 TotalSize += DwoWriter->writeObject(Asm);

1217 return TotalSize;

1218}

1219

1221 return ObjWriter->getSectionNumber(Section);

1222}

1223

1226

1227

1228void MCWinCOFFObjectTargetWriter::anchor() {}

1229

1230

1231

1232

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

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

1236}

1237

1239 std::unique_ptr MOTW, raw_pwrite_stream &OS,

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

1242}

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

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

COFFYAML::AuxSymbolType AuxType

COFF::MachineTypes Machine

This file defines the DenseMap class.

This file defines the DenseSet and SmallDenseSet classes.

std::optional< std::vector< StOtherPiece > > Other

std::pair< uint64_t, uint64_t > Interval

PowerPC TLS Dynamic Call Fixup

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallString class.

This file defines the SmallVector class.

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

static uint32_t getAlignment(const MCSectionCOFF &Sec)

static bool isAssociative(const COFFSection &Section)

static bool isDwoSection(const MCSection &Sec)

static std::time_t getTime()

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

const ValueT & at(const_arg_type_t< KeyT > Val) const

at - Return the entry for the specified key, or abort if no such entry exists.

bool contains(const_arg_type_t< KeyT > Val) const

Return true if the specified key is in the map, false otherwise.

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

MCSection * getParent() const

MutableArrayRef< std::pair< std::string, size_t > > getFileNames()

bool getEmitAddrsigSection()

virtual void reset()

lifetime management

SmallVector< CGProfileEntry, 0 > & getCGProfile()

std::vector< const MCSymbol * > AddrsigSyms

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()

uint16_t getClass() const

Represent a reference to a symbol from inside an expression.

const MCSymbol & getSymbol() const

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.

bool isUndefined(bool SetUsed=true) const

isUndefined - Check if this symbol undefined (i.e., implicitly defined).

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(bool SetUsed=true) const

This represents an "assembler immediate".

MCWinCOFFObjectTargetWriter(unsigned Machine_)

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.

size_t getOffset(CachedHashStringRef S) const

Get the offest of a string in the string table.

void write(raw_ostream &OS) const

size_t add(CachedHashStringRef S)

Add a string to the builder.

void finalize()

Analyze the strings and build the final table.

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 reset() override

lifetime management

void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override

Record a relocation entry.

int getSectionNumber(const MCSection &Section) const

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

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

void executePostLayoutBinding(MCAssembler &Asm) override

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

uint64_t writeObject(MCAssembler &Asm) override

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

uint64_t writeObject(MCAssembler &Asm)

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

enum llvm::WinCOFFWriter::DwoMode Mode

void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)

int getSectionNumber(const MCSection &Section) const

void executePostLayoutBinding(MCAssembler &Asm)

std::pair< iterator, bool > insert(const ValueT &V)

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

raw_ostream & write_zeros(unsigned NumZeros)

write_zeros - Insert 'NumZeros' nulls.

uint64_t tell() const

tell - Return the current offset with the file.

raw_ostream & write(unsigned char C)

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

A raw_ostream that writes to an SmallVector or SmallString.

#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.

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.

void sort(IteratorTy Start, IteratorTy End)

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

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

@ FK_SecRel_2

A two-byte section relative fixup.

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

Construct a new Win COFF writer instance.

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.

uint64_t value() const

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

uint32_t PointerToRelocations

uint16_t NumberOfLineNumbers

uint32_t PointerToRawData

uint16_t NumberOfRelocations

uint32_t PointerToLineNumbers

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

void write(ArrayRef< value_type > Val)