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