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