xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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   };
166   uint8_t Version;
167   llvm::yaml::Hex8 Feature;
168 
169   struct BBRangeEntry {
170     llvm::yaml::Hex64 BaseAddress;
171     std::optional<uint64_t> NumBlocks;
172     std::optional<std::vector<BBEntry>> BBEntries;
173   };
174 
175   std::optional<uint64_t> NumBBRanges;
176   std::optional<std::vector<BBRangeEntry>> BBRanges;
177 
getFunctionAddressBBAddrMapEntry178   llvm::yaml::Hex64 getFunctionAddress() const {
179     if (!BBRanges || BBRanges->empty())
180       return 0;
181     return BBRanges->front().BaseAddress;
182   }
183 };
184 
185 struct PGOAnalysisMapEntry {
186   struct PGOBBEntry {
187     struct SuccessorEntry {
188       uint32_t ID;
189       llvm::yaml::Hex32 BrProb;
190     };
191     std::optional<uint64_t> BBFreq;
192     std::optional<std::vector<SuccessorEntry>> Successors;
193   };
194   std::optional<uint64_t> FuncEntryCount;
195   std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
196 };
197 
198 struct StackSizeEntry {
199   llvm::yaml::Hex64 Address;
200   llvm::yaml::Hex64 Size;
201 };
202 
203 struct NoteEntry {
204   StringRef Name;
205   yaml::BinaryRef Desc;
206   ELF_NT Type;
207 };
208 
209 struct Chunk {
210   enum class ChunkKind {
211     Dynamic,
212     Group,
213     RawContent,
214     Relocation,
215     Relr,
216     NoBits,
217     Note,
218     Hash,
219     GnuHash,
220     Verdef,
221     Verneed,
222     StackSizes,
223     SymtabShndxSection,
224     Symver,
225     ARMIndexTable,
226     MipsABIFlags,
227     Addrsig,
228     LinkerOptions,
229     DependentLibraries,
230     CallGraphProfile,
231     BBAddrMap,
232 
233     // Special chunks.
234     SpecialChunksStart,
235     Fill = SpecialChunksStart,
236     SectionHeaderTable,
237   };
238 
239   ChunkKind Kind;
240   StringRef Name;
241   std::optional<llvm::yaml::Hex64> Offset;
242 
243   // Usually chunks are not created implicitly, but rather loaded from YAML.
244   // This flag is used to signal whether this is the case or not.
245   bool IsImplicit;
246 
ChunkChunk247   Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
248   virtual ~Chunk();
249 };
250 
251 struct Section : public Chunk {
252   ELF_SHT Type;
253   std::optional<ELF_SHF> Flags;
254   std::optional<llvm::yaml::Hex64> Address;
255   std::optional<StringRef> Link;
256   llvm::yaml::Hex64 AddressAlign;
257   std::optional<llvm::yaml::Hex64> EntSize;
258 
259   std::optional<yaml::BinaryRef> Content;
260   std::optional<llvm::yaml::Hex64> Size;
261 
262   // Holds the original section index.
263   unsigned OriginalSecNdx;
264 
ChunkSection265   Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
266 
classofSection267   static bool classof(const Chunk *S) {
268     return S->Kind < ChunkKind::SpecialChunksStart;
269   }
270 
271   // Some derived sections might have their own special entries. This method
272   // returns a vector of <entry name, is used> pairs. It is used for section
273   // validation.
getEntriesSection274   virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
275     return {};
276   };
277 
278   // The following members are used to override section fields which is
279   // useful for creating invalid objects.
280 
281   // This can be used to override the sh_addralign field.
282   std::optional<llvm::yaml::Hex64> ShAddrAlign;
283 
284   // This can be used to override the offset stored in the sh_name field.
285   // It does not affect the name stored in the string table.
286   std::optional<llvm::yaml::Hex64> ShName;
287 
288   // This can be used to override the sh_offset field. It does not place the
289   // section data at the offset specified.
290   std::optional<llvm::yaml::Hex64> ShOffset;
291 
292   // This can be used to override the sh_size field. It does not affect the
293   // content written.
294   std::optional<llvm::yaml::Hex64> ShSize;
295 
296   // This can be used to override the sh_flags field.
297   std::optional<llvm::yaml::Hex64> ShFlags;
298 
299   // This can be used to override the sh_type field. It is useful when we
300   // want to use specific YAML keys for a section of a particular type to
301   // describe the content, but still want to have a different final type
302   // for the section.
303   std::optional<ELF_SHT> ShType;
304 };
305 
306 // Fill is a block of data which is placed outside of sections. It is
307 // not present in the sections header table, but it might affect the output file
308 // size and program headers produced.
309 struct Fill : Chunk {
310   std::optional<yaml::BinaryRef> Pattern;
311   llvm::yaml::Hex64 Size;
312 
FillFill313   Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
314 
classofFill315   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
316 };
317 
318 struct SectionHeaderTable : Chunk {
SectionHeaderTableSectionHeaderTable319   SectionHeaderTable(bool IsImplicit)
320       : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
321 
classofSectionHeaderTable322   static bool classof(const Chunk *S) {
323     return S->Kind == ChunkKind::SectionHeaderTable;
324   }
325 
326   std::optional<std::vector<SectionHeader>> Sections;
327   std::optional<std::vector<SectionHeader>> Excluded;
328   std::optional<bool> NoHeaders;
329 
getNumHeadersSectionHeaderTable330   size_t getNumHeaders(size_t SectionsNum) const {
331     if (IsImplicit || isDefault())
332       return SectionsNum;
333     if (NoHeaders)
334       return (*NoHeaders) ? 0 : SectionsNum;
335     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
336   }
337 
isDefaultSectionHeaderTable338   bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
339 
340   static constexpr StringRef TypeStr = "SectionHeaderTable";
341 };
342 
343 struct BBAddrMapSection : Section {
344   std::optional<std::vector<BBAddrMapEntry>> Entries;
345   std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
346 
BBAddrMapSectionBBAddrMapSection347   BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
348 
getEntriesBBAddrMapSection349   std::vector<std::pair<StringRef, bool>> getEntries() const override {
350     return {{"Entries", Entries.has_value()}};
351   };
352 
classofBBAddrMapSection353   static bool classof(const Chunk *S) {
354     return S->Kind == ChunkKind::BBAddrMap;
355   }
356 };
357 
358 struct StackSizesSection : Section {
359   std::optional<std::vector<StackSizeEntry>> Entries;
360 
StackSizesSectionStackSizesSection361   StackSizesSection() : Section(ChunkKind::StackSizes) {}
362 
getEntriesStackSizesSection363   std::vector<std::pair<StringRef, bool>> getEntries() const override {
364     return {{"Entries", Entries.has_value()}};
365   };
366 
classofStackSizesSection367   static bool classof(const Chunk *S) {
368     return S->Kind == ChunkKind::StackSizes;
369   }
370 
nameMatchesStackSizesSection371   static bool nameMatches(StringRef Name) {
372     return Name == ".stack_sizes";
373   }
374 };
375 
376 struct DynamicSection : Section {
377   std::optional<std::vector<DynamicEntry>> Entries;
378 
DynamicSectionDynamicSection379   DynamicSection() : Section(ChunkKind::Dynamic) {}
380 
getEntriesDynamicSection381   std::vector<std::pair<StringRef, bool>> getEntries() const override {
382     return {{"Entries", Entries.has_value()}};
383   };
384 
classofDynamicSection385   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
386 };
387 
388 struct RawContentSection : Section {
389   std::optional<llvm::yaml::Hex64> Info;
390 
RawContentSectionRawContentSection391   RawContentSection() : Section(ChunkKind::RawContent) {}
392 
classofRawContentSection393   static bool classof(const Chunk *S) {
394     return S->Kind == ChunkKind::RawContent;
395   }
396 
397   // Is used when a content is read as an array of bytes.
398   std::optional<std::vector<uint8_t>> ContentBuf;
399 };
400 
401 struct NoBitsSection : Section {
NoBitsSectionNoBitsSection402   NoBitsSection() : Section(ChunkKind::NoBits) {}
403 
classofNoBitsSection404   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
405 };
406 
407 struct NoteSection : Section {
408   std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
409 
NoteSectionNoteSection410   NoteSection() : Section(ChunkKind::Note) {}
411 
getEntriesNoteSection412   std::vector<std::pair<StringRef, bool>> getEntries() const override {
413     return {{"Notes", Notes.has_value()}};
414   };
415 
classofNoteSection416   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
417 };
418 
419 struct HashSection : Section {
420   std::optional<std::vector<uint32_t>> Bucket;
421   std::optional<std::vector<uint32_t>> Chain;
422 
getEntriesHashSection423   std::vector<std::pair<StringRef, bool>> getEntries() const override {
424     return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
425   };
426 
427   // The following members are used to override section fields.
428   // This is useful for creating invalid objects.
429   std::optional<llvm::yaml::Hex64> NBucket;
430   std::optional<llvm::yaml::Hex64> NChain;
431 
HashSectionHashSection432   HashSection() : Section(ChunkKind::Hash) {}
433 
classofHashSection434   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
435 };
436 
437 struct GnuHashHeader {
438   // The number of hash buckets.
439   // Not used when dumping the object, but can be used to override
440   // the real number of buckets when emiting an object from a YAML document.
441   std::optional<llvm::yaml::Hex32> NBuckets;
442 
443   // Index of the first symbol in the dynamic symbol table
444   // included in the hash table.
445   llvm::yaml::Hex32 SymNdx;
446 
447   // The number of words in the Bloom filter.
448   // Not used when dumping the object, but can be used to override the real
449   // number of words in the Bloom filter when emiting an object from a YAML
450   // document.
451   std::optional<llvm::yaml::Hex32> MaskWords;
452 
453   // A shift constant used by the Bloom filter.
454   llvm::yaml::Hex32 Shift2;
455 };
456 
457 struct GnuHashSection : Section {
458   std::optional<GnuHashHeader> Header;
459   std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
460   std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
461   std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
462 
GnuHashSectionGnuHashSection463   GnuHashSection() : Section(ChunkKind::GnuHash) {}
464 
getEntriesGnuHashSection465   std::vector<std::pair<StringRef, bool>> getEntries() const override {
466     return {{"Header", Header.has_value()},
467             {"BloomFilter", BloomFilter.has_value()},
468             {"HashBuckets", HashBuckets.has_value()},
469             {"HashValues", HashValues.has_value()}};
470   };
471 
classofGnuHashSection472   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
473 };
474 
475 struct VernauxEntry {
476   uint32_t Hash;
477   uint16_t Flags;
478   uint16_t Other;
479   StringRef Name;
480 };
481 
482 struct VerneedEntry {
483   uint16_t Version;
484   StringRef File;
485   std::vector<VernauxEntry> AuxV;
486 };
487 
488 struct VerneedSection : Section {
489   std::optional<std::vector<VerneedEntry>> VerneedV;
490   std::optional<llvm::yaml::Hex64> Info;
491 
VerneedSectionVerneedSection492   VerneedSection() : Section(ChunkKind::Verneed) {}
493 
getEntriesVerneedSection494   std::vector<std::pair<StringRef, bool>> getEntries() const override {
495     return {{"Dependencies", VerneedV.has_value()}};
496   };
497 
classofVerneedSection498   static bool classof(const Chunk *S) {
499     return S->Kind == ChunkKind::Verneed;
500   }
501 };
502 
503 struct AddrsigSection : Section {
504   std::optional<std::vector<YAMLFlowString>> Symbols;
505 
AddrsigSectionAddrsigSection506   AddrsigSection() : Section(ChunkKind::Addrsig) {}
507 
getEntriesAddrsigSection508   std::vector<std::pair<StringRef, bool>> getEntries() const override {
509     return {{"Symbols", Symbols.has_value()}};
510   };
511 
classofAddrsigSection512   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
513 };
514 
515 struct LinkerOption {
516   StringRef Key;
517   StringRef Value;
518 };
519 
520 struct LinkerOptionsSection : Section {
521   std::optional<std::vector<LinkerOption>> Options;
522 
LinkerOptionsSectionLinkerOptionsSection523   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
524 
getEntriesLinkerOptionsSection525   std::vector<std::pair<StringRef, bool>> getEntries() const override {
526     return {{"Options", Options.has_value()}};
527   };
528 
classofLinkerOptionsSection529   static bool classof(const Chunk *S) {
530     return S->Kind == ChunkKind::LinkerOptions;
531   }
532 };
533 
534 struct DependentLibrariesSection : Section {
535   std::optional<std::vector<YAMLFlowString>> Libs;
536 
DependentLibrariesSectionDependentLibrariesSection537   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
538 
getEntriesDependentLibrariesSection539   std::vector<std::pair<StringRef, bool>> getEntries() const override {
540     return {{"Libraries", Libs.has_value()}};
541   };
542 
classofDependentLibrariesSection543   static bool classof(const Chunk *S) {
544     return S->Kind == ChunkKind::DependentLibraries;
545   }
546 };
547 
548 // Represents the call graph profile section entry.
549 struct CallGraphEntryWeight {
550   // The weight of the edge.
551   uint64_t Weight;
552 };
553 
554 struct CallGraphProfileSection : Section {
555   std::optional<std::vector<CallGraphEntryWeight>> Entries;
556 
CallGraphProfileSectionCallGraphProfileSection557   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
558 
getEntriesCallGraphProfileSection559   std::vector<std::pair<StringRef, bool>> getEntries() const override {
560     return {{"Entries", Entries.has_value()}};
561   };
562 
classofCallGraphProfileSection563   static bool classof(const Chunk *S) {
564     return S->Kind == ChunkKind::CallGraphProfile;
565   }
566 };
567 
568 struct SymverSection : Section {
569   std::optional<std::vector<uint16_t>> Entries;
570 
SymverSectionSymverSection571   SymverSection() : Section(ChunkKind::Symver) {}
572 
getEntriesSymverSection573   std::vector<std::pair<StringRef, bool>> getEntries() const override {
574     return {{"Entries", Entries.has_value()}};
575   };
576 
classofSymverSection577   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
578 };
579 
580 struct VerdefEntry {
581   std::optional<uint16_t> Version;
582   std::optional<uint16_t> Flags;
583   std::optional<uint16_t> VersionNdx;
584   std::optional<uint32_t> Hash;
585   std::vector<StringRef> VerNames;
586 };
587 
588 struct VerdefSection : Section {
589   std::optional<std::vector<VerdefEntry>> Entries;
590   std::optional<llvm::yaml::Hex64> Info;
591 
VerdefSectionVerdefSection592   VerdefSection() : Section(ChunkKind::Verdef) {}
593 
getEntriesVerdefSection594   std::vector<std::pair<StringRef, bool>> getEntries() const override {
595     return {{"Entries", Entries.has_value()}};
596   };
597 
classofVerdefSection598   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
599 };
600 
601 struct GroupSection : Section {
602   // Members of a group contain a flag and a list of section indices
603   // that are part of the group.
604   std::optional<std::vector<SectionOrType>> Members;
605   std::optional<StringRef> Signature; /* Info */
606 
GroupSectionGroupSection607   GroupSection() : Section(ChunkKind::Group) {}
608 
getEntriesGroupSection609   std::vector<std::pair<StringRef, bool>> getEntries() const override {
610     return {{"Members", Members.has_value()}};
611   };
612 
classofGroupSection613   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
614 };
615 
616 struct Relocation {
617   llvm::yaml::Hex64 Offset;
618   YAMLIntUInt Addend;
619   ELF_REL Type;
620   std::optional<StringRef> Symbol;
621 };
622 
623 struct RelocationSection : Section {
624   std::optional<std::vector<Relocation>> Relocations;
625   StringRef RelocatableSec; /* Info */
626 
RelocationSectionRelocationSection627   RelocationSection() : Section(ChunkKind::Relocation) {}
628 
getEntriesRelocationSection629   std::vector<std::pair<StringRef, bool>> getEntries() const override {
630     return {{"Relocations", Relocations.has_value()}};
631   };
632 
classofRelocationSection633   static bool classof(const Chunk *S) {
634     return S->Kind == ChunkKind::Relocation;
635   }
636 };
637 
638 struct RelrSection : Section {
639   std::optional<std::vector<llvm::yaml::Hex64>> Entries;
640 
RelrSectionRelrSection641   RelrSection() : Section(ChunkKind::Relr) {}
642 
getEntriesRelrSection643   std::vector<std::pair<StringRef, bool>> getEntries() const override {
644     return {{"Entries", Entries.has_value()}};
645   };
646 
classofRelrSection647   static bool classof(const Chunk *S) {
648     return S->Kind == ChunkKind::Relr;
649   }
650 };
651 
652 struct SymtabShndxSection : Section {
653   std::optional<std::vector<uint32_t>> Entries;
654 
SymtabShndxSectionSymtabShndxSection655   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
656 
getEntriesSymtabShndxSection657   std::vector<std::pair<StringRef, bool>> getEntries() const override {
658     return {{"Entries", Entries.has_value()}};
659   };
660 
classofSymtabShndxSection661   static bool classof(const Chunk *S) {
662     return S->Kind == ChunkKind::SymtabShndxSection;
663   }
664 };
665 
666 struct ARMIndexTableEntry {
667   llvm::yaml::Hex32 Offset;
668   llvm::yaml::Hex32 Value;
669 };
670 
671 struct ARMIndexTableSection : Section {
672   std::optional<std::vector<ARMIndexTableEntry>> Entries;
673 
ARMIndexTableSectionARMIndexTableSection674   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
675 
getEntriesARMIndexTableSection676   std::vector<std::pair<StringRef, bool>> getEntries() const override {
677     return {{"Entries", Entries.has_value()}};
678   };
679 
classofARMIndexTableSection680   static bool classof(const Chunk *S) {
681     return S->Kind == ChunkKind::ARMIndexTable;
682   }
683 };
684 
685 // Represents .MIPS.abiflags section
686 struct MipsABIFlags : Section {
687   llvm::yaml::Hex16 Version;
688   MIPS_ISA ISALevel;
689   llvm::yaml::Hex8 ISARevision;
690   MIPS_AFL_REG GPRSize;
691   MIPS_AFL_REG CPR1Size;
692   MIPS_AFL_REG CPR2Size;
693   MIPS_ABI_FP FpABI;
694   MIPS_AFL_EXT ISAExtension;
695   MIPS_AFL_ASE ASEs;
696   MIPS_AFL_FLAGS1 Flags1;
697   llvm::yaml::Hex32 Flags2;
698 
MipsABIFlagsMipsABIFlags699   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
700 
classofMipsABIFlags701   static bool classof(const Chunk *S) {
702     return S->Kind == ChunkKind::MipsABIFlags;
703   }
704 };
705 
706 struct ProgramHeader {
707   ELF_PT Type;
708   ELF_PF Flags;
709   llvm::yaml::Hex64 VAddr;
710   llvm::yaml::Hex64 PAddr;
711   std::optional<llvm::yaml::Hex64> Align;
712   std::optional<llvm::yaml::Hex64> FileSize;
713   std::optional<llvm::yaml::Hex64> MemSize;
714   std::optional<llvm::yaml::Hex64> Offset;
715   std::optional<StringRef> FirstSec;
716   std::optional<StringRef> LastSec;
717 
718   // This vector contains all chunks from [FirstSec, LastSec].
719   std::vector<Chunk *> Chunks;
720 };
721 
722 struct Object {
723   FileHeader Header;
724   std::vector<ProgramHeader> ProgramHeaders;
725 
726   // An object might contain output section descriptions as well as
727   // custom data that does not belong to any section.
728   std::vector<std::unique_ptr<Chunk>> Chunks;
729 
730   // Although in reality the symbols reside in a section, it is a lot
731   // cleaner and nicer if we read them from the YAML as a separate
732   // top-level key, which automatically ensures that invariants like there
733   // being a single SHT_SYMTAB section are upheld.
734   std::optional<std::vector<Symbol>> Symbols;
735   std::optional<std::vector<Symbol>> DynamicSymbols;
736   std::optional<DWARFYAML::Data> DWARF;
737 
getSectionsObject738   std::vector<Section *> getSections() {
739     std::vector<Section *> Ret;
740     for (const std::unique_ptr<Chunk> &Sec : Chunks)
741       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
742         Ret.push_back(S);
743     return Ret;
744   }
745 
getSectionHeaderTableObject746   const SectionHeaderTable &getSectionHeaderTable() const {
747     for (const std::unique_ptr<Chunk> &C : Chunks)
748       if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
749         return *S;
750     llvm_unreachable("the section header table chunk must always be present");
751   }
752 
753   ELF_ELFOSABI getOSAbi() const;
754   unsigned getMachine() const;
755 };
756 
757 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
758                              const NoBitsSection &S);
759 
760 } // end namespace ELFYAML
761 } // end namespace llvm
762 
763 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)764 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
765 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
766 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
767 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
768 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
769 LLVM_YAML_IS_SEQUENCE_VECTOR(
770     llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
771 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
772 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
773 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
774 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
775 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
776 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
777 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
778 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
779 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
780 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
781 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
782 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
783 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
784 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
785 
786 namespace llvm {
787 namespace yaml {
788 
789 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
790   static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
791                      raw_ostream &Out);
792   static StringRef input(StringRef Scalar, void *Ctx,
793                          ELFYAML::YAMLIntUInt &Val);
794   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
795 };
796 
797 template <>
798 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
799   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
800 };
801 
802 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
803   static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
804 };
805 
806 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
807   static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
808 };
809 
810 template <>
811 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
812   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
813 };
814 
815 template <>
816 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
817   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
818 };
819 
820 template <>
821 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
822   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
823 };
824 
825 template <>
826 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
827   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
828 };
829 
830 template <>
831 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
832   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
833 };
834 
835 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
836   static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
837 };
838 
839 template <>
840 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
841   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
842 };
843 
844 template <>
845 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
846   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
847 };
848 
849 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
850   static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
851 };
852 
853 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
854   static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
855 };
856 
857 template <>
858 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
859   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
860 };
861 
862 template <>
863 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
864   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
865 };
866 
867 template <>
868 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
869   static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
870 };
871 
872 template <>
873 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
874   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
875 };
876 
877 template <>
878 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
879   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
880 };
881 
882 template <>
883 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
884   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
885 };
886 
887 template <>
888 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
889   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
890 };
891 
892 template <>
893 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
894   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
895 };
896 
897 template <>
898 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
899   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
900 };
901 
902 template <>
903 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
904   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
905 };
906 
907 template <>
908 struct MappingTraits<ELFYAML::FileHeader> {
909   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
910 };
911 
912 template <> struct MappingTraits<ELFYAML::SectionHeader> {
913   static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
914 };
915 
916 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
917   static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
918   static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
919 };
920 
921 template <>
922 struct MappingTraits<ELFYAML::Symbol> {
923   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
924   static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
925 };
926 
927 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
928   static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
929 };
930 
931 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
932   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
933 };
934 
935 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
936   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
937 };
938 
939 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
940   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
941 };
942 
943 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
944   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
945 };
946 
947 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
948   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
949 };
950 
951 template <>
952 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
953   static void
954   mapping(IO &IO,
955           ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
956 };
957 
958 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
959   static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
960 };
961 
962 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
963   static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
964 };
965 
966 template <> struct MappingTraits<ELFYAML::NoteEntry> {
967   static void mapping(IO &IO, ELFYAML::NoteEntry &N);
968 };
969 
970 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
971   static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
972 };
973 
974 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
975   static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
976 };
977 
978 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
979   static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
980 };
981 
982 template <> struct MappingTraits<ELFYAML::LinkerOption> {
983   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
984 };
985 
986 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
987   static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
988 };
989 
990 template <> struct MappingTraits<ELFYAML::Relocation> {
991   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
992 };
993 
994 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
995   static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
996 };
997 
998 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
999   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
1000   static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
1001 };
1002 
1003 template <>
1004 struct MappingTraits<ELFYAML::Object> {
1005   static void mapping(IO &IO, ELFYAML::Object &Object);
1006 };
1007 
1008 template <> struct MappingTraits<ELFYAML::SectionOrType> {
1009   static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
1010 };
1011 
1012 } // end namespace yaml
1013 } // end namespace llvm
1014 
1015 #endif // LLVM_OBJECTYAML_ELFYAML_H
1016