LLVM: lib/ObjectYAML/ELFEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

32#include

33

34using namespace llvm;

35

36

37

38

39

40

41

42

43namespace {

44class ContiguousBlobAccumulator {

45 const uint64_t InitialOffset;

46 const uint64_t MaxSize;

47

48 SmallVector<char, 128> Buf;

49 raw_svector_ostream OS;

51

52 bool checkLimit(uint64_t Size) {

53 if (!ReachedLimitErr && getOffset() + Size <= MaxSize)

54 return true;

55 if (!ReachedLimitErr)

57 "reached the output size limit");

58 return false;

59 }

60

61public:

62 ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit)

63 : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {}

64

65 uint64_t tell() const { return OS.tell(); }

66 uint64_t getOffset() const { return InitialOffset + OS.tell(); }

67 void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); }

68

69 Error takeLimitError() {

70

71 checkLimit(0);

72 return std::move(ReachedLimitErr);

73 }

74

75

76 uint64_t padToAlignment(unsigned Align) {

77 uint64_t CurrentOffset = getOffset();

78 if (ReachedLimitErr)

79 return CurrentOffset;

80

81 uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align);

82 uint64_t PaddingSize = AlignedOffset - CurrentOffset;

83 if (!checkLimit(PaddingSize))

84 return CurrentOffset;

85

86 writeZeros(PaddingSize);

87 return AlignedOffset;

88 }

89

90 raw_ostream *getRawOS(uint64_t Size) {

91 if (checkLimit(Size))

92 return &OS;

93 return nullptr;

94 }

95

96 void writeAsBinary(const yaml::BinaryRef &Bin, uint64_t N = UINT64_MAX) {

97 if (!checkLimit(Bin.binary_size()))

98 return;

99 Bin.writeAsBinary(OS, N);

100 }

101

102 void writeZeros(uint64_t Num) {

103 if (checkLimit(Num))

104 OS.write_zeros(Num);

105 }

106

107 void write(const char *Ptr, size_t Size) {

108 if (checkLimit(Size))

109 OS.write(Ptr, Size);

110 }

111

112 void write(unsigned char C) {

113 if (checkLimit(1))

114 OS.write(C);

115 }

116

117 unsigned writeULEB128(uint64_t Val) {

118 if (!checkLimit(sizeof(uint64_t)))

119 return 0;

121 }

122

123 unsigned writeSLEB128(int64_t Val) {

124 if (!checkLimit(10))

125 return 0;

127 }

128

130 if (checkLimit(sizeof(T)))

132 }

133

134 void updateDataAt(uint64_t Pos, void *Data, size_t Size) {

136 memcpy(&Buf[Pos - InitialOffset], Data, Size);

137 }

138};

139

140

141

142class NameToIdxMap {

143 StringMap Map;

144

145public:

146

147 bool addName(StringRef Name, unsigned Ndx) {

148 return Map.insert({Name, Ndx}).second;

149 }

150

151 bool lookup(StringRef Name, unsigned &Idx) const {

152 auto I = Map.find(Name);

153 if (I == Map.end())

154 return false;

155 Idx = I->getValue();

156 return true;

157 }

158

159 unsigned get(StringRef Name) const {

160 unsigned Idx;

161 if (lookup(Name, Idx))

162 return Idx;

163 assert(false && "Expected section not found in index");

164 return 0;

165 }

166 unsigned size() const { return Map.size(); }

167};

168

169namespace {

170struct Fragment {

172 uint64_t Size;

173 uint32_t Type;

174 uint64_t AddrAlign;

175};

176}

177

178

179

180

181template class ELFState {

183

185

186

188

189

190

191

193

194

196

197

198

199

200

201 StringRef SectionHeaderStringTableName = ".shstrtab";

202 StringTableBuilder *ShStrtabStrings = &DotShStrtab;

203

204 NameToIdxMap SN2I;

205 NameToIdxMap SymN2I;

206 NameToIdxMap DynSymN2I;

207 ELFYAML::Object &Doc;

208

209 std::vector<std::pair<Elf_Shdr *, ELFYAML::Section>>

210 SectionHeadersOverrideHelper;

211

212 StringSet<> ExcludedSectionHeaders;

213

214 uint64_t LocationCounter = 0;

215 bool HasError = false;

219

221 const StringTableBuilder &Strtab);

222 unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = "");

223 unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic);

224

225 void buildSectionIndex();

226 void buildSymbolIndexes();

227 void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);

228 bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header,

229 StringRef SecName, ELFYAML::Section *YAMLSec);

230 void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,

231 ContiguousBlobAccumulator &CBA);

232 void overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders);

233 void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType,

234 ContiguousBlobAccumulator &CBA,

235 ELFYAML::Section *YAMLSec);

236 void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,

237 StringTableBuilder &STB,

238 ContiguousBlobAccumulator &CBA,

239 ELFYAML::Section *YAMLSec);

240 void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,

241 ContiguousBlobAccumulator &CBA,

242 ELFYAML::Section *YAMLSec);

243 void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,

244 std::vector<Elf_Shdr> &SHeaders);

245

246 std::vector

247 getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,

249

250 void finalizeStrings();

251 void writeELFHeader(raw_ostream &OS);

252 void writeSectionContent(Elf_Shdr &SHeader,

253 const ELFYAML::NoBitsSection &Section,

254 ContiguousBlobAccumulator &CBA);

255 void writeSectionContent(Elf_Shdr &SHeader,

256 const ELFYAML::RawContentSection &Section,

257 ContiguousBlobAccumulator &CBA);

258 void writeSectionContent(Elf_Shdr &SHeader,

259 const ELFYAML::RelocationSection &Section,

260 ContiguousBlobAccumulator &CBA);

261 void writeSectionContent(Elf_Shdr &SHeader,

262 const ELFYAML::RelrSection &Section,

263 ContiguousBlobAccumulator &CBA);

264 void writeSectionContent(Elf_Shdr &SHeader,

265 const ELFYAML::GroupSection &Group,

266 ContiguousBlobAccumulator &CBA);

267 void writeSectionContent(Elf_Shdr &SHeader,

268 const ELFYAML::SymtabShndxSection &Shndx,

269 ContiguousBlobAccumulator &CBA);

270 void writeSectionContent(Elf_Shdr &SHeader,

271 const ELFYAML::SymverSection &Section,

272 ContiguousBlobAccumulator &CBA);

273 void writeSectionContent(Elf_Shdr &SHeader,

274 const ELFYAML::VerneedSection &Section,

275 ContiguousBlobAccumulator &CBA);

276 void writeSectionContent(Elf_Shdr &SHeader,

277 const ELFYAML::VerdefSection &Section,

278 ContiguousBlobAccumulator &CBA);

279 void writeSectionContent(Elf_Shdr &SHeader,

280 const ELFYAML::ARMIndexTableSection &Section,

281 ContiguousBlobAccumulator &CBA);

282 void writeSectionContent(Elf_Shdr &SHeader,

283 const ELFYAML::MipsABIFlags &Section,

284 ContiguousBlobAccumulator &CBA);

285 void writeSectionContent(Elf_Shdr &SHeader,

286 const ELFYAML::DynamicSection &Section,

287 ContiguousBlobAccumulator &CBA);

288 void writeSectionContent(Elf_Shdr &SHeader,

289 const ELFYAML::StackSizesSection &Section,

290 ContiguousBlobAccumulator &CBA);

291 void writeSectionContent(Elf_Shdr &SHeader,

292 const ELFYAML::BBAddrMapSection &Section,

293 ContiguousBlobAccumulator &CBA);

294 void writeSectionContent(Elf_Shdr &SHeader,

295 const ELFYAML::HashSection &Section,

296 ContiguousBlobAccumulator &CBA);

297 void writeSectionContent(Elf_Shdr &SHeader,

298 const ELFYAML::AddrsigSection &Section,

299 ContiguousBlobAccumulator &CBA);

300 void writeSectionContent(Elf_Shdr &SHeader,

301 const ELFYAML::NoteSection &Section,

302 ContiguousBlobAccumulator &CBA);

303 void writeSectionContent(Elf_Shdr &SHeader,

304 const ELFYAML::GnuHashSection &Section,

305 ContiguousBlobAccumulator &CBA);

306 void writeSectionContent(Elf_Shdr &SHeader,

307 const ELFYAML::LinkerOptionsSection &Section,

308 ContiguousBlobAccumulator &CBA);

309 void writeSectionContent(Elf_Shdr &SHeader,

310 const ELFYAML::DependentLibrariesSection &Section,

311 ContiguousBlobAccumulator &CBA);

312 void writeSectionContent(Elf_Shdr &SHeader,

313 const ELFYAML::CallGraphProfileSection &Section,

314 ContiguousBlobAccumulator &CBA);

315

316 void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);

317

319

320 void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);

321

322 DenseMap<StringRef, size_t> buildSectionHeaderReorderMap();

323

325 uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,

326 std::optionalllvm::yaml::Hex64 Offset);

327

328 uint64_t getSectionNameOffset(StringRef Name);

329

330public:

331 static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,

333};

334}

335

337 return A.size() * sizeof(T);

338}

339

343

344template static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }

345

346template

348 : Doc(D), ErrHandler(EH) {

349

350

351

352 if (Doc.Header.SectionHeaderStringTable) {

353 SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable;

354 if (*Doc.Header.SectionHeaderStringTable == ".strtab")

355 ShStrtabStrings = &DotStrtab;

356 else if (*Doc.Header.SectionHeaderStringTable == ".dynstr")

357 ShStrtabStrings = &DotDynstr;

358

359 }

360

361 std::vector<ELFYAML::Section *> Sections = Doc.getSections();

362

363 if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL)

364 Doc.Chunks.insert(

365 Doc.Chunks.begin(),

366 std::make_uniqueELFYAML::Section(

368

371 for (size_t I = 0; I < Doc.Chunks.size(); ++I) {

372 const std::unique_ptrELFYAML::Chunk &C = Doc.Chunks[I];

373

374

376 if (SecHdrTable)

377 reportError("multiple section header tables are not allowed");

378 SecHdrTable = S;

379 continue;

380 }

381

382

383

384

385 if (C->Name.empty()) {

387 "", "index " + Twine(I));

390 }

391

392 if (!DocSections.insert(C->Name).second)

393 reportError("repeated section/fill name: '" + C->Name +

394 "' at YAML section/fill number " + Twine(I));

395 }

396

398 if (Doc.DynamicSymbols) {

399 if (SectionHeaderStringTableName == ".dynsym")

400 reportError("cannot use '.dynsym' as the section header name table when "

401 "there are dynamic symbols");

402 ImplicitSections.insert(".dynsym");

403 ImplicitSections.insert(".dynstr");

404 }

405 if (Doc.Symbols) {

406 if (SectionHeaderStringTableName == ".symtab")

407 reportError("cannot use '.symtab' as the section header name table when "

408 "there are symbols");

409 ImplicitSections.insert(".symtab");

410 }

411 if (Doc.DWARF)

412 for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {

413 std::string SecName = ("." + DebugSecName).str();

414

415

416 if (SectionHeaderStringTableName == SecName)

417 reportError("cannot use '" + SecName +

418 "' as the section header name table when it is needed for "

419 "DWARF output");

420 ImplicitSections.insert(StringRef(SecName).copy(StringAlloc));

421 }

422

423 ImplicitSections.insert(".strtab");

424 if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false))

425 ImplicitSections.insert(SectionHeaderStringTableName);

426

427

428

430 if (DocSections.count(SecName))

431 continue;

432

433 std::unique_ptrELFYAML::Section Sec = std::make_uniqueELFYAML::Section(

435 Sec->Name = SecName;

436

437 if (SecName == SectionHeaderStringTableName)

439 else if (SecName == ".dynsym")

441 else if (SecName == ".symtab")

443 else

445

446

447

448

449

450

451 if (Doc.Chunks.back().get() == SecHdrTable)

452 Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec));

453 else

454 Doc.Chunks.push_back(std::move(Sec));

455 }

456

457

458

459 if (!SecHdrTable)

460 Doc.Chunks.push_back(

461 std::make_uniqueELFYAML::SectionHeaderTable(true));

462}

463

464template

465void ELFState::writeELFHeader(raw_ostream &OS) {

467

468 Elf_Ehdr Header;

469 zero(Header);

470 Header.e_ident[EI_MAG0] = 0x7f;

471 Header.e_ident[EI_MAG1] = 'E';

472 Header.e_ident[EI_MAG2] = 'L';

473 Header.e_ident[EI_MAG3] = 'F';

475 Header.e_ident[EI_DATA] = Doc.Header.Data;

477 Header.e_ident[EI_OSABI] = Doc.Header.OSABI;

478 Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion;

479 Header.e_type = Doc.Header.Type;

480

481 if (Doc.Header.Machine)

482 Header.e_machine = *Doc.Header.Machine;

483 else

484 Header.e_machine = EM_NONE;

485

487 Header.e_entry = Doc.Header.Entry;

488 if (Doc.Header.Flags)

489 Header.e_flags = *Doc.Header.Flags;

490 else

491 Header.e_flags = 0;

492

493 Header.e_ehsize = sizeof(Elf_Ehdr);

494

495 if (Doc.Header.EPhOff)

496 Header.e_phoff = *Doc.Header.EPhOff;

497 else if (!Doc.ProgramHeaders.empty())

498 Header.e_phoff = sizeof(Header);

499 else

500 Header.e_phoff = 0;

501

502 if (Doc.Header.EPhEntSize)

503 Header.e_phentsize = *Doc.Header.EPhEntSize;

504 else if (!Doc.ProgramHeaders.empty())

505 Header.e_phentsize = sizeof(Elf_Phdr);

506 else

507 Header.e_phentsize = 0;

508

509 if (Doc.Header.EPhNum)

510 Header.e_phnum = *Doc.Header.EPhNum;

511 else if (!Doc.ProgramHeaders.empty())

512 Header.e_phnum = Doc.ProgramHeaders.size();

513 else

514 Header.e_phnum = 0;

515

516 Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize

517 : sizeof(Elf_Shdr);

518

520 Doc.getSectionHeaderTable();

521

522 if (Doc.Header.EShOff)

523 Header.e_shoff = *Doc.Header.EShOff;

524 else if (SectionHeaders.Offset)

525 Header.e_shoff = *SectionHeaders.Offset;

526 else

527 Header.e_shoff = 0;

528

529 if (Doc.Header.EShNum)

530 Header.e_shnum = *Doc.Header.EShNum;

531 else

532 Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size());

533

534 if (Doc.Header.EShStrNdx)

535 Header.e_shstrndx = *Doc.Header.EShStrNdx;

536 else if (SectionHeaders.Offset &&

537 !ExcludedSectionHeaders.count(SectionHeaderStringTableName))

538 Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName);

539 else

540 Header.e_shstrndx = 0;

541

542 OS.write((const char *)&Header, sizeof(Header));

543}

544

545template

546void ELFState::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) {

548 for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) {

549 NameToIndex[Doc.Chunks[I]->Name] = I + 1;

550 }

551

552 for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) {

554 Elf_Phdr Phdr;

556 Phdr.p_type = YamlPhdr.Type;

557 Phdr.p_flags = YamlPhdr.Flags;

558 Phdr.p_vaddr = YamlPhdr.VAddr;

559 Phdr.p_paddr = YamlPhdr.PAddr;

560 PHeaders.push_back(Phdr);

561

563 continue;

564

565

568 reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec +

569 "' by the 'FirstSec' key of the program header with index " +

571 size_t Last = NameToIndex[*YamlPhdr.LastSec];

573 reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec +

574 "' by the 'LastSec' key of the program header with index " +

577 continue;

578

581 ": the section index of " + *YamlPhdr.FirstSec +

582 " is greater than the index of " + *YamlPhdr.LastSec);

583

585 YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get());

586 }

587}

588

589template

590unsigned ELFState::toSectionIndex(StringRef S, StringRef LocSec,

593

594 unsigned Index;

595 if (!SN2I.lookup(S, Index) && to\_integer(S, Index)) {

596 if (!LocSym.empty())

597 reportError("unknown section referenced: '" + S + "' by YAML symbol '" +

598 LocSym + "'");

599 else

600 reportError("unknown section referenced: '" + S + "' by YAML section '" +

601 LocSec + "'");

602 return 0;

603 }

604

606 Doc.getSectionHeaderTable();

610 return Index;

611

613 size_t FirstExcluded =

614 SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0;

615 if (Index > FirstExcluded) {

616 if (LocSym.empty())

617 reportError("unable to link '" + LocSec + "' to excluded section '" + S +

618 "'");

619 else

620 reportError("excluded section referenced: '" + S + "' by symbol '" +

621 LocSym + "'");

622 }

623 return Index;

624}

625

626template

628 bool IsDynamic) {

629 const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I;

630 unsigned Index;

631

632

634 reportError("unknown symbol referenced: '" + S + "' by YAML section '" +

635 LocSec + "'");

636 return 0;

637 }

638 return Index;

639}

640

641template

643 if (!From)

644 return;

648 To.sh_flags = *From->ShFlags;

650 To.sh_name = *From->ShName;

652 To.sh_offset = *From->ShOffset;

654 To.sh_size = *From->ShSize;

656 To.sh_type = *From->ShType;

657}

658

659template

660bool ELFState::initImplicitHeader(ContiguousBlobAccumulator &CBA,

661 Elf_Shdr &Header, StringRef SecName,

663

664 if (Header.sh_offset)

665 return false;

666

667 if (SecName == ".strtab")

668 initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec);

669 else if (SecName == ".dynstr")

670 initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec);

671 else if (SecName == SectionHeaderStringTableName)

672 initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec);

673 else if (SecName == ".symtab")

674 initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);

675 else if (SecName == ".dynsym")

676 initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);

677 else if (SecName.starts_with(".debug_")) {

678

679

681 return false;

682 initDWARFSectionHeader(Header, SecName, CBA, YAMLSec);

683 } else

684 return false;

685

686 LocationCounter += Header.sh_size;

687

688

690 return true;

691}

692

695

697 const Twine &Msg) {

698

699 std::string Ret = Name.empty() ? "" : Name.str() + ' ';

701}

702

705 return S;

706

707

709 if (SuffixPos == 0)

710 return "";

711

712 if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ')

713 return S;

714 return S.substr(0, SuffixPos - 1);

715}

716

717template

719

720

721 if (ExcludedSectionHeaders.count(Name))

722 return 0;

723 return ShStrtabStrings->getOffset(Name);

724}

725

727 const std::optionalyaml::BinaryRef &Content,

728 const std::optionalllvm::yaml::Hex64 &Size) {

729 size_t ContentSize = 0;

730 if (Content) {

731 CBA.writeAsBinary(*Content);

732 ContentSize = Content->binary_size();

733 }

734

736 return ContentSize;

737

738 CBA.writeZeros(*Size - ContentSize);

739 return *Size;

740}

741

749 return ".symtab";

753 return ".dynsym";

757 return ".dynstr";

759 return ".strtab";

760 default:

761 return "";

762 }

763}

764

765template

766void ELFState::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,

767 ContiguousBlobAccumulator &CBA) {

768

769

770 SHeaders.resize(Doc.getSections().size());

771

772 for (const std::unique_ptrELFYAML::Chunk &D : Doc.Chunks) {

774 S->Offset = alignToOffset(CBA, 1, S->Offset);

775 writeFill(*S, CBA);

776 LocationCounter += S->Size;

777 continue;

778 }

779

782 if (S->NoHeaders.value_or(false))

783 continue;

784

785 if (!S->Offset)

786 S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint),

787 std::nullopt);

788 else

789 S->Offset = alignToOffset(CBA, 1, S->Offset);

790

791 uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr);

792

793

794 CBA.writeZeros(Size);

795 LocationCounter += Size;

796 continue;

797 }

798

800 bool IsFirstUndefSection = Sec == Doc.getSections().front();

801 if (IsFirstUndefSection && Sec->IsImplicit)

802 continue;

803

804 Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)];

805 if (Sec->Link) {

806 SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name);

807 } else {

809 unsigned Link = 0;

810 if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) &&

811 SN2I.lookup(LinkSec, Link))

812 SHeader.sh_link = Link;

813 }

814

816 SHeader.sh_entsize = *Sec->EntSize;

817 else

820

821

822

823

824

825 if (initImplicitHeader(CBA, SHeader, Sec->Name,

827 continue;

828

829 assert(Sec && "It can't be null unless it is an implicit section. But all "

830 "implicit sections should already have been handled above.");

831

832 SHeader.sh_name =

834 SHeader.sh_type = Sec->Type;

836 SHeader.sh_flags = *Sec->Flags;

838

839

840

841 if (!IsFirstUndefSection || Sec->Offset)

842 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset);

843

844 assignSectionAddress(SHeader, Sec);

845

846 if (IsFirstUndefSection) {

848

849 if (RawSec->Size)

850 SHeader.sh_size = *RawSec->Size;

851 if (RawSec->Info)

852 SHeader.sh_info = *RawSec->Info;

853 }

854

855 LocationCounter += SHeader.sh_size;

856 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});

857 continue;

858 }

859

862

864 writeSectionContent(SHeader, *S, CBA);

866 writeSectionContent(SHeader, *S, CBA);

868 writeSectionContent(SHeader, *S, CBA);

870 writeSectionContent(SHeader, *S, CBA);

872 writeSectionContent(SHeader, *S, CBA);

874 writeSectionContent(SHeader, *S, CBA);

876 writeSectionContent(SHeader, *S, CBA);

878 writeSectionContent(SHeader, *S, CBA);

880 writeSectionContent(SHeader, *S, CBA);

882 writeSectionContent(SHeader, *S, CBA);

884 writeSectionContent(SHeader, *S, CBA);

886 writeSectionContent(SHeader, *S, CBA);

888 writeSectionContent(SHeader, *S, CBA);

890 writeSectionContent(SHeader, *S, CBA);

892 writeSectionContent(SHeader, *S, CBA);

894 writeSectionContent(SHeader, *S, CBA);

896 writeSectionContent(SHeader, *S, CBA);

898 writeSectionContent(SHeader, *S, CBA);

900 writeSectionContent(SHeader, *S, CBA);

902 writeSectionContent(SHeader, *S, CBA);

904 writeSectionContent(SHeader, *S, CBA);

905 } else {

907 }

908

909 LocationCounter += SHeader.sh_size;

910 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});

911 }

912}

913

914template

915void ELFState::overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders) {

916 for (std::pair<Elf_Shdr *, ELFYAML::Section> &HeaderAndSec :

917 SectionHeadersOverrideHelper)

919}

920

921template

922void ELFState::assignSectionAddress(Elf_Shdr &SHeader,

924 if (YAMLSec && YAMLSec->Address) {

925 SHeader.sh_addr = *YAMLSec->Address;

926 LocationCounter = *YAMLSec->Address;

927 return;

928 }

929

930

931

932

933 if (Doc.Header.Type.value == ELF::ET_REL ||

935 return;

936

937 LocationCounter =

938 alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);

939 SHeader.sh_addr = LocationCounter;

940}

941

943 for (size_t I = 0; I < Symbols.size(); ++I)

945 return I;

946 return Symbols.size();

947}

948

949template

950std::vector

953 std::vector<Elf_Sym> Ret;

954 Ret.resize(Symbols.size() + 1);

955

956 size_t I = 0;

958 Elf_Sym &Symbol = Ret[++I];

959

960

961

962

963 if (Sym.StName)

964 Symbol.st_name = *Sym.StName;

965 else if (!Sym.Name.empty())

967

968 Symbol.setBindingAndType(Sym.Binding, Sym.Type);

969 if (Sym.Section)

970 Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name);

971 else if (Sym.Index)

972 Symbol.st_shndx = *Sym.Index;

973

974 Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0));

975 Symbol.st_other = Sym.Other.value_or(0);

976 Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0));

977 }

978

979 return Ret;

980}

981

982template

983void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader,

984 SymtabType STType,

985 ContiguousBlobAccumulator &CBA,

987

988 bool IsStatic = STType == SymtabType::Static;

990 if (IsStatic && Doc.Symbols)

992 else if (!IsStatic && Doc.DynamicSymbols)

993 Symbols = *Doc.DynamicSymbols;

994

997 if (RawSec && (RawSec->Content || RawSec->Size)) {

998 bool HasSymbolsDescription =

999 (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);

1000 if (HasSymbolsDescription) {

1001 StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`");

1003 reportError("cannot specify both `Content` and " + Property +

1004 " for symbol table section '" + RawSec->Name + "'");

1005 if (RawSec->Size)

1006 reportError("cannot specify both `Size` and " + Property +

1007 " for symbol table section '" + RawSec->Name + "'");

1008 return;

1009 }

1010 }

1011

1012 SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym");

1013

1014 if (YAMLSec)

1015 SHeader.sh_type = YAMLSec->Type;

1016 else

1018

1019 if (YAMLSec && YAMLSec->Flags)

1020 SHeader.sh_flags = *YAMLSec->Flags;

1021 else if (!IsStatic)

1023

1024

1025

1026 SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info)

1029

1030 assignSectionAddress(SHeader, YAMLSec);

1031

1032 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,

1033 RawSec ? RawSec->Offset : std::nullopt);

1034

1035 if (RawSec && (RawSec->Content || RawSec->Size)) {

1038 return;

1039 }

1040

1041 std::vector<Elf_Sym> Syms =

1042 toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr);

1043 SHeader.sh_size = Syms.size() * sizeof(Elf_Sym);

1044 CBA.write((const char *)Syms.data(), SHeader.sh_size);

1045}

1046

1047template

1048void ELFState::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,

1050 ContiguousBlobAccumulator &CBA,

1055

1058

1059 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,

1060 YAMLSec ? YAMLSec->Offset : std::nullopt);

1061

1062 if (RawSec && (RawSec->Content || RawSec->Size)) {

1064 } else {

1067 SHeader.sh_size = STB.getSize();

1068 }

1069

1070 if (RawSec && RawSec->Info)

1071 SHeader.sh_info = *RawSec->Info;

1072

1073 if (YAMLSec && YAMLSec->Flags)

1074 SHeader.sh_flags = *YAMLSec->Flags;

1075 else if (Name == ".dynstr")

1077

1078 assignSectionAddress(SHeader, YAMLSec);

1079}

1080

1083 return Name.consume_front(".") && DebugSecNames.count(Name);

1084}

1085

1086template

1089 ContiguousBlobAccumulator &CBA) {

1090

1091

1092

1094 if (!OS)

1095 return 0;

1096

1097 uint64_t BeginOffset = CBA.tell();

1098

1100 if (Error Err = EmitFunc(*OS, DWARF))

1101 return std::move(Err);

1102

1103 return CBA.tell() - BeginOffset;

1104}

1105

1106template

1107void ELFState::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,

1108 ContiguousBlobAccumulator &CBA,

1113 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,

1114 YAMLSec ? YAMLSec->Offset : std::nullopt);

1115

1119 if (RawSec && (RawSec->Content || RawSec->Size))

1120 reportError("cannot specify section '" + Name +

1121 "' contents in the 'DWARF' entry and the 'Content' "

1122 "or 'Size' in the 'Sections' entry at the same time");

1123 else {

1126 SHeader.sh_size = *ShSizeOrErr;

1127 else

1129 }

1130 } else if (RawSec)

1132 else

1133 llvm_unreachable("debug sections can only be initialized via the 'DWARF' "

1134 "entry or a RawContentSection");

1135

1136 if (RawSec && RawSec->Info)

1137 SHeader.sh_info = *RawSec->Info;

1138

1139 if (YAMLSec && YAMLSec->Flags)

1140 SHeader.sh_flags = *YAMLSec->Flags;

1141 else if (Name == ".debug_str")

1143

1144 assignSectionAddress(SHeader, YAMLSec);

1145}

1146

1147template void ELFState::reportError(const Twine &Msg) {

1148 ErrHandler(Msg);

1149 HasError = true;

1150}

1151

1152template void ELFState::reportError(Error Err) {

1155 });

1156}

1157

1158template

1159std::vector

1162 std::vector Ret;

1166 1});

1167 continue;

1168 }

1169

1171 const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)];

1172 Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign});

1173 }

1174 return Ret;

1175}

1176

1177template

1178void ELFState::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,

1179 std::vector<Elf_Shdr> &SHeaders) {

1181 for (auto &YamlPhdr : Doc.ProgramHeaders) {

1182 Elf_Phdr &PHeader = PHeaders[PhdrIdx++];

1183 std::vector Fragments = getPhdrFragments(YamlPhdr, SHeaders);

1184 if (llvm::is\_sorted(Fragments, [](const Fragment &A, const Fragment &B) {

1185 return A.Offset < B.Offset;

1186 }))

1187 reportError("sections in the program header with index " +

1188 Twine(PhdrIdx) + " are not sorted by their file offset");

1189

1190 if (YamlPhdr.Offset) {

1191 if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset)

1192 reportError("'Offset' for segment with index " + Twine(PhdrIdx) +

1193 " must be less than or equal to the minimum file offset of "

1194 "all included sections (0x" +

1196 PHeader.p_offset = *YamlPhdr.Offset;

1197 } else if (!Fragments.empty()) {

1198 PHeader.p_offset = Fragments.front().Offset;

1199 }

1200

1201

1203 PHeader.p_filesz = *YamlPhdr.FileSize;

1204 } else if (!Fragments.empty()) {

1205 uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset;

1206

1207

1208

1210 FileSize += Fragments.back().Size;

1211 PHeader.p_filesz = FileSize;

1212 }

1213

1214

1215 uint64_t MemOffset = PHeader.p_offset;

1216 for (const Fragment &F : Fragments)

1217 MemOffset = std::max(MemOffset, F.Offset + F.Size);

1218

1220 : MemOffset - PHeader.p_offset;

1221

1222 if (YamlPhdr.Align) {

1223 PHeader.p_align = *YamlPhdr.Align;

1224 } else {

1225

1226

1227

1228 PHeader.p_align = 1;

1229 for (const Fragment &F : Fragments)

1230 PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign);

1231 }

1232 }

1233}

1234

1239 PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; });

1240 if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) {

1241 return (isaELFYAML::Fill(C) ||

1242 castELFYAML::Section(C)->Type != ELF::SHT_NOBITS);

1243 }))

1244 return true;

1245 }

1246 return false;

1247}

1248

1249template

1250void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1252 ContiguousBlobAccumulator &CBA) {

1253 if (!S.Size)

1254 return;

1255

1256 SHeader.sh_size = *S.Size;

1257

1258

1259

1260

1261 if (shouldAllocateFileSpace(Doc.ProgramHeaders, S))

1262 CBA.writeZeros(*S.Size);

1263}

1264

1265template

1266void ELFState::writeSectionContent(

1268 ContiguousBlobAccumulator &CBA) {

1269 if (Section.Info)

1270 SHeader.sh_info = *Section.Info;

1271}

1272

1278

1279template

1280void ELFState::writeSectionContent(

1282 ContiguousBlobAccumulator &CBA) {

1286 "Section type is not SHT_REL nor SHT_RELA");

1287

1288 if (Section.RelocatableSec.empty())

1289 SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name);

1290

1291 if (Section.Relocations)

1292 return;

1293

1296 typename ELFT::uint OffsetMask = 8, Offset = 0, Addend = 0;

1298 uint64_t CurrentOffset = CBA.getOffset();

1299 if (IsCrel)

1301 OffsetMask |= Rel.Offset;

1303 if (IsCrel)

1305 Shift);

1307 const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym");

1310 if (IsCrel) {

1311

1312

1313

1314 auto DeltaOffset =

1315 (static_cast<typename ELFT::uint>(Rel.Offset) - Offset) >> Shift;

1318 DeltaOffset * 8 + (SymIdx != CurSymIdx) + (Type != Rel.Type ? 2 : 0) +

1319 (Addend != static_cast<typename ELFT::uint>(Rel.Addend) ? 4 : 0);

1320 if (DeltaOffset < 0x10) {

1321 CBA.write(B);

1322 } else {

1323 CBA.write(B | 0x80);

1324 CBA.writeULEB128(DeltaOffset >> 4);

1325 }

1326

1327 if (B & 1) {

1328 CBA.writeSLEB128(

1329 std::make_signed_t(CurSymIdx - SymIdx));

1330 SymIdx = CurSymIdx;

1331 }

1332 if (B & 2) {

1333 CBA.writeSLEB128(static_cast<int32_t>(Rel.Type - Type));

1335 }

1336 if (B & 4) {

1337 CBA.writeSLEB128(

1338 std::make_signed_t(Rel.Addend - Addend));

1339 Addend = Rel.Addend;

1340 }

1341 } else if (IsRela) {

1342 Elf_Rela REntry;

1343 zero(REntry);

1344 REntry.r_offset = Rel.Offset;

1345 REntry.r_addend = Rel.Addend;

1346 REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc));

1347 CBA.write((const char *)&REntry, sizeof(REntry));

1348 } else {

1349 Elf_Rel REntry;

1350 zero(REntry);

1351 REntry.r_offset = Rel.Offset;

1352 REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc));

1353 CBA.write((const char *)&REntry, sizeof(REntry));

1354 }

1355 }

1356

1357 SHeader.sh_size = CBA.getOffset() - CurrentOffset;

1358}

1359

1360template

1361void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1363 ContiguousBlobAccumulator &CBA) {

1365 return;

1366

1367 for (llvm::yaml::Hex64 E : *Section.Entries) {

1368 if (!ELFT::Is64Bits && E > UINT32_MAX)

1369 reportError(Section.Name + ": the value is too large for 32-bits: 0x" +

1371 CBA.write<uintX_t>(E, ELFT::Endianness);

1372 }

1373

1374 SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();

1375}

1376

1377template

1378void ELFState::writeSectionContent(

1380 ContiguousBlobAccumulator &CBA) {

1383 return;

1384 }

1385

1387 return;

1388

1390 CBA.write<uint32_t>(E, ELFT::Endianness);

1391 SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize;

1392}

1393

1394template

1395void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1397 ContiguousBlobAccumulator &CBA) {

1399 "Section type is not SHT_GROUP");

1400

1402 SHeader.sh_info =

1403 toSymbolIndex(*Section.Signature, Section.Name, false);

1404

1406 return;

1407

1409 unsigned int SectionIndex = 0;

1410 if (Member.sectionNameOrType == "GRP_COMDAT")

1412 else

1413 SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name);

1414 CBA.write<uint32_t>(SectionIndex, ELFT::Endianness);

1415 }

1416 SHeader.sh_size = SHeader.sh_entsize * Section.Members->size();

1417}

1418

1419template

1420void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1422 ContiguousBlobAccumulator &CBA) {

1424 return;

1425

1427 CBA.write<uint16_t>(Version, ELFT::Endianness);

1428 SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize;

1429}

1430

1431template

1432void ELFState::writeSectionContent(

1434 ContiguousBlobAccumulator &CBA) {

1436 return;

1437

1439 CBA.write<uintX_t>(E.Address, ELFT::Endianness);

1440 SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size);

1441 }

1442}

1443

1444template

1445void ELFState::writeSectionContent(

1447 ContiguousBlobAccumulator &CBA) {

1449 if (Section.PGOAnalyses)

1451 << "PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when "

1452 "Entries does not exist";

1453 return;

1454 }

1455

1456 const std::vectorELFYAML::PGOAnalysisMapEntry *PGOAnalyses = nullptr;

1457 if (Section.PGOAnalyses) {

1458 if (Section.Entries->size() != Section.PGOAnalyses->size())

1459 WithColor::warning() << "PGOAnalyses must be the same length as Entries "

1460 "in SHT_LLVM_BB_ADDR_MAP";

1461 else

1462 PGOAnalyses = &Section.PGOAnalyses.value();

1463 }

1464

1466

1468 if (E.Version > 5)

1469 WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "

1470 << static_cast<int>(E.Version)

1471 << "; encoding using the most recent version";

1472 CBA.write(E.Version);

1473 SHeader.sh_size += 1;

1474 if (E.Version < 5) {

1475 CBA.write(static_cast<uint8_t>(E.Feature));

1476 SHeader.sh_size += 1;

1477 } else {

1478 CBA.write<uint16_t>(E.Feature, ELFT::Endianness);

1479 SHeader.sh_size += 2;

1480 }

1481 }

1483 bool MultiBBRangeFeatureEnabled = false;

1484 if (!FeatureOrErr)

1486 else

1487 MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;

1488 bool MultiBBRange =

1489 MultiBBRangeFeatureEnabled ||

1490 (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||

1491 (E.BBRanges && E.BBRanges->size() != 1);

1492 if (MultiBBRange && !MultiBBRangeFeatureEnabled)

1494 << ") does not support multiple BB ranges.";

1495 if (MultiBBRange) {

1496

1497

1499 E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);

1500 SHeader.sh_size += CBA.writeULEB128(NumBBRanges);

1501 }

1502 if (E.BBRanges)

1503 continue;

1504 uint64_t TotalNumBlocks = 0;

1505 bool EmitCallsiteEndOffsets =

1506 FeatureOrErr->CallsiteEndOffsets || E.hasAnyCallsiteEndOffsets();

1508

1509 CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);

1510

1511

1512

1515 SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);

1516

1517 if (!BBR.BBEntries || FeatureOrErr->OmitBBEntries)

1518 continue;

1520 ++TotalNumBlocks;

1522 SHeader.sh_size += CBA.writeULEB128(BBE.ID);

1523 SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);

1524 if (EmitCallsiteEndOffsets) {

1525 size_t NumCallsiteEndOffsets =

1527 SHeader.sh_size += CBA.writeULEB128(NumCallsiteEndOffsets);

1530 SHeader.sh_size += CBA.writeULEB128(Offset);

1531 }

1532 }

1533 SHeader.sh_size += CBA.writeULEB128(BBE.Size);

1534 SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);

1535 if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {

1537 BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);

1538 CBA.write<uint64_t>(Hash, ELFT::Endianness);

1539 SHeader.sh_size += 8;

1540 }

1541 }

1542 }

1543 if (!PGOAnalyses)

1544 continue;

1546

1548 SHeader.sh_size += CBA.writeULEB128(*PGOEntry.FuncEntryCount);

1549

1551 continue;

1552

1553 const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();

1554 if (TotalNumBlocks != PGOBBEntries.size()) {

1556 "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n"

1557 << "Mismatch on function with address: "

1558 << E.getFunctionAddress();

1559 continue;

1560 }

1561

1562 for (const auto &PGOBBE : PGOBBEntries) {

1563 if (PGOBBE.BBFreq)

1564 SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);

1565 if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())

1566 SHeader.sh_size += CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));

1567 if (PGOBBE.Successors) {

1568 SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());

1569 for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {

1570 SHeader.sh_size += CBA.writeULEB128(ID);

1571 SHeader.sh_size += CBA.writeULEB128(BrProb);

1572 if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())

1573 SHeader.sh_size += CBA.writeULEB128(PostLinkBrFreq.value_or(0));

1574 }

1575 }

1576 }

1577 }

1578}

1579

1580template

1581void ELFState::writeSectionContent(

1583 ContiguousBlobAccumulator &CBA) {

1585 return;

1586

1588 CBA.write(LO.Key.data(), LO.Key.size());

1589 CBA.write('\0');

1590 CBA.write(LO.Value.data(), LO.Value.size());

1591 CBA.write('\0');

1592 SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);

1593 }

1594}

1595

1596template

1597void ELFState::writeSectionContent(

1599 ContiguousBlobAccumulator &CBA) {

1601 return;

1602

1604 CBA.write(Lib.data(), Lib.size());

1605 CBA.write('\0');

1606 SHeader.sh_size += Lib.size() + 1;

1607 }

1608}

1609

1610template

1612ELFState::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,

1613 std::optionalllvm::yaml::Hex64 Offset) {

1614 uint64_t CurrentOffset = CBA.getOffset();

1616

1621 return CurrentOffset;

1622 }

1623

1624

1625 AlignedOffset = *Offset;

1626 } else {

1628 }

1629

1630 CBA.writeZeros(AlignedOffset - CurrentOffset);

1631 return AlignedOffset;

1632}

1633

1634template

1635void ELFState::writeSectionContent(

1637 ContiguousBlobAccumulator &CBA) {

1639 return;

1640

1642 CBA.write<uint64_t>(E.Weight, ELFT::Endianness);

1644 }

1645}

1646

1647template

1648void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1650 ContiguousBlobAccumulator &CBA) {

1652 return;

1653

1655 Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())),

1656 ELFT::Endianness);

1658 Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())),

1659 ELFT::Endianness);

1660

1662 CBA.write<uint32_t>(Val, ELFT::Endianness);

1664 CBA.write<uint32_t>(Val, ELFT::Endianness);

1665

1666 SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4;

1667}

1668

1669template

1670void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1672 ContiguousBlobAccumulator &CBA) {

1673

1675 SHeader.sh_info = *Section.Info;

1676 else if (Section.Entries)

1677 SHeader.sh_info = Section.Entries->size();

1678

1680 return;

1681

1683 for (size_t I = 0; I < Section.Entries->size(); ++I) {

1685

1686 Elf_Verdef VerDef;

1687 VerDef.vd_version = E.Version.value_or(1);

1688 VerDef.vd_flags = E.Flags.value_or(0);

1689 VerDef.vd_ndx = E.VersionNdx.value_or(0);

1690 VerDef.vd_hash = E.Hash.value_or(0);

1691 VerDef.vd_aux = E.VDAux.value_or(sizeof(Elf_Verdef));

1692 VerDef.vd_cnt = E.VerNames.size();

1693 if (I == Section.Entries->size() - 1)

1694 VerDef.vd_next = 0;

1695 else

1696 VerDef.vd_next =

1697 sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);

1698 CBA.write((const char *)&VerDef, sizeof(Elf_Verdef));

1699

1700 for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {

1701 Elf_Verdaux VerdAux;

1702 VerdAux.vda_name = DotDynstr.getOffset(E.VerNames[J]);

1703 if (J == E.VerNames.size() - 1)

1704 VerdAux.vda_next = 0;

1705 else

1706 VerdAux.vda_next = sizeof(Elf_Verdaux);

1707 CBA.write((const char *)&VerdAux, sizeof(Elf_Verdaux));

1708 }

1709 }

1710

1711 SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) +

1712 AuxCnt * sizeof(Elf_Verdaux);

1713}

1714

1715template

1716void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1718 ContiguousBlobAccumulator &CBA) {

1720 SHeader.sh_info = *Section.Info;

1721 else if (Section.VerneedV)

1722 SHeader.sh_info = Section.VerneedV->size();

1723

1725 return;

1726

1728 for (size_t I = 0; I < Section.VerneedV->size(); ++I) {

1730

1731 Elf_Verneed VerNeed;

1732 VerNeed.vn_version = VE.Version;

1733 VerNeed.vn_file = DotDynstr.getOffset(VE.File);

1734 if (I == Section.VerneedV->size() - 1)

1735 VerNeed.vn_next = 0;

1736 else

1737 VerNeed.vn_next =

1738 sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux);

1739 VerNeed.vn_cnt = VE.AuxV.size();

1740 VerNeed.vn_aux = sizeof(Elf_Verneed);

1741 CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed));

1742

1743 for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) {

1745

1746 Elf_Vernaux VernAux;

1747 VernAux.vna_hash = VAuxE.Hash;

1748 VernAux.vna_flags = VAuxE.Flags;

1749 VernAux.vna_other = VAuxE.Other;

1750 VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name);

1751 if (J == VE.AuxV.size() - 1)

1752 VernAux.vna_next = 0;

1753 else

1754 VernAux.vna_next = sizeof(Elf_Vernaux);

1755 CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux));

1756 }

1757 }

1758

1759 SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) +

1760 AuxCnt * sizeof(Elf_Vernaux);

1761}

1762

1763template

1764void ELFState::writeSectionContent(

1766 ContiguousBlobAccumulator &CBA) {

1768 return;

1769

1771 CBA.write<uint32_t>(E.Offset, ELFT::Endianness);

1772 CBA.write<uint32_t>(E.Value, ELFT::Endianness);

1773 }

1774 SHeader.sh_size = Section.Entries->size() * 8;

1775}

1776

1777template

1778void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1780 ContiguousBlobAccumulator &CBA) {

1782 "Section type is not SHT_MIPS_ABIFLAGS");

1783

1785 zero(Flags);

1786 SHeader.sh_size = SHeader.sh_entsize;

1787

1788 Flags.version = Section.Version;

1789 Flags.isa_level = Section.ISALevel;

1790 Flags.isa_rev = Section.ISARevision;

1791 Flags.gpr_size = Section.GPRSize;

1792 Flags.cpr1_size = Section.CPR1Size;

1793 Flags.cpr2_size = Section.CPR2Size;

1794 Flags.fp_abi = Section.FpABI;

1795 Flags.isa_ext = Section.ISAExtension;

1796 Flags.ases = Section.ASEs;

1797 Flags.flags1 = Section.Flags1;

1798 Flags.flags2 = Section.Flags2;

1799 CBA.write((const char *)&Flags, sizeof(Flags));

1800}

1801

1802template

1803void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1805 ContiguousBlobAccumulator &CBA) {

1807 "Section type is not SHT_DYNAMIC");

1808

1810 return;

1811

1813 CBA.write<uintX_t>(DE.Tag, ELFT::Endianness);

1814 CBA.write<uintX_t>(DE.Val, ELFT::Endianness);

1815 }

1816 SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();

1817}

1818

1819template

1820void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1822 ContiguousBlobAccumulator &CBA) {

1824 return;

1825

1827 SHeader.sh_size +=

1828 CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, false));

1829}

1830

1831template

1832void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1834 ContiguousBlobAccumulator &CBA) {

1836 return;

1837

1839 switch (Section.AddressAlign) {

1840 case 0:

1841 case 4:

1843 break;

1844 case 8:

1846 break;

1847 default:

1848 reportError(Section.Name + ": invalid alignment for a note section: 0x" +

1850 return;

1851 }

1852

1853 if (CBA.getOffset() != alignTo(CBA.getOffset(), Align)) {

1854 reportError(Section.Name + ": invalid offset of a note section: 0x" +

1855 Twine::utohexstr(CBA.getOffset()) + ", should be aligned to " +

1857 return;

1858 }

1859

1862

1863 if (NE.Name.empty())

1864 CBA.write<uint32_t>(0, ELFT::Endianness);

1865 else

1866 CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::Endianness);

1867

1868

1869 if (NE.Desc.binary_size() == 0)

1870 CBA.write<uint32_t>(0, ELFT::Endianness);

1871 else

1872 CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::Endianness);

1873

1874

1875 CBA.write<uint32_t>(NE.Type, ELFT::Endianness);

1876

1877

1878 if (NE.Name.empty()) {

1879 CBA.write(NE.Name.data(), NE.Name.size());

1880 CBA.write('\0');

1881 }

1882

1883

1884 if (NE.Desc.binary_size() != 0) {

1885 CBA.padToAlignment(Align);

1886 CBA.writeAsBinary(NE.Desc);

1887 }

1888

1889 CBA.padToAlignment(Align);

1890 }

1891

1892 SHeader.sh_size = CBA.tell() - Offset;

1893}

1894

1895template

1896void ELFState::writeSectionContent(Elf_Shdr &SHeader,

1898 ContiguousBlobAccumulator &CBA) {

1899 if (Section.HashBuckets)

1900 return;

1901

1903 return;

1904

1905

1906

1907

1908

1909 if (Section.Header->NBuckets)

1910 CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::Endianness);

1911 else

1912 CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::Endianness);

1913

1914

1915

1916 CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::Endianness);

1917

1918

1919

1920 if (Section.Header->MaskWords)

1921 CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::Endianness);

1922 else

1923 CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::Endianness);

1924

1925

1926 CBA.write<uint32_t>(Section.Header->Shift2, ELFT::Endianness);

1927

1928

1929 for (llvm::yaml::Hex64 Val : *Section.BloomFilter)

1930 CBA.write<uintX_t>(Val, ELFT::Endianness);

1931

1932

1933 for (llvm::yaml::Hex32 Val : *Section.HashBuckets)

1934 CBA.write<uint32_t>(Val, ELFT::Endianness);

1935

1936

1937 for (llvm::yaml::Hex32 Val : *Section.HashValues)

1938 CBA.write<uint32_t>(Val, ELFT::Endianness);

1939

1940 SHeader.sh_size = 16 +

1941 Section.BloomFilter->size() * sizeof(typename ELFT::uint) +

1942 Section.HashBuckets->size() * 4 +

1943 Section.HashValues->size() * 4;

1944}

1945

1946template

1947void ELFState::writeFill(ELFYAML::Fill &Fill,

1948 ContiguousBlobAccumulator &CBA) {

1949 size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0;

1950 if (!PatternSize) {

1951 CBA.writeZeros(Fill.Size);

1952 return;

1953 }

1954

1955

1957 for (; Written + PatternSize <= Fill.Size; Written += PatternSize)

1958 CBA.writeAsBinary(*Fill.Pattern);

1959 CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written);

1960}

1961

1962template

1965 Doc.getSectionHeaderTable();

1969

1971 size_t SecNdx = 0;

1973

1975 if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second)

1976 reportError("repeated section name: '" + Hdr.Name +

1977 "' in the section header description");

1978 Seen.insert(Hdr.Name);

1979 };

1980

1981 if (SectionHeaders.Sections)

1983 AddSection(Hdr);

1984

1985 if (SectionHeaders.Excluded)

1987 AddSection(Hdr);

1988

1990

1991 if (S == Doc.getSections().front())

1992 continue;

1995 "' should be present in the 'Sections' or 'Excluded' lists");

1997 }

1998

1999 for (const auto &It : Seen)

2000 reportError("section header contains undefined section '" + It.getKey() +

2001 "'");

2002 return Ret;

2003}

2004

2005template void ELFState::buildSectionIndex() {

2006

2007

2009

2010 if (HasError)

2011 return;

2012

2013

2014 std::vector<ELFYAML::Section *> Sections = Doc.getSections();

2016 Doc.getSectionHeaderTable();

2017 if (SectionHeaders.Excluded)

2019 if (!ExcludedSectionHeaders.insert(Hdr.Name).second)

2021

2022 if (SectionHeaders.NoHeaders.value_or(false))

2024 if (!ExcludedSectionHeaders.insert(S->Name).second)

2026

2027 size_t SecNdx = -1;

2029 ++SecNdx;

2030

2031 size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name);

2032 if (!SN2I.addName(S->Name, Index))

2034

2035 if (!ExcludedSectionHeaders.count(S->Name))

2037 }

2038}

2039

2040template void ELFState::buildSymbolIndexes() {

2042 for (size_t I = 0, S = V.size(); I < S; ++I) {

2045 reportError("repeated symbol name: '" + Sym.Name + "'");

2046 }

2047 };

2048

2049 if (Doc.Symbols)

2050 Build(*Doc.Symbols, SymN2I);

2051 if (Doc.DynamicSymbols)

2052 Build(*Doc.DynamicSymbols, DynSymN2I);

2053}

2054

2055template void ELFState::finalizeStrings() {

2056

2057 if (Doc.Symbols)

2060 DotStrtab.finalize();

2061

2062

2063 if (Doc.DynamicSymbols)

2066

2067

2068

2069 for (const ELFYAML::Chunk *Sec : Doc.getSections()) {

2071 if (VerNeed->VerneedV) {

2073 DotDynstr.add(VE.File);

2075 DotDynstr.add(Aux.Name);

2076 }

2077 }

2079 if (VerDef->Entries)

2082 DotDynstr.add(Name);

2083 }

2084 }

2085

2086 DotDynstr.finalize();

2087

2088

2089

2090 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)

2091 ShStrtabStrings->finalize();

2092}

2093

2094template

2097 ELFState State(Doc, EH);

2098 if (State.HasError)

2099 return false;

2100

2101

2102

2103 State.buildSectionIndex();

2104 State.buildSymbolIndexes();

2105

2106

2107

2108

2109 State.finalizeStrings();

2110

2111 if (State.HasError)

2112 return false;

2113

2114 std::vector<Elf_Phdr> PHeaders;

2115 State.initProgramHeaders(PHeaders);

2116

2117

2118

2119 const size_t SectionContentBeginOffset =

2120 sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();

2121

2122

2123

2124

2125 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);

2126

2127 std::vector<Elf_Shdr> SHeaders;

2128 State.initSectionHeaders(SHeaders, CBA);

2129

2130

2131 State.setProgramHeaderLayout(PHeaders, SHeaders);

2132

2133

2134

2135

2136 State.overrideSectionHeaders(SHeaders);

2137

2138 bool ReachedLimit = CBA.getOffset() > MaxSize;

2139 if (Error E = CBA.takeLimitError()) {

2140

2142 ReachedLimit = true;

2143 }

2144

2145 if (ReachedLimit)

2146 State.reportError(

2147 "the desired output size is greater than permitted. Use the "

2148 "--max-size option to change the limit");

2149

2150 if (State.HasError)

2151 return false;

2152

2153 State.writeELFHeader(OS);

2155

2157 if (!SHT.NoHeaders.value_or(false))

2158 CBA.updateDataAt(*SHT.Offset, SHeaders.data(),

2159 SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr));

2160

2161 CBA.writeBlobToStream(OS);

2162 return true;

2163}

2164

2165namespace llvm {

2166namespace yaml {

2167

2172 if (Is64Bit) {

2173 if (IsLE)

2174 return ELFStateobject::ELF64LE::writeELF(Out, Doc, EH, MaxSize);

2175 return ELFStateobject::ELF64BE::writeELF(Out, Doc, EH, MaxSize);

2176 }

2177 if (IsLE)

2178 return ELFStateobject::ELF32LE::writeELF(Out, Doc, EH, MaxSize);

2179 return ELFStateobject::ELF32BE::writeELF(Out, Doc, EH, MaxSize);

2180}

2181

2182}

2183}

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

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

static Error reportError(StringRef Message)

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

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

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

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

Common declarations for yaml2obj.

This file declares classes for handling the YAML representation of DWARF Debug Info.

DXIL Resource Implicit Binding

This file defines the DenseMap class.

static StringRef getDefaultLinkSec(unsigned SecType)

Definition ELFEmitter.cpp:742

constexpr char SuffixEnd

Definition ELFEmitter.cpp:694

static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To)

Definition ELFEmitter.cpp:642

static void writeArrayData(raw_ostream &OS, ArrayRef< T > A)

Definition ELFEmitter.cpp:340

static bool isMips64EL(const ELFYAML::Object &Obj)

Definition ELFEmitter.cpp:1273

static size_t arrayDataSize(ArrayRef< T > A)

Definition ELFEmitter.cpp:336

constexpr char SuffixStart

Definition ELFEmitter.cpp:693

static void zero(T &Obj)

Definition ELFEmitter.cpp:344

static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name)

Definition ELFEmitter.cpp:1081

static uint64_t writeContent(ContiguousBlobAccumulator &CBA, const std::optional< yaml::BinaryRef > &Content, const std::optional< llvm::yaml::Hex64 > &Size)

Definition ELFEmitter.cpp:726

Expected< uint64_t > emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, const DWARFYAML::Data &DWARF, ContiguousBlobAccumulator &CBA)

Definition ELFEmitter.cpp:1087

static size_t findFirstNonGlobal(ArrayRef< ELFYAML::Symbol > Symbols)

Definition ELFEmitter.cpp:942

#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

This file declares classes for handling the YAML representation of ELF.

static cl::opt< unsigned > SizeLimit("eif-limit", cl::init(6), cl::Hidden, cl::desc("Size limit in Hexagon early if-conversion"))

static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)

A Lookup helper functions.

This file implements a set that has insertion order iteration characteristics.

StringSet - A set-like wrapper for the StringMap.

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

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

Base class for error info classes.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

A vector that has set insertion semantics.

size_type count(const_arg_type key) const

Count the number of elements of a given key in the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

A SetVector that performs no allocations if smaller than a certain size.

size_type count(StringRef Key) const

count - Return 1 if the element is in the map, 0 otherwise.

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

static constexpr size_t npos

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

char back() const

back - Get the last character in the string.

size_t rfind(char C, size_t From=npos) const

Search for the last character C in the string.

StringRef copy(Allocator &A) const

StringSet - A wrapper for StringMap that provides set-like functionality.

std::pair< typename Base::iterator, bool > insert(StringRef key)

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 void write(raw_ostream &OS) const

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

static Twine utohexstr(uint64_t Val)

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

static LLVM_ABI raw_ostream & warning()

Convenience method for printing "warning: " to stderr.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & write(unsigned char C)

#define llvm_unreachable(msg)

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

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

LLVM_ABI std::function< Error(raw_ostream &, const Data &)> getDWARFEmitterByName(StringRef SecName)

std::string appendUniqueSuffix(StringRef Name, const Twine &Msg)

Definition ELFEmitter.cpp:696

unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType, StringRef SecName)

StringRef dropUniqueSuffix(StringRef S)

Definition ELFEmitter.cpp:703

bool shouldAllocateFileSpace(ArrayRef< ProgramHeader > Phdrs, const NoBitsSection &S)

Definition ELFEmitter.cpp:1235

@ SHT_LLVM_CALL_GRAPH_PROFILE

constexpr unsigned CREL_HDR_ADDEND

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

Write a value to memory with a particular endianness.

LLVM_ABI bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, uint64_t MaxSize)

Definition ELFEmitter.cpp:2168

llvm::function_ref< void(const Twine &Msg)> ErrorHandler

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.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

decltype(auto) dyn_cast(const From &Val)

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

void handleAllErrors(Error E, HandlerTs &&... Handlers)

Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

int countr_zero(T Val)

Count number of 0's from the least significant bit to the most stopping at the first 1.

auto dyn_cast_or_null(const Y &Val)

static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

bool is_sorted(R &&Range, Compare C)

Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

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.

@ Dynamic

Denotes mode unknown at compile time.

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

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)

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

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

decltype(auto) cast(const From &Val)

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

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if 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.

bool to_integer(StringRef S, N &Num, unsigned Base=0)

Convert the string S to an integer of the specified type using the radix Base. If Base is 0,...

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

void consumeError(Error Err)

Consume a Error without doing anything.

This struct is a compact representation of a valid (non-zero power of two) alignment.

LLVM_ABI SetVector< StringRef > getNonEmptySectionNames() const

std::optional< llvm::yaml::Hex64 > Hash

llvm::yaml::Hex64 Metadata

std::optional< std::vector< llvm::yaml::Hex64 > > CallsiteEndOffsets

llvm::yaml::Hex64 AddressOffset

std::optional< uint64_t > NumBlocks

llvm::yaml::Hex64 BaseAddress

std::optional< std::vector< BBEntry > > BBEntries

std::optional< llvm::yaml::Hex64 > Offset

std::optional< yaml::BinaryRef > Pattern

const SectionHeaderTable & getSectionHeaderTable() const

std::vector< ProgramHeader > ProgramHeaders

std::optional< std::vector< PGOBBEntry > > PGOBBEntries

std::optional< uint64_t > FuncEntryCount

std::optional< llvm::yaml::Hex64 > Info

std::optional< StringRef > Symbol

std::optional< llvm::yaml::Hex64 > Address

std::optional< StringRef > Link

std::optional< llvm::yaml::Hex64 > Size

std::optional< llvm::yaml::Hex64 > ShAddrAlign

llvm::yaml::Hex64 AddressAlign

std::optional< ELF_SHF > Flags

std::optional< ELF_SHT > ShType

std::optional< llvm::yaml::Hex64 > ShOffset

std::optional< llvm::yaml::Hex64 > ShFlags

std::optional< llvm::yaml::Hex64 > ShName

std::optional< yaml::BinaryRef > Content

std::optional< llvm::yaml::Hex64 > EntSize

std::optional< llvm::yaml::Hex64 > ShSize

std::optional< std::vector< uint32_t > > Entries

static Expected< Features > decode(uint16_t Val)

Common declarations for yaml2obj.