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