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;
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()) {
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) && (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 ((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 (.RelocatableSec.empty())
1289 SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name);
1290
1291 if (.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 (.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 (.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 (.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.