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