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