xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file declares classes for handling the YAML representation
11 /// of ELF.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_OBJECTYAML_ELFYAML_H
16 #define LLVM_OBJECTYAML_ELFYAML_H
17 
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Object/ELFTypes.h"
21 #include "llvm/ObjectYAML/DWARFYAML.h"
22 #include "llvm/ObjectYAML/YAML.h"
23 #include "llvm/Support/YAMLTraits.h"
24 #include <cstdint>
25 #include <memory>
26 #include <optional>
27 #include <vector>
28 
29 namespace llvm {
30 namespace ELFYAML {
31 
32 StringRef dropUniqueSuffix(StringRef S);
33 std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
34 
35 // These types are invariant across 32/64-bit ELF, so for simplicity just
36 // directly give them their exact sizes. We don't need to worry about
37 // endianness because these are just the types in the YAMLIO structures,
38 // and are appropriately converted to the necessary endianness when
39 // reading/generating binary object files.
40 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
41 // the common prefix of the respective constants. E.g. ELF_EM corresponds
42 // to the `e_machine` constants, like `EM_X86_64`.
43 // In the future, these would probably be better suited by C++11 enum
44 // class's with appropriate fixed underlying type.
LLVM_YAML_STRONG_TYPEDEF(uint16_t,ELF_ET)45 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
46 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
47 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
48 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
49 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
50 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
51 // Just use 64, since it can hold 32-bit values too.
52 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
53 // Just use 64, since it can hold 32-bit values too.
54 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
55 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
56 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
57 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
59 // Just use 64, since it can hold 32-bit values too.
60 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
61 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
62 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
63 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)
65 
66 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
67 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
68 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
69 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
70 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
71 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
72 
73 LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
74 LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
75 
76 template <class ELFT>
77 unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
78                              StringRef SecName) {
79   if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
80     return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
81 
82   switch (SecType) {
83   case ELF::SHT_SYMTAB:
84   case ELF::SHT_DYNSYM:
85     return sizeof(typename ELFT::Sym);
86   case ELF::SHT_GROUP:
87     return sizeof(typename ELFT::Word);
88   case ELF::SHT_REL:
89     return sizeof(typename ELFT::Rel);
90   case ELF::SHT_RELA:
91     return sizeof(typename ELFT::Rela);
92   case ELF::SHT_RELR:
93     return sizeof(typename ELFT::Relr);
94   case ELF::SHT_DYNAMIC:
95     return sizeof(typename ELFT::Dyn);
96   case ELF::SHT_HASH:
97     return sizeof(typename ELFT::Word);
98   case ELF::SHT_SYMTAB_SHNDX:
99     return sizeof(typename ELFT::Word);
100   case ELF::SHT_GNU_versym:
101     return sizeof(typename ELFT::Half);
102   case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
103     return sizeof(object::Elf_CGProfile_Impl<ELFT>);
104   default:
105     if (SecName == ".debug_str")
106       return 1;
107     return 0;
108   }
109 }
110 
111 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
112 // since 64-bit can hold 32-bit values too.
113 struct FileHeader {
114   ELF_ELFCLASS Class;
115   ELF_ELFDATA Data;
116   ELF_ELFOSABI OSABI;
117   llvm::yaml::Hex8 ABIVersion;
118   ELF_ET Type;
119   std::optional<ELF_EM> Machine;
120   ELF_EF Flags;
121   llvm::yaml::Hex64 Entry;
122   std::optional<StringRef> SectionHeaderStringTable;
123 
124   std::optional<llvm::yaml::Hex64> EPhOff;
125   std::optional<llvm::yaml::Hex16> EPhEntSize;
126   std::optional<llvm::yaml::Hex16> EPhNum;
127   std::optional<llvm::yaml::Hex16> EShEntSize;
128   std::optional<llvm::yaml::Hex64> EShOff;
129   std::optional<llvm::yaml::Hex16> EShNum;
130   std::optional<llvm::yaml::Hex16> EShStrNdx;
131 };
132 
133 struct SectionHeader {
134   StringRef Name;
135 };
136 
137 struct Symbol {
138   StringRef Name;
139   ELF_STT Type;
140   std::optional<StringRef> Section;
141   std::optional<ELF_SHN> Index;
142   ELF_STB Binding;
143   std::optional<llvm::yaml::Hex64> Value;
144   std::optional<llvm::yaml::Hex64> Size;
145   std::optional<uint8_t> Other;
146 
147   std::optional<uint32_t> StName;
148 };
149 
150 struct SectionOrType {
151   StringRef sectionNameOrType;
152 };
153 
154 struct DynamicEntry {
155   ELF_DYNTAG Tag;
156   llvm::yaml::Hex64 Val;
157 };
158 
159 struct BBAddrMapEntry {
160   struct BBEntry {
161     uint32_t ID;
162     llvm::yaml::Hex64 AddressOffset;
163     llvm::yaml::Hex64 Size;
164     llvm::yaml::Hex64 Metadata;
165     std::optional<std::vector<llvm::yaml::Hex64>> CallsiteOffsets;
166   };
167   uint8_t Version;
168   llvm::yaml::Hex8 Feature;
169 
170   struct BBRangeEntry {
171     llvm::yaml::Hex64 BaseAddress;
172     std::optional<uint64_t> NumBlocks;
173     std::optional<std::vector<BBEntry>> BBEntries;
174   };
175 
176   std::optional<uint64_t> NumBBRanges;
177   std::optional<std::vector<BBRangeEntry>> BBRanges;
178 
getFunctionAddressBBAddrMapEntry179   llvm::yaml::Hex64 getFunctionAddress() const {
180     if (!BBRanges || BBRanges->empty())
181       return 0;
182     return BBRanges->front().BaseAddress;
183   }
184 
185   // Returns if any BB entries have non-empty callsite offsets.
hasAnyCallsiteOffsetsBBAddrMapEntry186   bool hasAnyCallsiteOffsets() const {
187     if (!BBRanges)
188       return false;
189     for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *BBRanges) {
190       if (!BBR.BBEntries)
191         continue;
192       for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries)
193         if (BBE.CallsiteOffsets && !BBE.CallsiteOffsets->empty())
194           return true;
195     }
196     return false;
197   }
198 };
199 
200 struct PGOAnalysisMapEntry {
201   struct PGOBBEntry {
202     struct SuccessorEntry {
203       uint32_t ID;
204       llvm::yaml::Hex32 BrProb;
205     };
206     std::optional<uint64_t> BBFreq;
207     std::optional<std::vector<SuccessorEntry>> Successors;
208   };
209   std::optional<uint64_t> FuncEntryCount;
210   std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
211 };
212 
213 struct StackSizeEntry {
214   llvm::yaml::Hex64 Address;
215   llvm::yaml::Hex64 Size;
216 };
217 
218 struct NoteEntry {
219   StringRef Name;
220   yaml::BinaryRef Desc;
221   ELF_NT Type;
222 };
223 
224 struct Chunk {
225   enum class ChunkKind {
226     Dynamic,
227     Group,
228     RawContent,
229     Relocation,
230     Relr,
231     NoBits,
232     Note,
233     Hash,
234     GnuHash,
235     Verdef,
236     Verneed,
237     StackSizes,
238     SymtabShndxSection,
239     Symver,
240     ARMIndexTable,
241     MipsABIFlags,
242     Addrsig,
243     LinkerOptions,
244     DependentLibraries,
245     CallGraphProfile,
246     BBAddrMap,
247 
248     // Special chunks.
249     SpecialChunksStart,
250     Fill = SpecialChunksStart,
251     SectionHeaderTable,
252   };
253 
254   ChunkKind Kind;
255   StringRef Name;
256   std::optional<llvm::yaml::Hex64> Offset;
257 
258   // Usually chunks are not created implicitly, but rather loaded from YAML.
259   // This flag is used to signal whether this is the case or not.
260   bool IsImplicit;
261 
ChunkChunk262   Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
263   virtual ~Chunk();
264 };
265 
266 struct Section : public Chunk {
267   ELF_SHT Type;
268   std::optional<ELF_SHF> Flags;
269   std::optional<llvm::yaml::Hex64> Address;
270   std::optional<StringRef> Link;
271   llvm::yaml::Hex64 AddressAlign;
272   std::optional<llvm::yaml::Hex64> EntSize;
273 
274   std::optional<yaml::BinaryRef> Content;
275   std::optional<llvm::yaml::Hex64> Size;
276 
277   // Holds the original section index.
278   unsigned OriginalSecNdx;
279 
ChunkSection280   Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
281 
classofSection282   static bool classof(const Chunk *S) {
283     return S->Kind < ChunkKind::SpecialChunksStart;
284   }
285 
286   // Some derived sections might have their own special entries. This method
287   // returns a vector of <entry name, is used> pairs. It is used for section
288   // validation.
getEntriesSection289   virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
290     return {};
291   };
292 
293   // The following members are used to override section fields which is
294   // useful for creating invalid objects.
295 
296   // This can be used to override the sh_addralign field.
297   std::optional<llvm::yaml::Hex64> ShAddrAlign;
298 
299   // This can be used to override the offset stored in the sh_name field.
300   // It does not affect the name stored in the string table.
301   std::optional<llvm::yaml::Hex64> ShName;
302 
303   // This can be used to override the sh_offset field. It does not place the
304   // section data at the offset specified.
305   std::optional<llvm::yaml::Hex64> ShOffset;
306 
307   // This can be used to override the sh_size field. It does not affect the
308   // content written.
309   std::optional<llvm::yaml::Hex64> ShSize;
310 
311   // This can be used to override the sh_flags field.
312   std::optional<llvm::yaml::Hex64> ShFlags;
313 
314   // This can be used to override the sh_type field. It is useful when we
315   // want to use specific YAML keys for a section of a particular type to
316   // describe the content, but still want to have a different final type
317   // for the section.
318   std::optional<ELF_SHT> ShType;
319 };
320 
321 // Fill is a block of data which is placed outside of sections. It is
322 // not present in the sections header table, but it might affect the output file
323 // size and program headers produced.
324 struct Fill : Chunk {
325   std::optional<yaml::BinaryRef> Pattern;
326   llvm::yaml::Hex64 Size;
327 
FillFill328   Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
329 
classofFill330   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
331 };
332 
333 struct SectionHeaderTable : Chunk {
SectionHeaderTableSectionHeaderTable334   SectionHeaderTable(bool IsImplicit)
335       : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
336 
classofSectionHeaderTable337   static bool classof(const Chunk *S) {
338     return S->Kind == ChunkKind::SectionHeaderTable;
339   }
340 
341   std::optional<std::vector<SectionHeader>> Sections;
342   std::optional<std::vector<SectionHeader>> Excluded;
343   std::optional<bool> NoHeaders;
344 
getNumHeadersSectionHeaderTable345   size_t getNumHeaders(size_t SectionsNum) const {
346     if (IsImplicit || isDefault())
347       return SectionsNum;
348     if (NoHeaders)
349       return (*NoHeaders) ? 0 : SectionsNum;
350     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
351   }
352 
isDefaultSectionHeaderTable353   bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
354 
355   static constexpr StringRef TypeStr = "SectionHeaderTable";
356 };
357 
358 struct BBAddrMapSection : Section {
359   std::optional<std::vector<BBAddrMapEntry>> Entries;
360   std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
361 
BBAddrMapSectionBBAddrMapSection362   BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
363 
getEntriesBBAddrMapSection364   std::vector<std::pair<StringRef, bool>> getEntries() const override {
365     return {{"Entries", Entries.has_value()}};
366   };
367 
classofBBAddrMapSection368   static bool classof(const Chunk *S) {
369     return S->Kind == ChunkKind::BBAddrMap;
370   }
371 };
372 
373 struct StackSizesSection : Section {
374   std::optional<std::vector<StackSizeEntry>> Entries;
375 
StackSizesSectionStackSizesSection376   StackSizesSection() : Section(ChunkKind::StackSizes) {}
377 
getEntriesStackSizesSection378   std::vector<std::pair<StringRef, bool>> getEntries() const override {
379     return {{"Entries", Entries.has_value()}};
380   };
381 
classofStackSizesSection382   static bool classof(const Chunk *S) {
383     return S->Kind == ChunkKind::StackSizes;
384   }
385 
nameMatchesStackSizesSection386   static bool nameMatches(StringRef Name) {
387     return Name == ".stack_sizes";
388   }
389 };
390 
391 struct DynamicSection : Section {
392   std::optional<std::vector<DynamicEntry>> Entries;
393 
DynamicSectionDynamicSection394   DynamicSection() : Section(ChunkKind::Dynamic) {}
395 
getEntriesDynamicSection396   std::vector<std::pair<StringRef, bool>> getEntries() const override {
397     return {{"Entries", Entries.has_value()}};
398   };
399 
classofDynamicSection400   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
401 };
402 
403 struct RawContentSection : Section {
404   std::optional<llvm::yaml::Hex64> Info;
405 
RawContentSectionRawContentSection406   RawContentSection() : Section(ChunkKind::RawContent) {}
407 
classofRawContentSection408   static bool classof(const Chunk *S) {
409     return S->Kind == ChunkKind::RawContent;
410   }
411 
412   // Is used when a content is read as an array of bytes.
413   std::optional<std::vector<uint8_t>> ContentBuf;
414 };
415 
416 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection417   NoBitsSection() : Section(ChunkKind::NoBits) {}
418 
classofNoBitsSection419   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
420 };
421 
422 struct NoteSection : Section {
423   std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
424 
NoteSectionNoteSection425   NoteSection() : Section(ChunkKind::Note) {}
426 
getEntriesNoteSection427   std::vector<std::pair<StringRef, bool>> getEntries() const override {
428     return {{"Notes", Notes.has_value()}};
429   };
430 
classofNoteSection431   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
432 };
433 
434 struct HashSection : Section {
435   std::optional<std::vector<uint32_t>> Bucket;
436   std::optional<std::vector<uint32_t>> Chain;
437 
getEntriesHashSection438   std::vector<std::pair<StringRef, bool>> getEntries() const override {
439     return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
440   };
441 
442   // The following members are used to override section fields.
443   // This is useful for creating invalid objects.
444   std::optional<llvm::yaml::Hex64> NBucket;
445   std::optional<llvm::yaml::Hex64> NChain;
446 
HashSectionHashSection447   HashSection() : Section(ChunkKind::Hash) {}
448 
classofHashSection449   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
450 };
451 
452 struct GnuHashHeader {
453   // The number of hash buckets.
454   // Not used when dumping the object, but can be used to override
455   // the real number of buckets when emiting an object from a YAML document.
456   std::optional<llvm::yaml::Hex32> NBuckets;
457 
458   // Index of the first symbol in the dynamic symbol table
459   // included in the hash table.
460   llvm::yaml::Hex32 SymNdx;
461 
462   // The number of words in the Bloom filter.
463   // Not used when dumping the object, but can be used to override the real
464   // number of words in the Bloom filter when emiting an object from a YAML
465   // document.
466   std::optional<llvm::yaml::Hex32> MaskWords;
467 
468   // A shift constant used by the Bloom filter.
469   llvm::yaml::Hex32 Shift2;
470 };
471 
472 struct GnuHashSection : Section {
473   std::optional<GnuHashHeader> Header;
474   std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
475   std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
476   std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
477 
GnuHashSectionGnuHashSection478   GnuHashSection() : Section(ChunkKind::GnuHash) {}
479 
getEntriesGnuHashSection480   std::vector<std::pair<StringRef, bool>> getEntries() const override {
481     return {{"Header", Header.has_value()},
482             {"BloomFilter", BloomFilter.has_value()},
483             {"HashBuckets", HashBuckets.has_value()},
484             {"HashValues", HashValues.has_value()}};
485   };
486 
classofGnuHashSection487   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
488 };
489 
490 struct VernauxEntry {
491   uint32_t Hash;
492   uint16_t Flags;
493   uint16_t Other;
494   StringRef Name;
495 };
496 
497 struct VerneedEntry {
498   uint16_t Version;
499   StringRef File;
500   std::vector<VernauxEntry> AuxV;
501 };
502 
503 struct VerneedSection : Section {
504   std::optional<std::vector<VerneedEntry>> VerneedV;
505   std::optional<llvm::yaml::Hex64> Info;
506 
VerneedSectionVerneedSection507   VerneedSection() : Section(ChunkKind::Verneed) {}
508 
getEntriesVerneedSection509   std::vector<std::pair<StringRef, bool>> getEntries() const override {
510     return {{"Dependencies", VerneedV.has_value()}};
511   };
512 
classofVerneedSection513   static bool classof(const Chunk *S) {
514     return S->Kind == ChunkKind::Verneed;
515   }
516 };
517 
518 struct AddrsigSection : Section {
519   std::optional<std::vector<YAMLFlowString>> Symbols;
520 
AddrsigSectionAddrsigSection521   AddrsigSection() : Section(ChunkKind::Addrsig) {}
522 
getEntriesAddrsigSection523   std::vector<std::pair<StringRef, bool>> getEntries() const override {
524     return {{"Symbols", Symbols.has_value()}};
525   };
526 
classofAddrsigSection527   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
528 };
529 
530 struct LinkerOption {
531   StringRef Key;
532   StringRef Value;
533 };
534 
535 struct LinkerOptionsSection : Section {
536   std::optional<std::vector<LinkerOption>> Options;
537 
LinkerOptionsSectionLinkerOptionsSection538   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
539 
getEntriesLinkerOptionsSection540   std::vector<std::pair<StringRef, bool>> getEntries() const override {
541     return {{"Options", Options.has_value()}};
542   };
543 
classofLinkerOptionsSection544   static bool classof(const Chunk *S) {
545     return S->Kind == ChunkKind::LinkerOptions;
546   }
547 };
548 
549 struct DependentLibrariesSection : Section {
550   std::optional<std::vector<YAMLFlowString>> Libs;
551 
DependentLibrariesSectionDependentLibrariesSection552   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
553 
getEntriesDependentLibrariesSection554   std::vector<std::pair<StringRef, bool>> getEntries() const override {
555     return {{"Libraries", Libs.has_value()}};
556   };
557 
classofDependentLibrariesSection558   static bool classof(const Chunk *S) {
559     return S->Kind == ChunkKind::DependentLibraries;
560   }
561 };
562 
563 // Represents the call graph profile section entry.
564 struct CallGraphEntryWeight {
565   // The weight of the edge.
566   uint64_t Weight;
567 };
568 
569 struct CallGraphProfileSection : Section {
570   std::optional<std::vector<CallGraphEntryWeight>> Entries;
571 
CallGraphProfileSectionCallGraphProfileSection572   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
573 
getEntriesCallGraphProfileSection574   std::vector<std::pair<StringRef, bool>> getEntries() const override {
575     return {{"Entries", Entries.has_value()}};
576   };
577 
classofCallGraphProfileSection578   static bool classof(const Chunk *S) {
579     return S->Kind == ChunkKind::CallGraphProfile;
580   }
581 };
582 
583 struct SymverSection : Section {
584   std::optional<std::vector<uint16_t>> Entries;
585 
SymverSectionSymverSection586   SymverSection() : Section(ChunkKind::Symver) {}
587 
getEntriesSymverSection588   std::vector<std::pair<StringRef, bool>> getEntries() const override {
589     return {{"Entries", Entries.has_value()}};
590   };
591 
classofSymverSection592   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
593 };
594 
595 struct VerdefEntry {
596   std::optional<uint16_t> Version;
597   std::optional<uint16_t> Flags;
598   std::optional<uint16_t> VersionNdx;
599   std::optional<uint32_t> Hash;
600   std::optional<uint16_t> VDAux;
601   std::vector<StringRef> VerNames;
602 };
603 
604 struct VerdefSection : Section {
605   std::optional<std::vector<VerdefEntry>> Entries;
606   std::optional<llvm::yaml::Hex64> Info;
607 
VerdefSectionVerdefSection608   VerdefSection() : Section(ChunkKind::Verdef) {}
609 
getEntriesVerdefSection610   std::vector<std::pair<StringRef, bool>> getEntries() const override {
611     return {{"Entries", Entries.has_value()}};
612   };
613 
classofVerdefSection614   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
615 };
616 
617 struct GroupSection : Section {
618   // Members of a group contain a flag and a list of section indices
619   // that are part of the group.
620   std::optional<std::vector<SectionOrType>> Members;
621   std::optional<StringRef> Signature; /* Info */
622 
GroupSectionGroupSection623   GroupSection() : Section(ChunkKind::Group) {}
624 
getEntriesGroupSection625   std::vector<std::pair<StringRef, bool>> getEntries() const override {
626     return {{"Members", Members.has_value()}};
627   };
628 
classofGroupSection629   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
630 };
631 
632 struct Relocation {
633   llvm::yaml::Hex64 Offset;
634   YAMLIntUInt Addend;
635   ELF_REL Type;
636   std::optional<StringRef> Symbol;
637 };
638 
639 struct RelocationSection : Section {
640   std::optional<std::vector<Relocation>> Relocations;
641   StringRef RelocatableSec; /* Info */
642 
RelocationSectionRelocationSection643   RelocationSection() : Section(ChunkKind::Relocation) {}
644 
getEntriesRelocationSection645   std::vector<std::pair<StringRef, bool>> getEntries() const override {
646     return {{"Relocations", Relocations.has_value()}};
647   };
648 
classofRelocationSection649   static bool classof(const Chunk *S) {
650     return S->Kind == ChunkKind::Relocation;
651   }
652 };
653 
654 struct RelrSection : Section {
655   std::optional<std::vector<llvm::yaml::Hex64>> Entries;
656 
RelrSectionRelrSection657   RelrSection() : Section(ChunkKind::Relr) {}
658 
getEntriesRelrSection659   std::vector<std::pair<StringRef, bool>> getEntries() const override {
660     return {{"Entries", Entries.has_value()}};
661   };
662 
classofRelrSection663   static bool classof(const Chunk *S) {
664     return S->Kind == ChunkKind::Relr;
665   }
666 };
667 
668 struct SymtabShndxSection : Section {
669   std::optional<std::vector<uint32_t>> Entries;
670 
SymtabShndxSectionSymtabShndxSection671   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
672 
getEntriesSymtabShndxSection673   std::vector<std::pair<StringRef, bool>> getEntries() const override {
674     return {{"Entries", Entries.has_value()}};
675   };
676 
classofSymtabShndxSection677   static bool classof(const Chunk *S) {
678     return S->Kind == ChunkKind::SymtabShndxSection;
679   }
680 };
681 
682 struct ARMIndexTableEntry {
683   llvm::yaml::Hex32 Offset;
684   llvm::yaml::Hex32 Value;
685 };
686 
687 struct ARMIndexTableSection : Section {
688   std::optional<std::vector<ARMIndexTableEntry>> Entries;
689 
ARMIndexTableSectionARMIndexTableSection690   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
691 
getEntriesARMIndexTableSection692   std::vector<std::pair<StringRef, bool>> getEntries() const override {
693     return {{"Entries", Entries.has_value()}};
694   };
695 
classofARMIndexTableSection696   static bool classof(const Chunk *S) {
697     return S->Kind == ChunkKind::ARMIndexTable;
698   }
699 };
700 
701 // Represents .MIPS.abiflags section
702 struct MipsABIFlags : Section {
703   llvm::yaml::Hex16 Version;
704   MIPS_ISA ISALevel;
705   llvm::yaml::Hex8 ISARevision;
706   MIPS_AFL_REG GPRSize;
707   MIPS_AFL_REG CPR1Size;
708   MIPS_AFL_REG CPR2Size;
709   MIPS_ABI_FP FpABI;
710   MIPS_AFL_EXT ISAExtension;
711   MIPS_AFL_ASE ASEs;
712   MIPS_AFL_FLAGS1 Flags1;
713   llvm::yaml::Hex32 Flags2;
714 
MipsABIFlagsMipsABIFlags715   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
716 
classofMipsABIFlags717   static bool classof(const Chunk *S) {
718     return S->Kind == ChunkKind::MipsABIFlags;
719   }
720 };
721 
722 struct ProgramHeader {
723   ELF_PT Type;
724   ELF_PF Flags;
725   llvm::yaml::Hex64 VAddr;
726   llvm::yaml::Hex64 PAddr;
727   std::optional<llvm::yaml::Hex64> Align;
728   std::optional<llvm::yaml::Hex64> FileSize;
729   std::optional<llvm::yaml::Hex64> MemSize;
730   std::optional<llvm::yaml::Hex64> Offset;
731   std::optional<StringRef> FirstSec;
732   std::optional<StringRef> LastSec;
733 
734   // This vector contains all chunks from [FirstSec, LastSec].
735   std::vector<Chunk *> Chunks;
736 };
737 
738 struct Object {
739   FileHeader Header;
740   std::vector<ProgramHeader> ProgramHeaders;
741 
742   // An object might contain output section descriptions as well as
743   // custom data that does not belong to any section.
744   std::vector<std::unique_ptr<Chunk>> Chunks;
745 
746   // Although in reality the symbols reside in a section, it is a lot
747   // cleaner and nicer if we read them from the YAML as a separate
748   // top-level key, which automatically ensures that invariants like there
749   // being a single SHT_SYMTAB section are upheld.
750   std::optional<std::vector<Symbol>> Symbols;
751   std::optional<std::vector<Symbol>> DynamicSymbols;
752   std::optional<DWARFYAML::Data> DWARF;
753 
getSectionsObject754   std::vector<Section *> getSections() {
755     std::vector<Section *> Ret;
756     for (const std::unique_ptr<Chunk> &Sec : Chunks)
757       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
758         Ret.push_back(S);
759     return Ret;
760   }
761 
getSectionHeaderTableObject762   const SectionHeaderTable &getSectionHeaderTable() const {
763     for (const std::unique_ptr<Chunk> &C : Chunks)
764       if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
765         return *S;
766     llvm_unreachable("the section header table chunk must always be present");
767   }
768 
769   ELF_ELFOSABI getOSAbi() const;
770   unsigned getMachine() const;
771 };
772 
773 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
774                              const NoBitsSection &S);
775 
776 } // end namespace ELFYAML
777 } // end namespace llvm
778 
779 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)780 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
781 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
782 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
783 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
784 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
785 LLVM_YAML_IS_SEQUENCE_VECTOR(
786     llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
787 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
788 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
789 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
790 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
791 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
792 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
793 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
794 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
795 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
796 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
797 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
798 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
799 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
800 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
801 
802 namespace llvm {
803 namespace yaml {
804 
805 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
806   static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
807                      raw_ostream &Out);
808   static StringRef input(StringRef Scalar, void *Ctx,
809                          ELFYAML::YAMLIntUInt &Val);
810   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
811 };
812 
813 template <>
814 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
815   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
816 };
817 
818 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
819   static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
820 };
821 
822 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
823   static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
824 };
825 
826 template <>
827 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
828   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
829 };
830 
831 template <>
832 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
833   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
834 };
835 
836 template <>
837 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
838   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
839 };
840 
841 template <>
842 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
843   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
844 };
845 
846 template <>
847 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
848   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
849 };
850 
851 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
852   static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
853 };
854 
855 template <>
856 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
857   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
858 };
859 
860 template <>
861 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
862   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
863 };
864 
865 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
866   static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
867 };
868 
869 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
870   static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
871 };
872 
873 template <>
874 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
875   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
876 };
877 
878 template <>
879 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
880   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
881 };
882 
883 template <>
884 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
885   static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
886 };
887 
888 template <>
889 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
890   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
891 };
892 
893 template <>
894 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
895   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
896 };
897 
898 template <>
899 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
900   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
901 };
902 
903 template <>
904 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
905   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
906 };
907 
908 template <>
909 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
910   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
911 };
912 
913 template <>
914 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
915   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
916 };
917 
918 template <>
919 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
920   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
921 };
922 
923 template <>
924 struct MappingTraits<ELFYAML::FileHeader> {
925   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
926 };
927 
928 template <> struct MappingTraits<ELFYAML::SectionHeader> {
929   static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
930 };
931 
932 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
933   static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
934   static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
935 };
936 
937 template <>
938 struct MappingTraits<ELFYAML::Symbol> {
939   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
940   static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
941 };
942 
943 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
944   static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
945 };
946 
947 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
948   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
949 };
950 
951 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
952   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
953 };
954 
955 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
956   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
957 };
958 
959 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
960   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
961 };
962 
963 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
964   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
965 };
966 
967 template <>
968 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
969   static void
970   mapping(IO &IO,
971           ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
972 };
973 
974 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
975   static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
976 };
977 
978 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
979   static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
980 };
981 
982 template <> struct MappingTraits<ELFYAML::NoteEntry> {
983   static void mapping(IO &IO, ELFYAML::NoteEntry &N);
984 };
985 
986 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
987   static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
988 };
989 
990 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
991   static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
992 };
993 
994 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
995   static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
996 };
997 
998 template <> struct MappingTraits<ELFYAML::LinkerOption> {
999   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
1000 };
1001 
1002 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
1003   static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
1004 };
1005 
1006 template <> struct MappingTraits<ELFYAML::Relocation> {
1007   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
1008 };
1009 
1010 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
1011   static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
1012 };
1013 
1014 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
1015   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
1016   static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
1017 };
1018 
1019 template <>
1020 struct MappingTraits<ELFYAML::Object> {
1021   static void mapping(IO &IO, ELFYAML::Object &Object);
1022 };
1023 
1024 template <> struct MappingTraits<ELFYAML::SectionOrType> {
1025   static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
1026 };
1027 
1028 } // end namespace yaml
1029 } // end namespace llvm
1030 
1031 #endif // LLVM_OBJECTYAML_ELFYAML_H
1032