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

1

2

3

4

5

6

7

8

9

10

11

12

26

27#include

28#include

29

30using namespace llvm;

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47namespace {

48

49constexpr unsigned DefaultSectionAlign = 4;

50constexpr int16_t MaxSectionIndex = INT16_MAX;

51

52

54

55struct XCOFFRelocation {

56 uint32_t SymbolTableIndex;

57 uint32_t FixupOffsetInCsect;

58 uint8_t SignAndSize;

59 uint8_t Type;

60};

61

62

63struct Symbol {

64 const MCSymbolXCOFF *const MCSym;

65 uint32_t SymbolTableIndex;

66

68 return MCSym->getVisibilityType();

69 }

70

72 return MCSym->getStorageClass();

73 }

74 StringRef getSymbolTableName() const { return MCSym->getSymbolTableName(); }

75 Symbol(const MCSymbolXCOFF *MCSym) : MCSym(MCSym), SymbolTableIndex(-1) {}

76};

77

78

79

80struct XCOFFSection {

81 const MCSectionXCOFF *const MCSec;

82 uint32_t SymbolTableIndex;

83 uint64_t Address;

84 uint64_t Size;

85

88 StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); }

90 return MCSec->getVisibilityType();

91 }

92 XCOFFSection(const MCSectionXCOFF *MCSec)

93 : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}

94};

95

96

97

98

99

100using CsectGroup = std::deque;

101using CsectGroups = std::deque<CsectGroup *>;

102

103

104

107

108

109

110

111

112

113 uint64_t Address;

114 uint64_t Size;

115 uint64_t FileOffsetToData;

116 uint64_t FileOffsetToRelocations;

117 uint32_t RelocationCount;

118 int32_t Flags;

119

120 int16_t Index;

121

122 virtual uint64_t advanceFileOffset(const uint64_t MaxRawDataSize,

123 const uint64_t RawPointer) {

124 FileOffsetToData = RawPointer;

125 uint64_t NewPointer = RawPointer + Size;

126 if (NewPointer > MaxRawDataSize)

128 return NewPointer;

129 }

130

131

132

133

134

135

136

137

138 static constexpr int16_t UninitializedIndex =

140

142 : Name(), Address(0), Size(0), FileOffsetToData(0),

143 FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),

144 Index(UninitializedIndex) {

146 memcpy(Name, N.data(), N.size());

147 }

148

149 virtual void reset() {

150 Address = 0;

151 Size = 0;

152 FileOffsetToData = 0;

153 FileOffsetToRelocations = 0;

154 RelocationCount = 0;

155 Index = UninitializedIndex;

156 }

157

159};

160

161

162

163

164

165

166struct CsectSectionEntry : public SectionEntry {

167

168 const bool IsVirtual;

169

170

171 CsectGroups Groups;

172

174 CsectGroups Groups)

175 : SectionEntry(N, Flags), IsVirtual(IsVirtual), Groups(Groups) {

177 memcpy(Name, N.data(), N.size());

178 }

179

180 void reset() override {

181 SectionEntry::reset();

182

183 for (auto *Group : Groups)

184 Group->clear();

185 }

186

187 ~CsectSectionEntry() override = default;

188};

189

190struct DwarfSectionEntry : public SectionEntry {

191

192 std::unique_ptr DwarfSect;

193

194

195

196 uint32_t MemorySize;

197

198

199

200

201

202 uint64_t advanceFileOffset(const uint64_t MaxRawDataSize,

203 const uint64_t RawPointer) override {

204 FileOffsetToData = RawPointer;

205 uint64_t NewPointer = RawPointer + MemorySize;

206 assert(NewPointer <= MaxRawDataSize &&

207 "Section raw data overflowed this object file.");

208 return NewPointer;

209 }

210

211 DwarfSectionEntry(StringRef N, int32_t Flags,

212 std::unique_ptr Sect)

214 MemorySize(0) {

215 assert(DwarfSect->MCSec->isDwarfSect() &&

216 "This should be a DWARF section!");

218 memcpy(Name, N.data(), N.size());

219 }

220

221 DwarfSectionEntry(DwarfSectionEntry &&s) = default;

222

223 ~DwarfSectionEntry() override = default;

224};

225

226struct ExceptionTableEntry {

228 uint64_t TrapAddress = ~0ul;

229 unsigned Lang;

230 unsigned Reason;

231

232 ExceptionTableEntry(const MCSymbol *Trap, unsigned Lang, unsigned Reason)

233 : Trap(Trap), Lang(Lang), Reason(Reason) {}

234};

235

236struct ExceptionInfo {

237 const MCSymbol *FunctionSymbol;

238 unsigned FunctionSize;

239 std::vector Entries;

240};

241

242struct ExceptionSectionEntry : public SectionEntry {

243 std::map<const StringRef, ExceptionInfo> ExceptionTable;

244 bool isDebugEnabled = false;

245

246 ExceptionSectionEntry(StringRef N, int32_t Flags)

249 memcpy(Name, N.data(), N.size());

250 }

251

252 ~ExceptionSectionEntry() override = default;

253};

254

255struct CInfoSymInfo {

256

257 std::string Name;

258 std::string Metadata;

259

260 uint64_t Offset;

261

262 CInfoSymInfo(std::string Name, std::string Metadata)

263 : Name(Name), Metadata(Metadata) {}

264

265 uint32_t paddingSize() const {

266 return alignTo(Metadata.size(), sizeof(uint32_t)) - Metadata.size();

267 };

268

269

270 uint32_t size() const {

271 return Metadata.size() + paddingSize() + sizeof(uint32_t);

272 };

273};

274

275struct CInfoSymSectionEntry : public SectionEntry {

276 std::unique_ptr Entry;

277

278 CInfoSymSectionEntry(StringRef N, int32_t Flags) : SectionEntry(N, Flags) {}

279 ~CInfoSymSectionEntry() override = default;

280 void addEntry(std::unique_ptr NewEntry) {

281 Entry = std::move(NewEntry);

282 Entry->Offset = sizeof(uint32_t);

283 Size += Entry->size();

284 }

285 void reset() override {

286 SectionEntry::reset();

287 Entry.reset();

288 }

289};

290

292 uint32_t SymbolTableEntryCount = 0;

293 uint64_t SymbolTableOffset = 0;

294 uint16_t SectionCount = 0;

295 uint32_t PaddingsBeforeDwarf = 0;

296 bool HasVisibility = false;

297

298 support::endian::Writer W;

299 std::unique_ptr TargetObjectWriter;

300 StringTableBuilder Strings;

301

302 const uint64_t MaxRawDataSize =

303 TargetObjectWriter->is64Bit() ? UINT64_MAX : UINT32_MAX;

304

305

306

307

308 DenseMap<const MCSectionXCOFF *, XCOFFSection *> SectionMap;

309

310

311

312 DenseMap<const MCSymbol *, uint32_t> SymbolIndexMap;

313

314

315

316

317 CsectGroup UndefinedCsects;

318 CsectGroup ProgramCodeCsects;

319 CsectGroup ReadOnlyCsects;

320 CsectGroup DataCsects;

321 CsectGroup FuncDSCsects;

322 CsectGroup TOCCsects;

323 CsectGroup BSSCsects;

324 CsectGroup TDataCsects;

325 CsectGroup TBSSCsects;

326

327

328 CsectSectionEntry Text;

329 CsectSectionEntry Data;

330 CsectSectionEntry BSS;

331 CsectSectionEntry TData;

332 CsectSectionEntry TBSS;

333

334

335

336 std::array<CsectSectionEntry *const, 5> Sections{

337 {&Text, &Data, &BSS, &TData, &TBSS}};

338

339 std::vector DwarfSections;

340 std::vector OverflowSections;

341

342 ExceptionSectionEntry ExceptionSection;

343 CInfoSymSectionEntry CInfoSymSection;

344

345 CsectGroup &getCsectGroup(const MCSectionXCOFF *MCSec);

346

347 void reset() override;

348

349 void executePostLayoutBinding() override;

350

351 void recordRelocation(const MCFragment &, const MCFixup &, MCValue,

352 uint64_t &) override;

353

354 uint64_t writeObject() override;

355

356 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }

357 bool nameShouldBeInStringTable(const StringRef &);

358 void writeSymbolName(const StringRef &);

359 bool auxFileSymNameShouldBeInStringTable(const StringRef &);

360 void writeAuxFileSymName(const StringRef &);

361

362 void writeSymbolEntryForCsectMemberLabel(const Symbol &SymbolRef,

363 const XCOFFSection &CSectionRef,

364 int16_t SectionIndex,

365 uint64_t SymbolOffset);

366 void writeSymbolEntryForControlSection(const XCOFFSection &CSectionRef,

367 int16_t SectionIndex,

369 void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef,

370 int16_t SectionIndex);

371 void writeFileHeader();

372 void writeAuxFileHeader();

373 void writeSectionHeader(const SectionEntry *Sec);

374 void writeSectionHeaderTable();

375 void writeSections(const MCAssembler &Asm);

376 void writeSectionForControlSectionEntry(const MCAssembler &Asm,

377 const CsectSectionEntry &CsectEntry,

378 uint64_t &CurrentAddressLocation);

379 void writeSectionForDwarfSectionEntry(const MCAssembler &Asm,

380 const DwarfSectionEntry &DwarfEntry,

381 uint64_t &CurrentAddressLocation);

382 void

383 writeSectionForExceptionSectionEntry(const MCAssembler &Asm,

384 ExceptionSectionEntry &ExceptionEntry,

385 uint64_t &CurrentAddressLocation);

386 void writeSectionForCInfoSymSectionEntry(const MCAssembler &Asm,

387 CInfoSymSectionEntry &CInfoSymEntry,

388 uint64_t &CurrentAddressLocation);

390 void writeSymbolAuxFileEntry(StringRef &Name, uint8_t ftype);

391 void writeSymbolAuxDwarfEntry(uint64_t LengthOfSectionPortion,

392 uint64_t NumberOfRelocEnt = 0);

393 void writeSymbolAuxCsectEntry(uint64_t SectionOrLength,

394 uint8_t SymbolAlignmentAndType,

396 void writeSymbolAuxFunctionEntry(uint32_t EntryOffset, uint32_t FunctionSize,

397 uint64_t LineNumberPointer,

398 uint32_t EndIndex);

399 void writeSymbolAuxExceptionEntry(uint64_t EntryOffset, uint32_t FunctionSize,

400 uint32_t EndIndex);

401 void writeSymbolEntry(StringRef SymbolName, uint64_t Value,

402 int16_t SectionNumber, uint16_t SymbolType,

403 uint8_t StorageClass, uint8_t NumberOfAuxEntries = 1);

404 void writeRelocations();

405 void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &Section);

406

407

408

409

410

411

412

413

414

415 void assignAddressesAndIndices(MCAssembler &Asm);

416

417 void finalizeSectionInfo();

418 void finalizeRelocationInfo(SectionEntry *Sec, uint64_t RelCount);

419 void calcOffsetToRelocations(SectionEntry *Sec, uint64_t &RawPointer);

420

421 bool hasExceptionSection() {

422 return !ExceptionSection.ExceptionTable.empty();

423 }

424 unsigned getExceptionSectionSize();

425 unsigned getExceptionOffset(const MCSymbol *Symbol);

426

427 size_t auxiliaryHeaderSize() const {

428

430 }

431

432public:

433 XCOFFWriter(std::unique_ptr MOTW,

434 raw_pwrite_stream &OS);

435

436 void writeWord(uint64_t Word) {

438 }

439

440 void addExceptionEntry(const MCSymbol *Symbol, const MCSymbol *Trap,

441 unsigned LanguageCode, unsigned ReasonCode,

442 unsigned FunctionSize, bool hasDebug) override;

443 void addCInfoSymEntry(StringRef Name, StringRef Metadata) override;

444};

445

446XCOFFWriter::XCOFFWriter(std::unique_ptr MOTW,

451 CsectGroups{&ProgramCodeCsects, &ReadOnlyCsects}),

453 CsectGroups{&DataCsects, &FuncDSCsects, &TOCCsects}),

455 CsectGroups{&BSSCsects}),

457 CsectGroups{&TDataCsects}),

459 CsectGroups{&TBSSCsects}),

462

463void XCOFFWriter::reset() {

464

465 SymbolIndexMap.clear();

466 SectionMap.clear();

467

468 UndefinedCsects.clear();

469

470 for (auto *Sec : Sections)

471 Sec->reset();

472 for (auto &DwarfSec : DwarfSections)

473 DwarfSec.reset();

474 for (auto &OverflowSec : OverflowSections)

475 OverflowSec.reset();

476 ExceptionSection.reset();

477 CInfoSymSection.reset();

478

479

480 SymbolTableEntryCount = 0;

481 SymbolTableOffset = 0;

482 SectionCount = 0;

483 PaddingsBeforeDwarf = 0;

485

487}

488

489CsectGroup &XCOFFWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {

493 "Only an initialized csect can contain program code.");

494 return ProgramCodeCsects;

497 "Only an initialized csect can contain read only data.");

498 return ReadOnlyCsects;

501 return BSSCsects;

502

504 return DataCsects;

505

506 report_fatal_error("Unhandled mapping of read-write csect to section.");

508 return FuncDSCsects;

511 "Mapping invalid csect. CSECT with bss storage class must be "

512 "common type.");

513 return BSSCsects;

516 "Mapping invalid csect. CSECT with tdata storage class must be "

517 "an initialized csect.");

518 return TDataCsects;

521 "Mapping invalid csect. CSECT with tbss storage class must be "

522 "an uninitialized csect.");

523 return TBSSCsects;

526 "Only an initialized csect can contain TOC-base.");

527 assert(TOCCsects.empty() &&

528 "We should have only one TOC-base, and it should be the first csect "

529 "in this CsectGroup.");

530 return TOCCsects;

534 "A TOC symbol must be an initialized csect.");

535 assert(!TOCCsects.empty() &&

536 "We should at least have a TOC-base in this CsectGroup.");

537 return TOCCsects;

541 "Symbol type incompatible with toc-data.");

542 assert(!TOCCsects.empty() &&

543 "We should at least have a TOC-base in this CsectGroup.");

544 return TOCCsects;

545 default:

547 }

548}

549

550static MCSectionXCOFF *getContainingCsect(const MCSymbolXCOFF *XSym) {

554}

555

556void XCOFFWriter::executePostLayoutBinding() {

557 for (const auto &S : *Asm) {

558 auto *MCSec = static_cast<const MCSectionXCOFF *>(&S);

559 assert(!SectionMap.contains(MCSec) && "Cannot add a section twice.");

560

561

562

566

567

568

570 "An undefined csect should not get registered.");

571 CsectGroup &Group = getCsectGroup(MCSec);

572 Group.emplace_back(MCSec);

573 SectionMap[MCSec] = &Group.back();

575

576 std::unique_ptr DwarfSec =

577 std::make_unique(MCSec);

578 SectionMap[MCSec] = DwarfSec.get();

579

580 DwarfSectionEntry SecEntry(MCSec->getName(),

582 std::move(DwarfSec));

583 DwarfSections.push_back(std::move(SecEntry));

584 } else

586 }

587

588 for (const MCSymbol &S : Asm->symbols()) {

589

590 if (S.isTemporary())

591 continue;

592

593 auto *XSym = static_cast<const MCSymbolXCOFF *>(&S);

594 const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym);

595

597 continue;

598

600 HasVisibility = true;

601

603

604 UndefinedCsects.emplace_back(ContainingCsect);

605 SectionMap[ContainingCsect] = &UndefinedCsects.back();

606 if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName()))

608 continue;

609 }

610

611

612

614 continue;

615

616

618 continue;

619

621 "Expected containing csect to exist in map");

622 XCOFFSection *Csect = SectionMap[ContainingCsect];

623

624 assert(Csect->MCSec->isCsect() && "only csect is supported now!");

625 Csect->Syms.emplace_back(XSym);

626

627

628

631 }

632

633 std::unique_ptr &CISI = CInfoSymSection.Entry;

634 if (CISI && nameShouldBeInStringTable(CISI->Name))

635 Strings.add(CISI->Name);

636

637

638 if (FileNames.empty())

639 FileNames.emplace_back(".file", 0);

640 for (const std::pair<std::string, size_t> &F : FileNames) {

641 if (auxFileSymNameShouldBeInStringTable(F.first))

642 Strings.add(F.first);

643 }

644

645

646

647 if (nameShouldBeInStringTable(".file"))

648 Strings.add(".file");

649 StringRef Vers = CompilerVersion;

650 if (auxFileSymNameShouldBeInStringTable(Vers))

651 Strings.add(Vers);

652

654 assignAddressesAndIndices(*Asm);

655}

656

657void XCOFFWriter::recordRelocation(const MCFragment &F, const MCFixup &Fixup,

658 MCValue Target, uint64_t &FixedValue) {

659 auto getIndex = [this](const MCSymbol *Sym,

660 const MCSectionXCOFF *ContainingCsect) {

661

662

663

664 auto It = SymbolIndexMap.find(Sym);

665 return It != SymbolIndexMap.end()

666 ? It->second

668 };

669

670 auto getVirtualAddress =

672 const MCSectionXCOFF *ContainingSect) -> uint64_t {

673

674 if (ContainingSect->isDwarfSect())

675 return Asm->getSymbolOffset(*Sym);

676

677

679 return SectionMap[ContainingSect]->Address;

680

681

682 assert(Sym->isDefined() && "not a valid object that has address!");

683 return SectionMap[ContainingSect]->Address + Asm->getSymbolOffset(*Sym);

684 };

685

687 uint8_t Type;

688 uint8_t SignAndSize;

689 std::tie(Type, SignAndSize) = TargetObjectWriter->getRelocTypeAndSignSize(

691

692 const MCSectionXCOFF *SymASec =

693 getContainingCsect(static_cast<const MCSymbolXCOFF *>(SymA));

695 "Expected containing csect to exist in map.");

696

697 assert((Fixup.getOffset() <= MaxRawDataSize - Asm->getFragmentOffset(F)) &&

698 "Fragment offset + fixup offset is overflowed.");

699 uint32_t FixupOffsetInCsect = Asm->getFragmentOffset(F) + Fixup.getOffset();

700

701 const uint32_t Index = getIndex(SymA, SymASec);

702 if (Type == XCOFF::RelocationType::R_POS ||

703 Type == XCOFF::RelocationType::R_TLS ||

704 Type == XCOFF::RelocationType::R_TLS_LE ||

705 Type == XCOFF::RelocationType::R_TLS_IE ||

706 Type == XCOFF::RelocationType::R_TLS_LD)

707

708

709 FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();

710 else if (Type == XCOFF::RelocationType::R_TLSM)

711

712

713 FixedValue = 0;

714 else if (Type == XCOFF::RelocationType::R_TOC ||

715 Type == XCOFF::RelocationType::R_TOCL) {

716

717

718

719

720

722 FixedValue = 0;

723 } else {

724

725

726 int64_t TOCEntryOffset = SectionMap[SymASec]->Address -

727 TOCCsects.front().Address + Target.getConstant();

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

744 if (Type == XCOFF::RelocationType::R_TOC && isInt<16>(TOCEntryOffset))

746

747 FixedValue = TOCEntryOffset;

748 }

749 } else if (Type == XCOFF::RelocationType::R_RBR) {

750 auto *ParentSec = static_cast<MCSectionXCOFF *>(F.getParent());

752 ParentSec->getMappingClass() == XCOFF::XMC_PR) &&

753 "Only XMC_PR csect may have the R_RBR relocation.");

754

755

756

757 uint64_t BRInstrAddress =

758 SectionMap[ParentSec]->Address + FixupOffsetInCsect;

759

760

761 FixedValue = getVirtualAddress(SymA, SymASec) - BRInstrAddress +

762 Target.getConstant();

763 } else if (Type == XCOFF::RelocationType::R_REF) {

764

765

766 FixedValue = 0;

767 FixupOffsetInCsect = 0;

768 }

769

770 XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type};

771 auto *RelocationSec = static_cast<MCSectionXCOFF *>(F.getParent());

773 "Expected containing csect to exist in map.");

774 SectionMap[RelocationSec]->Relocations.push_back(Reloc);

775

776 auto SymB = static_cast<const MCSymbolXCOFF *>(Target.getSubSym());

777 if (!SymB)

778 return;

779 if (SymA == SymB)

780 report_fatal_error("relocation for opposite term is not yet supported");

781

782 const MCSectionXCOFF *SymBSec = getContainingCsect(SymB);

784 "Expected containing csect to exist in map.");

785 if (SymASec == SymBSec)

787 "relocation for paired relocatable term is not yet supported");

788

789 assert(Type == XCOFF::RelocationType::R_POS &&

790 "SymA must be R_POS here if it's not opposite term or paired "

791 "relocatable term.");

792 const uint32_t IndexB = getIndex(SymB, SymBSec);

793

794

795 const uint8_t TypeB = XCOFF::RelocationType::R_NEG;

796 XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};

797 SectionMap[RelocationSec]->Relocations.push_back(RelocB);

798

799

800 FixedValue -= getVirtualAddress(SymB, SymBSec);

801}

802

803void XCOFFWriter::writeSections(const MCAssembler &Asm) {

804 uint64_t CurrentAddressLocation = 0;

805 for (const auto *Section : Sections)

806 writeSectionForControlSectionEntry(Asm, *Section, CurrentAddressLocation);

807 for (const auto &DwarfSection : DwarfSections)

808 writeSectionForDwarfSectionEntry(Asm, DwarfSection, CurrentAddressLocation);

809 writeSectionForExceptionSectionEntry(Asm, ExceptionSection,

810 CurrentAddressLocation);

811 writeSectionForCInfoSymSectionEntry(Asm, CInfoSymSection,

812 CurrentAddressLocation);

813}

814

815uint64_t XCOFFWriter::writeObject() {

816

817

818

819

820 finalizeSectionInfo();

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

822

823 writeFileHeader();

824 writeAuxFileHeader();

825 writeSectionHeaderTable();

826 writeSections(*Asm);

827 writeRelocations();

829

831

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

833}

834

835bool XCOFFWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {

837}

838

839void XCOFFWriter::writeSymbolName(const StringRef &SymbolName) {

840

841 if (nameShouldBeInStringTable(SymbolName)) {

842 W.write<int32_t>(0);

843 W.write<uint32_t>(Strings.getOffset(SymbolName));

844 } else {

848 W.write(NameRef);

849 }

850}

851

852void XCOFFWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,

853 int16_t SectionNumber, uint16_t SymbolType,

855 uint8_t NumberOfAuxEntries) {

857 W.write<uint64_t>(Value);

858 W.write<uint32_t>(Strings.getOffset(SymbolName));

859 } else {

860 writeSymbolName(SymbolName);

861 W.write<uint32_t>(Value);

862 }

863 W.write<int16_t>(SectionNumber);

866 W.write<uint8_t>(NumberOfAuxEntries);

867}

868

869void XCOFFWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,

870 uint8_t SymbolAlignmentAndType,

872 W.write<uint32_t>(is64Bit() ? Lo_32(SectionOrLength) : SectionOrLength);

873 W.write<uint32_t>(0);

874 W.write<uint16_t>(0);

875 W.write<uint8_t>(SymbolAlignmentAndType);

878 W.write<uint32_t>(Hi_32(SectionOrLength));

879 W.OS.write_zeros(1);

881 } else {

882 W.write<uint32_t>(0);

883 W.write<uint16_t>(0);

884 }

885}

886

887bool XCOFFWriter::auxFileSymNameShouldBeInStringTable(

888 const StringRef &SymbolName) {

890}

891

892void XCOFFWriter::writeAuxFileSymName(const StringRef &SymbolName) {

893

894 if (auxFileSymNameShouldBeInStringTable(SymbolName)) {

895 W.write<int32_t>(0);

896 W.write<uint32_t>(Strings.getOffset(SymbolName));

898 } else {

902 W.write(NameRef);

903 }

904}

905

906void XCOFFWriter::writeSymbolAuxFileEntry(StringRef &Name, uint8_t ftype) {

907 writeAuxFileSymName(Name);

908 W.write<uint8_t>(ftype);

909 W.OS.write_zeros(2);

912 else

913 W.OS.write_zeros(1);

914}

915

916void XCOFFWriter::writeSymbolAuxDwarfEntry(uint64_t LengthOfSectionPortion,

917 uint64_t NumberOfRelocEnt) {

918 writeWord(LengthOfSectionPortion);

920 W.OS.write_zeros(4);

921 writeWord(NumberOfRelocEnt);

923 W.OS.write_zeros(1);

925 } else {

926 W.OS.write_zeros(6);

927 }

928}

929

930void XCOFFWriter::writeSymbolEntryForCsectMemberLabel(

931 const Symbol &SymbolRef, const XCOFFSection &CSectionRef,

932 int16_t SectionIndex, uint64_t SymbolOffset) {

933 assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&

934 "Symbol address overflowed.");

935

936 auto Entry = ExceptionSection.ExceptionTable.find(SymbolRef.MCSym->getName());

937 if (Entry != ExceptionSection.ExceptionTable.end()) {

938 writeSymbolEntry(SymbolRef.getSymbolTableName(),

939 CSectionRef.Address + SymbolOffset, SectionIndex,

940

941

942

943 is64Bit() ? SymbolRef.getVisibilityType()

944 : SymbolRef.getVisibilityType() | 0x0020,

945 SymbolRef.getStorageClass(),

946 (is64Bit() && ExceptionSection.isDebugEnabled) ? 3 : 2);

947 if (is64Bit() && ExceptionSection.isDebugEnabled) {

948

949

950 writeSymbolAuxExceptionEntry(

951 ExceptionSection.FileOffsetToData +

952 getExceptionOffset(Entry->second.FunctionSymbol),

953 Entry->second.FunctionSize,

954 SymbolIndexMap[Entry->second.FunctionSymbol] + 4);

955 }

956

957

958 writeSymbolAuxFunctionEntry(

959 ExceptionSection.FileOffsetToData +

960 getExceptionOffset(Entry->second.FunctionSymbol),

961 Entry->second.FunctionSize, 0,

962 (is64Bit() && ExceptionSection.isDebugEnabled)

963 ? SymbolIndexMap[Entry->second.FunctionSymbol] + 4

964 : SymbolIndexMap[Entry->second.FunctionSymbol] + 3);

965 } else {

966 writeSymbolEntry(SymbolRef.getSymbolTableName(),

967 CSectionRef.Address + SymbolOffset, SectionIndex,

968 SymbolRef.getVisibilityType(),

969 SymbolRef.getStorageClass());

970 }

971 writeSymbolAuxCsectEntry(CSectionRef.SymbolTableIndex, XCOFF::XTY_LD,

973}

974

975void XCOFFWriter::writeSymbolEntryForDwarfSection(

976 const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {

977 assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!");

978

979 writeSymbolEntry(DwarfSectionRef.getSymbolTableName(), 0,

981

982 writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);

983}

984

985void XCOFFWriter::writeSymbolEntryForControlSection(

986 const XCOFFSection &CSectionRef, int16_t SectionIndex,

988 writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,

989 SectionIndex, CSectionRef.getVisibilityType(), StorageClass);

990

991 writeSymbolAuxCsectEntry(CSectionRef.Size, getEncodedType(CSectionRef.MCSec),

993}

994

995void XCOFFWriter::writeSymbolAuxFunctionEntry(uint32_t EntryOffset,

996 uint32_t FunctionSize,

997 uint64_t LineNumberPointer,

998 uint32_t EndIndex) {

1000 writeWord(LineNumberPointer);

1001 else

1002 W.write<uint32_t>(EntryOffset);

1003 W.write<uint32_t>(FunctionSize);

1005 writeWord(LineNumberPointer);

1006 W.write<uint32_t>(EndIndex);

1008 W.OS.write_zeros(1);

1010 } else {

1011 W.OS.write_zeros(2);

1012 }

1013}

1014

1015void XCOFFWriter::writeSymbolAuxExceptionEntry(uint64_t EntryOffset,

1016 uint32_t FunctionSize,

1017 uint32_t EndIndex) {

1018 assert(is64Bit() && "Exception auxilliary entries are 64-bit only.");

1019 W.write<uint64_t>(EntryOffset);

1020 W.write<uint32_t>(FunctionSize);

1021 W.write<uint32_t>(EndIndex);

1022 W.OS.write_zeros(1);

1024}

1025

1026void XCOFFWriter::writeFileHeader() {

1028 W.write<uint16_t>(SectionCount);

1029 W.write<int32_t>(0);

1030 writeWord(SymbolTableOffset);

1032 W.write<uint16_t>(auxiliaryHeaderSize());

1033 W.write<uint16_t>(0);

1034 W.write<int32_t>(SymbolTableEntryCount);

1035 } else {

1036 W.write<int32_t>(SymbolTableEntryCount);

1037 W.write<uint16_t>(auxiliaryHeaderSize());

1038 W.write<uint16_t>(0);

1039 }

1040}

1041

1042void XCOFFWriter::writeAuxFileHeader() {

1043 if (!auxiliaryHeaderSize())

1044 return;

1045 W.write<uint16_t>(0);

1046 W.write<uint16_t>(

1048

1049

1050 W.write<uint32_t>(Sections[0]->Size);

1051 W.write<uint32_t>(Sections[1]->Size);

1052 W.write<uint32_t>(Sections[2]->Size);

1053 W.write<uint32_t>(0);

1054 W.write<uint32_t>(Sections[0]->Address);

1055 W.write<uint32_t>(Sections[1]->Address);

1056}

1057

1058void XCOFFWriter::writeSectionHeader(const SectionEntry *Sec) {

1061

1062 if (Sec->Index == SectionEntry::UninitializedIndex)

1063 return;

1064

1065

1067 W.write(NameRef);

1068

1069

1070

1071 writeWord(IsDwarf ? 0 : Sec->Address);

1072

1073 writeWord((IsDwarf || IsOvrflo) ? 0 : Sec->Address);

1074

1075 writeWord(Sec->Size);

1076 writeWord(Sec->FileOffsetToData);

1077 writeWord(Sec->FileOffsetToRelocations);

1078 writeWord(0);

1079

1081 W.write<uint32_t>(Sec->RelocationCount);

1082 W.write<uint32_t>(0);

1083 W.write<int32_t>(Sec->Flags);

1084 W.OS.write_zeros(4);

1085 } else {

1086

1087

1088

1089

1090 W.write<uint16_t>(Sec->RelocationCount);

1092 ? Sec->RelocationCount

1093 : 0);

1094 W.write<int32_t>(Sec->Flags);

1095 }

1096}

1097

1098void XCOFFWriter::writeSectionHeaderTable() {

1099 for (const auto *CsectSec : Sections)

1100 writeSectionHeader(CsectSec);

1101 for (const auto &DwarfSec : DwarfSections)

1102 writeSectionHeader(&DwarfSec);

1103 for (const auto &OverflowSec : OverflowSections)

1104 writeSectionHeader(&OverflowSec);

1105 if (hasExceptionSection())

1106 writeSectionHeader(&ExceptionSection);

1107 if (CInfoSymSection.Entry)

1108 writeSectionHeader(&CInfoSymSection);

1109}

1110

1111void XCOFFWriter::writeRelocation(XCOFFRelocation Reloc,

1112 const XCOFFSection &Section) {

1113 if (Section.MCSec->isCsect())

1114 writeWord(Section.Address + Reloc.FixupOffsetInCsect);

1115 else {

1116

1117 assert(Section.MCSec->isDwarfSect() && "unsupport section type!");

1118 writeWord(Reloc.FixupOffsetInCsect);

1119 }

1120 W.write<uint32_t>(Reloc.SymbolTableIndex);

1121 W.write<uint8_t>(Reloc.SignAndSize);

1122 W.write<uint8_t>(Reloc.Type);

1123}

1124

1125void XCOFFWriter::writeRelocations() {

1126 for (const auto *Section : Sections) {

1127 if (Section->Index == SectionEntry::UninitializedIndex)

1128

1129 continue;

1130

1131 for (const auto *Group : Section->Groups) {

1132 if (Group->empty())

1133 continue;

1134

1135 for (const auto &Csect : *Group) {

1136 for (const auto Reloc : Csect.Relocations)

1137 writeRelocation(Reloc, Csect);

1138 }

1139 }

1140 }

1141

1142 for (const auto &DwarfSection : DwarfSections)

1143 for (const auto &Reloc : DwarfSection.DwarfSect->Relocations)

1144 writeRelocation(Reloc, *DwarfSection.DwarfSect);

1145}

1146

1147void XCOFFWriter::writeSymbolTable(MCAssembler &Asm) {

1148

1149 StringRef Vers = CompilerVersion;

1150

1151 for (const std::pair<std::string, size_t> &F : FileNames) {

1152

1153

1154 StringRef FileName = F.first;

1155

1156

1157

1158

1159

1160

1161 uint8_t LangID;

1171 else

1173

1175

1176 int NumberOfFileAuxEntries = 1;

1177 if (!Vers.empty())

1178 ++NumberOfFileAuxEntries;

1179 writeSymbolEntry(".file", 0, XCOFF::ReservedSectionNum::N_DEBUG,

1180 (LangID << 8) | CpuID, XCOFF::C_FILE,

1181 NumberOfFileAuxEntries);

1182 writeSymbolAuxFileEntry(FileName, XCOFF::XFT_FN);

1183 if (!Vers.empty())

1185 }

1186

1187 if (CInfoSymSection.Entry)

1188 writeSymbolEntry(CInfoSymSection.Entry->Name, CInfoSymSection.Entry->Offset,

1189 CInfoSymSection.Index,

1191 0);

1192

1193 for (const auto &Csect : UndefinedCsects) {

1194 writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF,

1196 }

1197

1198 for (const auto *Section : Sections) {

1199 if (Section->Index == SectionEntry::UninitializedIndex)

1200

1201 continue;

1202

1203 for (const auto *Group : Section->Groups) {

1204 if (Group->empty())

1205 continue;

1206

1207 const int16_t SectionIndex = Section->Index;

1208 for (const auto &Csect : *Group) {

1209

1210 writeSymbolEntryForControlSection(Csect, SectionIndex,

1212

1213 for (const auto &Sym : Csect.Syms)

1214 writeSymbolEntryForCsectMemberLabel(

1215 Sym, Csect, SectionIndex, Asm.getSymbolOffset(*(Sym.MCSym)));

1216 }

1217 }

1218 }

1219

1220 for (const auto &DwarfSection : DwarfSections)

1221 writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect,

1222 DwarfSection.Index);

1223}

1224

1225void XCOFFWriter::finalizeRelocationInfo(SectionEntry *Sec, uint64_t RelCount) {

1226

1227

1229

1231

1232

1233

1234 SecEntry.RelocationCount = Sec->Index;

1235

1236

1237

1238 SecEntry.Address = RelCount;

1239 SecEntry.Index = ++SectionCount;

1240 OverflowSections.push_back(std::move(SecEntry));

1241

1242

1243

1245 } else {

1246 Sec->RelocationCount = RelCount;

1247 }

1248}

1249

1250void XCOFFWriter::calcOffsetToRelocations(SectionEntry *Sec,

1251 uint64_t &RawPointer) {

1252 if (!Sec->RelocationCount)

1253 return;

1254

1255 Sec->FileOffsetToRelocations = RawPointer;

1256 uint64_t RelocationSizeInSec = 0;

1259

1260 for (auto &OverflowSec : OverflowSections) {

1261 if (OverflowSec.RelocationCount == static_cast<uint32_t>(Sec->Index)) {

1262 RelocationSizeInSec =

1264

1265

1266

1267 OverflowSec.FileOffsetToRelocations = Sec->FileOffsetToRelocations;

1268 }

1269 }

1270 assert(RelocationSizeInSec && "Overflow section header doesn't exist.");

1271 } else {

1272 RelocationSizeInSec = Sec->RelocationCount *

1275 }

1276

1277 RawPointer += RelocationSizeInSec;

1278 if (RawPointer > MaxRawDataSize)

1280}

1281

1282void XCOFFWriter::finalizeSectionInfo() {

1283 for (auto *Section : Sections) {

1284 if (Section->Index == SectionEntry::UninitializedIndex)

1285

1286 continue;

1287

1288 uint64_t RelCount = 0;

1289 for (const auto *Group : Section->Groups) {

1290 if (Group->empty())

1291 continue;

1292

1293 for (auto &Csect : *Group)

1294 RelCount += Csect.Relocations.size();

1295 }

1296 finalizeRelocationInfo(Section, RelCount);

1297 }

1298

1299 for (auto &DwarfSection : DwarfSections)

1300 finalizeRelocationInfo(&DwarfSection,

1301 DwarfSection.DwarfSect->Relocations.size());

1302

1303

1304 uint64_t RawPointer =

1309 auxiliaryHeaderSize();

1310

1311

1312 for (auto *Sec : Sections) {

1313 if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)

1314 continue;

1315

1316 RawPointer = Sec->advanceFileOffset(MaxRawDataSize, RawPointer);

1317 }

1318

1319 if (!DwarfSections.empty()) {

1320 RawPointer += PaddingsBeforeDwarf;

1321 for (auto &DwarfSection : DwarfSections) {

1322 RawPointer = DwarfSection.advanceFileOffset(MaxRawDataSize, RawPointer);

1323 }

1324 }

1325

1326 if (hasExceptionSection())

1327 RawPointer = ExceptionSection.advanceFileOffset(MaxRawDataSize, RawPointer);

1328

1329 if (CInfoSymSection.Entry)

1330 RawPointer = CInfoSymSection.advanceFileOffset(MaxRawDataSize, RawPointer);

1331

1332 for (auto *Sec : Sections) {

1333 if (Sec->Index != SectionEntry::UninitializedIndex)

1334 calcOffsetToRelocations(Sec, RawPointer);

1335 }

1336

1337 for (auto &DwarfSec : DwarfSections)

1338 calcOffsetToRelocations(&DwarfSec, RawPointer);

1339

1340

1341

1342 if (SymbolTableEntryCount)

1343 SymbolTableOffset = RawPointer;

1344}

1345

1346void XCOFFWriter::addExceptionEntry(const MCSymbol *Symbol,

1347 const MCSymbol *Trap, unsigned LanguageCode,

1348 unsigned ReasonCode, unsigned FunctionSize,

1349 bool hasDebug) {

1350

1351

1352 if (hasDebug)

1353 ExceptionSection.isDebugEnabled = true;

1354 auto Entry = ExceptionSection.ExceptionTable.find(Symbol->getName());

1355 if (Entry != ExceptionSection.ExceptionTable.end()) {

1356 Entry->second.Entries.push_back(

1357 ExceptionTableEntry(Trap, LanguageCode, ReasonCode));

1358 return;

1359 }

1360 ExceptionInfo NewEntry;

1361 NewEntry.FunctionSymbol = Symbol;

1362 NewEntry.FunctionSize = FunctionSize;

1363 NewEntry.Entries.push_back(

1364 ExceptionTableEntry(Trap, LanguageCode, ReasonCode));

1365 ExceptionSection.ExceptionTable.insert(

1366 std::pair<const StringRef, ExceptionInfo>(Symbol->getName(), NewEntry));

1367}

1368

1369unsigned XCOFFWriter::getExceptionSectionSize() {

1370 unsigned EntryNum = 0;

1371

1372 for (const auto &TableEntry : ExceptionSection.ExceptionTable)

1373

1374

1375 EntryNum += TableEntry.second.Entries.size() + 1;

1376

1379}

1380

1381unsigned XCOFFWriter::getExceptionOffset(const MCSymbol *Symbol) {

1382 unsigned EntryNum = 0;

1383 for (const auto &TableEntry : ExceptionSection.ExceptionTable) {

1384 if (Symbol == TableEntry.second.FunctionSymbol)

1385 break;

1386 EntryNum += TableEntry.second.Entries.size() + 1;

1387 }

1390}

1391

1392void XCOFFWriter::addCInfoSymEntry(StringRef Name, StringRef Metadata) {

1393 assert(!CInfoSymSection.Entry && "Multiple entries are not supported");

1394 CInfoSymSection.addEntry(

1395 std::make_unique(Name.str(), Metadata.str()));

1396}

1397

1398void XCOFFWriter::assignAddressesAndIndices(MCAssembler &Asm) {

1399

1400

1401 uint32_t SymbolTableIndex =

1402 (2 + (CompilerVersion.empty() ? 0 : 1)) * FileNames.size();

1403

1404 if (CInfoSymSection.Entry)

1405 SymbolTableIndex++;

1406

1407

1408 for (auto &Csect : UndefinedCsects) {

1409 Csect.Size = 0;

1410 Csect.Address = 0;

1411 Csect.SymbolTableIndex = SymbolTableIndex;

1412 SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;

1413

1414 SymbolTableIndex += 2;

1415 }

1416

1417

1418

1419

1421

1422 int32_t SectionIndex = 1;

1423 bool HasTDataSection = false;

1424

1425 for (auto *Section : Sections) {

1426 const bool IsEmpty =

1428 [](const CsectGroup *Group) { return Group->empty(); });

1429 if (IsEmpty)

1430 continue;

1431

1432 if (SectionIndex > MaxSectionIndex)

1434 Section->Index = SectionIndex++;

1435 SectionCount++;

1436

1437 bool SectionAddressSet = false;

1438

1441 HasTDataSection = true;

1442 }

1443

1444

1447

1448 for (auto *Group : Section->Groups) {

1449 if (Group->empty())

1450 continue;

1451

1452 for (auto &Csect : *Group) {

1453 const MCSectionXCOFF *MCSec = Csect.MCSec;

1455 Csect.Size = Asm.getSectionAddressSize(*MCSec);

1456 Address = Csect.Address + Csect.Size;

1457 Csect.SymbolTableIndex = SymbolTableIndex;

1458 SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;

1459

1460 SymbolTableIndex += 2;

1461

1462 for (auto &Sym : Csect.Syms) {

1463 bool hasExceptEntry = false;

1465 ExceptionSection.ExceptionTable.find(Sym.MCSym->getName());

1466 if (Entry != ExceptionSection.ExceptionTable.end()) {

1467 hasExceptEntry = true;

1468 for (auto &TrapEntry : Entry->second.Entries) {

1469 TrapEntry.TrapAddress = Asm.getSymbolOffset(*(Sym.MCSym)) +

1470 TrapEntry.Trap->getOffset();

1471 }

1472 }

1473 Sym.SymbolTableIndex = SymbolTableIndex;

1474 SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex;

1475

1476

1477

1478

1479 SymbolTableIndex += 2;

1480 if (hasExceptionSection() && hasExceptEntry) {

1481 if (is64Bit() && ExceptionSection.isDebugEnabled)

1482 SymbolTableIndex += 2;

1483 else

1484 SymbolTableIndex += 1;

1485 }

1486 }

1487 }

1488

1489 if (!SectionAddressSet) {

1490 Section->Address = Group->front().Address;

1491 SectionAddressSet = true;

1492 }

1493 }

1494

1495

1496

1499 }

1500

1501

1502

1503

1504

1505

1506 if (!DwarfSections.empty())

1507 PaddingsBeforeDwarf =

1509 (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) -

1511

1512 DwarfSectionEntry *LastDwarfSection = nullptr;

1513 for (auto &DwarfSection : DwarfSections) {

1514 assert((SectionIndex <= MaxSectionIndex) && "Section index overflow!");

1515

1516 XCOFFSection &DwarfSect = *DwarfSection.DwarfSect;

1517 const MCSectionXCOFF *MCSec = DwarfSect.MCSec;

1518

1519

1520 DwarfSection.Index = SectionIndex++;

1521 SectionCount++;

1522

1523

1524 DwarfSect.SymbolTableIndex = SymbolTableIndex;

1525 SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex;

1526

1527 SymbolTableIndex += 2;

1528

1529

1530

1531

1532

1533 DwarfSection.Address = DwarfSect.Address =

1535

1536

1537

1538 DwarfSection.Size = DwarfSect.Size = Asm.getSectionAddressSize(*MCSec);

1539

1540 Address = DwarfSection.Address + DwarfSection.Size;

1541

1542 if (LastDwarfSection)

1543 LastDwarfSection->MemorySize =

1544 DwarfSection.Address - LastDwarfSection->Address;

1545 LastDwarfSection = &DwarfSection;

1546 }

1547 if (LastDwarfSection) {

1548

1549

1550 Address = alignTo(LastDwarfSection->Address + LastDwarfSection->Size,

1551 DefaultSectionAlign);

1552 LastDwarfSection->MemorySize = Address - LastDwarfSection->Address;

1553 }

1554 if (hasExceptionSection()) {

1555 ExceptionSection.Index = SectionIndex++;

1556 SectionCount++;

1557 ExceptionSection.Address = 0;

1558 ExceptionSection.Size = getExceptionSectionSize();

1559 Address += ExceptionSection.Size;

1561 }

1562

1563 if (CInfoSymSection.Entry) {

1564 CInfoSymSection.Index = SectionIndex++;

1565 SectionCount++;

1566 CInfoSymSection.Address = 0;

1567 Address += CInfoSymSection.Size;

1569 }

1570

1571 SymbolTableEntryCount = SymbolTableIndex;

1572}

1573

1574void XCOFFWriter::writeSectionForControlSectionEntry(

1575 const MCAssembler &Asm, const CsectSectionEntry &CsectEntry,

1576 uint64_t &CurrentAddressLocation) {

1577

1578 if (CsectEntry.Index == SectionEntry::UninitializedIndex)

1579 return;

1580

1581

1582

1583

1584

1585 assert(((CurrentAddressLocation <= CsectEntry.Address) ||

1588 "CurrentAddressLocation should be less than or equal to section "

1589 "address if the section is not TData or TBSS.");

1590

1591 CurrentAddressLocation = CsectEntry.Address;

1592

1593

1594

1595

1596 if (CsectEntry.IsVirtual) {

1597 CurrentAddressLocation += CsectEntry.Size;

1598 return;

1599 }

1600

1601 for (const auto &Group : CsectEntry.Groups) {

1602 for (const auto &Csect : *Group) {

1603 if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)

1604 W.OS.write_zeros(PaddingSize);

1605 if (Csect.Size)

1606 Asm.writeSectionData(W.OS, Csect.MCSec);

1607 CurrentAddressLocation = Csect.Address + Csect.Size;

1608 }

1609 }

1610

1611

1612

1613

1614 if (uint64_t PaddingSize =

1615 CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) {

1616 W.OS.write_zeros(PaddingSize);

1617 CurrentAddressLocation += PaddingSize;

1618 }

1619}

1620

1621void XCOFFWriter::writeSectionForDwarfSectionEntry(

1622 const MCAssembler &Asm, const DwarfSectionEntry &DwarfEntry,

1623 uint64_t &CurrentAddressLocation) {

1624

1625

1626

1627 assert(CurrentAddressLocation <= DwarfEntry.Address &&

1628 "CurrentAddressLocation should be less than or equal to section "

1629 "address.");

1630

1631 if (uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation)

1632 W.OS.write_zeros(PaddingSize);

1633

1634 if (DwarfEntry.Size)

1635 Asm.writeSectionData(W.OS, DwarfEntry.DwarfSect->MCSec);

1636

1637 CurrentAddressLocation = DwarfEntry.Address + DwarfEntry.Size;

1638

1639

1640

1641 uint32_t Mod = CurrentAddressLocation % DefaultSectionAlign;

1642 uint32_t TailPaddingSize = Mod ? DefaultSectionAlign - Mod : 0;

1643 if (TailPaddingSize)

1644 W.OS.write_zeros(TailPaddingSize);

1645

1646 CurrentAddressLocation += TailPaddingSize;

1647}

1648

1649void XCOFFWriter::writeSectionForExceptionSectionEntry(

1650 const MCAssembler &Asm, ExceptionSectionEntry &ExceptionEntry,

1651 uint64_t &CurrentAddressLocation) {

1652 for (const auto &TableEntry : ExceptionEntry.ExceptionTable) {

1653

1654

1655 W.write<uint32_t>(SymbolIndexMap[TableEntry.second.FunctionSymbol]);

1657

1658 W.OS.write_zeros(4);

1659 }

1660 W.OS.write_zeros(2);

1661 for (auto &TrapEntry : TableEntry.second.Entries) {

1662 writeWord(TrapEntry.TrapAddress);

1663 W.write<uint8_t>(TrapEntry.Lang);

1664 W.write<uint8_t>(TrapEntry.Reason);

1665 }

1666 }

1667

1668 CurrentAddressLocation += getExceptionSectionSize();

1669}

1670

1671void XCOFFWriter::writeSectionForCInfoSymSectionEntry(

1672 const MCAssembler &Asm, CInfoSymSectionEntry &CInfoSymEntry,

1673 uint64_t &CurrentAddressLocation) {

1674 if (!CInfoSymSection.Entry)

1675 return;

1676

1677 constexpr int WordSize = sizeof(uint32_t);

1678 std::unique_ptr &CISI = CInfoSymEntry.Entry;

1679 const std::string &Metadata = CISI->Metadata;

1680

1681

1682 W.write<uint32_t>(Metadata.size());

1683

1685 return;

1686

1687

1688 size_t Index = 0;

1689 while (Index + WordSize <= Metadata.size()) {

1690 uint32_t NextWord =

1692 W.write<uint32_t>(NextWord);

1693 Index += WordSize;

1694 }

1695

1696

1697 if (CISI->paddingSize()) {

1698 std::array<uint8_t, WordSize> LastWord = {0};

1699 ::memcpy(LastWord.data(), Metadata.data() + Index, Metadata.size() - Index);

1701 }

1702

1703 CurrentAddressLocation += CISI->size();

1704}

1705

1706

1707

1708

1709uint8_t getEncodedType(const MCSectionXCOFF *Sec) {

1711

1712

1713

1714 uint8_t EncodedAlign = Log2Align << 3;

1716}

1717

1718}

1719

1720std::unique_ptr

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

1724}

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

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

static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t MembersOffset, unsigned NumSyms, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0, bool Is64Bit=false)

static const Function * getParent(const Value *V)

static unsigned getCPUType(const MachOObjectFile &O)

PowerPC TLS Dynamic Call Fixup

if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod

static bool is64Bit(const char *name)

iterator find(const_arg_type_t< KeyT > Val)

bool contains(const_arg_type_t< KeyT > Val) const

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

virtual void reset()

lifetime management

StringRef getSymbolTableName() const

std::optional< XCOFF::DwarfSectionSubtypeFlags > getDwarfSubtypeFlags() const

XCOFF::StorageClass getStorageClass() const

XCOFF::StorageMappingClass getMappingClass() const

MCSymbolXCOFF * getQualNameSymbol() const

XCOFF::SymbolType getCSectType() const

StringRef getName() const

XCOFF::VisibilityType getVisibilityType() const

StringRef getSymbolTableName() const

MCSectionXCOFF * getRepresentedCsect() const

bool isDefined() const

isDefined - Check if this symbol is defined (i.e., it has an address).

StringRef getName() const

getName - Get the symbol name.

MCFragment * getFragment() const

SectionEntry - represents a section emitted into memory by the dynamic linker.

SectionEntry(StringRef name, uint8_t *address, size_t size, size_t allocationSize, uintptr_t objAddress)

constexpr bool empty() const

empty - Check if the string is empty.

bool ends_with(StringRef Suffix) const

Check if this string ends with the given Suffix.

LLVM_ABI bool ends_with_insensitive(StringRef Suffix) const

Check if this string ends with the given Suffix, ignoring case.

Utility for building string tables with deduplicated suffixes.

LLVM_ABI size_t getOffset(CachedHashStringRef S) const

Get the offest of a string in the string table.

LLVM_ABI size_t add(CachedHashStringRef S, uint8_t Priority=0)

Add a string to the builder.

LLVM_ABI void write(raw_ostream &OS) const

LLVM_ABI void finalize()

Analyze the strings and build the final table.

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

#define llvm_unreachable(msg)

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

constexpr char SymbolName[]

Key for Kernel::Metadata::mSymbolName.

C::iterator addEntry(C &Container, StringRef InstallName)

constexpr size_t RelocationSerializationSize32

LLVM_ABI XCOFF::CFileCpuId getCpuID(StringRef CPU)

constexpr size_t ExceptionSectionEntrySize64

constexpr size_t RelocationSerializationSize64

constexpr size_t ExceptionSectionEntrySize32

constexpr size_t FileHeaderSize64

constexpr size_t SectionHeaderSize64

constexpr size_t AuxFileEntNameSize

@ AUX_SECT

Identifies a SECT auxiliary entry.

@ AUX_FILE

Identifies a file auxiliary entry.

@ AUX_EXCEPT

Identifies an exception auxiliary entry.

@ AUX_FCN

Identifies a function auxiliary entry.

@ AUX_CSECT

Identifies a csect auxiliary entry.

@ TB_Fortran

Fortran language.

@ TB_CPLUSPLUS

C++ language.

VisibilityType

Values for visibility as they would appear when encoded in the high 4 bits of the 16-bit unsigned n_t...

constexpr size_t NameSize

constexpr uint16_t RelocOverflow

constexpr size_t AuxFileHeaderSizeShort

@ XFT_FN

Specifies the source-file name.

@ XFT_CV

Specifies the compiler version number.

constexpr size_t FileHeaderSize32

StorageMappingClass

Storage Mapping Class definitions.

@ XMC_TE

Symbol mapped at the end of TOC.

@ XMC_TC0

TOC Anchor for TOC Addressability.

@ XMC_DS

Descriptor csect.

@ XMC_TL

Initialized thread-local variable.

@ XMC_RO

Read Only Constant.

@ XMC_TD

Scalar data item in the TOC.

@ XMC_UL

Uninitialized thread-local variable.

@ XMC_BS

BSS class (uninitialized static internal)

@ XMC_TC

General TOC item.

constexpr size_t SectionHeaderSize32

constexpr size_t FileNamePadSize

@ XTY_CM

Common csect definition. For uninitialized storage.

@ XTY_SD

Csect definition for initialized storage.

@ XTY_LD

Label definition.

@ XTY_ER

External reference.

support::ulittle32_t Word

uint32_t read32be(const void *P)

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

bool all_of(R &&range, UnaryPredicate P)

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

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.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

constexpr uint32_t Hi_32(uint64_t Value)

Return the high 32 bits of a 64 bit value.

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

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

constexpr uint32_t Lo_32(uint64_t Value)

Return the low 32 bits of a 64 bit value.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

OutputIt move(R &&Range, OutputIt Out)

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

LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue)

constexpr int64_t SignExtend64(uint64_t x)

Sign-extend the number in the bottom B bits of X to a 64-bit integer.

unsigned Log2(Align A)

Returns the log2 of the alignment.

std::unique_ptr< MCObjectWriter > createXCOFFObjectWriter(std::unique_ptr< MCXCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)

Definition XCOFFObjectWriter.cpp:1721

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