Home | History | Annotate | Line # | Download | only in ObjectYAML
      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 
    122   Optional<llvm::yaml::Hex64> EPhOff;
    123   Optional<llvm::yaml::Hex16> EPhEntSize;
    124   Optional<llvm::yaml::Hex16> EPhNum;
    125   Optional<llvm::yaml::Hex16> EShEntSize;
    126   Optional<llvm::yaml::Hex64> EShOff;
    127   Optional<llvm::yaml::Hex16> EShNum;
    128   Optional<llvm::yaml::Hex16> EShStrNdx;
    129 };
    130 
    131 struct SectionHeader {
    132   StringRef Name;
    133 };
    134 
    135 struct Symbol {
    136   StringRef Name;
    137   ELF_STT Type;
    138   Optional<StringRef> Section;
    139   Optional<ELF_SHN> Index;
    140   ELF_STB Binding;
    141   Optional<llvm::yaml::Hex64> Value;
    142   Optional<llvm::yaml::Hex64> Size;
    143   Optional<uint8_t> Other;
    144 
    145   Optional<uint32_t> StName;
    146 };
    147 
    148 struct SectionOrType {
    149   StringRef sectionNameOrType;
    150 };
    151 
    152 struct DynamicEntry {
    153   ELF_DYNTAG Tag;
    154   llvm::yaml::Hex64 Val;
    155 };
    156 
    157 struct BBAddrMapEntry {
    158   struct BBEntry {
    159     llvm::yaml::Hex64 AddressOffset;
    160     llvm::yaml::Hex64 Size;
    161     llvm::yaml::Hex64 Metadata;
    162   };
    163   llvm::yaml::Hex64 Address;
    164   Optional<uint64_t> NumBlocks;
    165   Optional<std::vector<BBEntry>> BBEntries;
    166 };
    167 
    168 struct StackSizeEntry {
    169   llvm::yaml::Hex64 Address;
    170   llvm::yaml::Hex64 Size;
    171 };
    172 
    173 struct NoteEntry {
    174   StringRef Name;
    175   yaml::BinaryRef Desc;
    176   ELF_NT Type;
    177 };
    178 
    179 struct Chunk {
    180   enum class ChunkKind {
    181     Dynamic,
    182     Group,
    183     RawContent,
    184     Relocation,
    185     Relr,
    186     NoBits,
    187     Note,
    188     Hash,
    189     GnuHash,
    190     Verdef,
    191     Verneed,
    192     StackSizes,
    193     SymtabShndxSection,
    194     Symver,
    195     ARMIndexTable,
    196     MipsABIFlags,
    197     Addrsig,
    198     LinkerOptions,
    199     DependentLibraries,
    200     CallGraphProfile,
    201     BBAddrMap,
    202 
    203     // Special chunks.
    204     SpecialChunksStart,
    205     Fill = SpecialChunksStart,
    206     SectionHeaderTable,
    207   };
    208 
    209   ChunkKind Kind;
    210   StringRef Name;
    211   Optional<llvm::yaml::Hex64> Offset;
    212 
    213   // Usually chunks are not created implicitly, but rather loaded from YAML.
    214   // This flag is used to signal whether this is the case or not.
    215   bool IsImplicit;
    216 
    217   Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
    218   virtual ~Chunk();
    219 };
    220 
    221 struct Section : public Chunk {
    222   ELF_SHT Type;
    223   Optional<ELF_SHF> Flags;
    224   Optional<llvm::yaml::Hex64> Address;
    225   Optional<StringRef> Link;
    226   llvm::yaml::Hex64 AddressAlign;
    227   Optional<llvm::yaml::Hex64> EntSize;
    228 
    229   Optional<yaml::BinaryRef> Content;
    230   Optional<llvm::yaml::Hex64> Size;
    231 
    232   // Holds the original section index.
    233   unsigned OriginalSecNdx;
    234 
    235   Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
    236 
    237   static bool classof(const Chunk *S) {
    238     return S->Kind < ChunkKind::SpecialChunksStart;
    239   }
    240 
    241   // Some derived sections might have their own special entries. This method
    242   // returns a vector of <entry name, is used> pairs. It is used for section
    243   // validation.
    244   virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
    245     return {};
    246   };
    247 
    248   // The following members are used to override section fields which is
    249   // useful for creating invalid objects.
    250 
    251   // This can be used to override the sh_addralign field.
    252   Optional<llvm::yaml::Hex64> ShAddrAlign;
    253 
    254   // This can be used to override the offset stored in the sh_name field.
    255   // It does not affect the name stored in the string table.
    256   Optional<llvm::yaml::Hex64> ShName;
    257 
    258   // This can be used to override the sh_offset field. It does not place the
    259   // section data at the offset specified.
    260   Optional<llvm::yaml::Hex64> ShOffset;
    261 
    262   // This can be used to override the sh_size field. It does not affect the
    263   // content written.
    264   Optional<llvm::yaml::Hex64> ShSize;
    265 
    266   // This can be used to override the sh_flags field.
    267   Optional<llvm::yaml::Hex64> ShFlags;
    268 
    269   // This can be used to override the sh_type field. It is useful when we
    270   // want to use specific YAML keys for a section of a particular type to
    271   // describe the content, but still want to have a different final type
    272   // for the section.
    273   Optional<ELF_SHT> ShType;
    274 };
    275 
    276 // Fill is a block of data which is placed outside of sections. It is
    277 // not present in the sections header table, but it might affect the output file
    278 // size and program headers produced.
    279 struct Fill : Chunk {
    280   Optional<yaml::BinaryRef> Pattern;
    281   llvm::yaml::Hex64 Size;
    282 
    283   Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
    284 
    285   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
    286 };
    287 
    288 struct SectionHeaderTable : Chunk {
    289   SectionHeaderTable(bool IsImplicit)
    290       : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
    291 
    292   static bool classof(const Chunk *S) {
    293     return S->Kind == ChunkKind::SectionHeaderTable;
    294   }
    295 
    296   Optional<std::vector<SectionHeader>> Sections;
    297   Optional<std::vector<SectionHeader>> Excluded;
    298   Optional<bool> NoHeaders;
    299 
    300   size_t getNumHeaders(size_t SectionsNum) const {
    301     if (IsImplicit || isDefault())
    302       return SectionsNum;
    303     if (NoHeaders)
    304       return (*NoHeaders) ? 0 : SectionsNum;
    305     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
    306   }
    307 
    308   bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
    309 
    310   static constexpr StringRef TypeStr = "SectionHeaderTable";
    311 };
    312 
    313 struct BBAddrMapSection : Section {
    314   Optional<std::vector<BBAddrMapEntry>> Entries;
    315 
    316   BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
    317 
    318   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    319     return {{"Entries", Entries.hasValue()}};
    320   };
    321 
    322   static bool classof(const Chunk *S) {
    323     return S->Kind == ChunkKind::BBAddrMap;
    324   }
    325 };
    326 
    327 struct StackSizesSection : Section {
    328   Optional<std::vector<StackSizeEntry>> Entries;
    329 
    330   StackSizesSection() : Section(ChunkKind::StackSizes) {}
    331 
    332   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    333     return {{"Entries", Entries.hasValue()}};
    334   };
    335 
    336   static bool classof(const Chunk *S) {
    337     return S->Kind == ChunkKind::StackSizes;
    338   }
    339 
    340   static bool nameMatches(StringRef Name) {
    341     return Name == ".stack_sizes";
    342   }
    343 };
    344 
    345 struct DynamicSection : Section {
    346   Optional<std::vector<DynamicEntry>> Entries;
    347 
    348   DynamicSection() : Section(ChunkKind::Dynamic) {}
    349 
    350   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    351     return {{"Entries", Entries.hasValue()}};
    352   };
    353 
    354   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
    355 };
    356 
    357 struct RawContentSection : Section {
    358   Optional<llvm::yaml::Hex64> Info;
    359 
    360   RawContentSection() : Section(ChunkKind::RawContent) {}
    361 
    362   static bool classof(const Chunk *S) {
    363     return S->Kind == ChunkKind::RawContent;
    364   }
    365 
    366   // Is used when a content is read as an array of bytes.
    367   Optional<std::vector<uint8_t>> ContentBuf;
    368 };
    369 
    370 struct NoBitsSection : Section {
    371   NoBitsSection() : Section(ChunkKind::NoBits) {}
    372 
    373   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
    374 };
    375 
    376 struct NoteSection : Section {
    377   Optional<std::vector<ELFYAML::NoteEntry>> Notes;
    378 
    379   NoteSection() : Section(ChunkKind::Note) {}
    380 
    381   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    382     return {{"Notes", Notes.hasValue()}};
    383   };
    384 
    385   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
    386 };
    387 
    388 struct HashSection : Section {
    389   Optional<std::vector<uint32_t>> Bucket;
    390   Optional<std::vector<uint32_t>> Chain;
    391 
    392   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    393     return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
    394   };
    395 
    396   // The following members are used to override section fields.
    397   // This is useful for creating invalid objects.
    398   Optional<llvm::yaml::Hex64> NBucket;
    399   Optional<llvm::yaml::Hex64> NChain;
    400 
    401   HashSection() : Section(ChunkKind::Hash) {}
    402 
    403   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
    404 };
    405 
    406 struct GnuHashHeader {
    407   // The number of hash buckets.
    408   // Not used when dumping the object, but can be used to override
    409   // the real number of buckets when emiting an object from a YAML document.
    410   Optional<llvm::yaml::Hex32> NBuckets;
    411 
    412   // Index of the first symbol in the dynamic symbol table
    413   // included in the hash table.
    414   llvm::yaml::Hex32 SymNdx;
    415 
    416   // The number of words in the Bloom filter.
    417   // Not used when dumping the object, but can be used to override the real
    418   // number of words in the Bloom filter when emiting an object from a YAML
    419   // document.
    420   Optional<llvm::yaml::Hex32> MaskWords;
    421 
    422   // A shift constant used by the Bloom filter.
    423   llvm::yaml::Hex32 Shift2;
    424 };
    425 
    426 struct GnuHashSection : Section {
    427   Optional<GnuHashHeader> Header;
    428   Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
    429   Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
    430   Optional<std::vector<llvm::yaml::Hex32>> HashValues;
    431 
    432   GnuHashSection() : Section(ChunkKind::GnuHash) {}
    433 
    434   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    435     return {{"Header", Header.hasValue()},
    436             {"BloomFilter", BloomFilter.hasValue()},
    437             {"HashBuckets", HashBuckets.hasValue()},
    438             {"HashValues", HashValues.hasValue()}};
    439   };
    440 
    441   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
    442 };
    443 
    444 struct VernauxEntry {
    445   uint32_t Hash;
    446   uint16_t Flags;
    447   uint16_t Other;
    448   StringRef Name;
    449 };
    450 
    451 struct VerneedEntry {
    452   uint16_t Version;
    453   StringRef File;
    454   std::vector<VernauxEntry> AuxV;
    455 };
    456 
    457 struct VerneedSection : Section {
    458   Optional<std::vector<VerneedEntry>> VerneedV;
    459   Optional<llvm::yaml::Hex64> Info;
    460 
    461   VerneedSection() : Section(ChunkKind::Verneed) {}
    462 
    463   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    464     return {{"Dependencies", VerneedV.hasValue()}};
    465   };
    466 
    467   static bool classof(const Chunk *S) {
    468     return S->Kind == ChunkKind::Verneed;
    469   }
    470 };
    471 
    472 struct AddrsigSection : Section {
    473   Optional<std::vector<YAMLFlowString>> Symbols;
    474 
    475   AddrsigSection() : Section(ChunkKind::Addrsig) {}
    476 
    477   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    478     return {{"Symbols", Symbols.hasValue()}};
    479   };
    480 
    481   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
    482 };
    483 
    484 struct LinkerOption {
    485   StringRef Key;
    486   StringRef Value;
    487 };
    488 
    489 struct LinkerOptionsSection : Section {
    490   Optional<std::vector<LinkerOption>> Options;
    491 
    492   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
    493 
    494   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    495     return {{"Options", Options.hasValue()}};
    496   };
    497 
    498   static bool classof(const Chunk *S) {
    499     return S->Kind == ChunkKind::LinkerOptions;
    500   }
    501 };
    502 
    503 struct DependentLibrariesSection : Section {
    504   Optional<std::vector<YAMLFlowString>> Libs;
    505 
    506   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
    507 
    508   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    509     return {{"Libraries", Libs.hasValue()}};
    510   };
    511 
    512   static bool classof(const Chunk *S) {
    513     return S->Kind == ChunkKind::DependentLibraries;
    514   }
    515 };
    516 
    517 // Represents the call graph profile section entry.
    518 struct CallGraphEntry {
    519   // The symbol of the source of the edge.
    520   StringRef From;
    521   // The symbol index of the destination of the edge.
    522   StringRef To;
    523   // The weight of the edge.
    524   uint64_t Weight;
    525 };
    526 
    527 struct CallGraphProfileSection : Section {
    528   Optional<std::vector<CallGraphEntry>> Entries;
    529 
    530   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
    531 
    532   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    533     return {{"Entries", Entries.hasValue()}};
    534   };
    535 
    536   static bool classof(const Chunk *S) {
    537     return S->Kind == ChunkKind::CallGraphProfile;
    538   }
    539 };
    540 
    541 struct SymverSection : Section {
    542   Optional<std::vector<uint16_t>> Entries;
    543 
    544   SymverSection() : Section(ChunkKind::Symver) {}
    545 
    546   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    547     return {{"Entries", Entries.hasValue()}};
    548   };
    549 
    550   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
    551 };
    552 
    553 struct VerdefEntry {
    554   Optional<uint16_t> Version;
    555   Optional<uint16_t> Flags;
    556   Optional<uint16_t> VersionNdx;
    557   Optional<uint32_t> Hash;
    558   std::vector<StringRef> VerNames;
    559 };
    560 
    561 struct VerdefSection : Section {
    562   Optional<std::vector<VerdefEntry>> Entries;
    563   Optional<llvm::yaml::Hex64> Info;
    564 
    565   VerdefSection() : Section(ChunkKind::Verdef) {}
    566 
    567   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    568     return {{"Entries", Entries.hasValue()}};
    569   };
    570 
    571   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
    572 };
    573 
    574 struct GroupSection : Section {
    575   // Members of a group contain a flag and a list of section indices
    576   // that are part of the group.
    577   Optional<std::vector<SectionOrType>> Members;
    578   Optional<StringRef> Signature; /* Info */
    579 
    580   GroupSection() : Section(ChunkKind::Group) {}
    581 
    582   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    583     return {{"Members", Members.hasValue()}};
    584   };
    585 
    586   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
    587 };
    588 
    589 struct Relocation {
    590   llvm::yaml::Hex64 Offset;
    591   YAMLIntUInt Addend;
    592   ELF_REL Type;
    593   Optional<StringRef> Symbol;
    594 };
    595 
    596 struct RelocationSection : Section {
    597   Optional<std::vector<Relocation>> Relocations;
    598   StringRef RelocatableSec; /* Info */
    599 
    600   RelocationSection() : Section(ChunkKind::Relocation) {}
    601 
    602   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    603     return {{"Relocations", Relocations.hasValue()}};
    604   };
    605 
    606   static bool classof(const Chunk *S) {
    607     return S->Kind == ChunkKind::Relocation;
    608   }
    609 };
    610 
    611 struct RelrSection : Section {
    612   Optional<std::vector<llvm::yaml::Hex64>> Entries;
    613 
    614   RelrSection() : Section(ChunkKind::Relr) {}
    615 
    616   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    617     return {{"Entries", Entries.hasValue()}};
    618   };
    619 
    620   static bool classof(const Chunk *S) {
    621     return S->Kind == ChunkKind::Relr;
    622   }
    623 };
    624 
    625 struct SymtabShndxSection : Section {
    626   Optional<std::vector<uint32_t>> Entries;
    627 
    628   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
    629 
    630   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    631     return {{"Entries", Entries.hasValue()}};
    632   };
    633 
    634   static bool classof(const Chunk *S) {
    635     return S->Kind == ChunkKind::SymtabShndxSection;
    636   }
    637 };
    638 
    639 struct ARMIndexTableEntry {
    640   llvm::yaml::Hex32 Offset;
    641   llvm::yaml::Hex32 Value;
    642 };
    643 
    644 struct ARMIndexTableSection : Section {
    645   Optional<std::vector<ARMIndexTableEntry>> Entries;
    646 
    647   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
    648 
    649   std::vector<std::pair<StringRef, bool>> getEntries() const override {
    650     return {{"Entries", Entries.hasValue()}};
    651   };
    652 
    653   static bool classof(const Chunk *S) {
    654     return S->Kind == ChunkKind::ARMIndexTable;
    655   }
    656 };
    657 
    658 // Represents .MIPS.abiflags section
    659 struct MipsABIFlags : Section {
    660   llvm::yaml::Hex16 Version;
    661   MIPS_ISA ISALevel;
    662   llvm::yaml::Hex8 ISARevision;
    663   MIPS_AFL_REG GPRSize;
    664   MIPS_AFL_REG CPR1Size;
    665   MIPS_AFL_REG CPR2Size;
    666   MIPS_ABI_FP FpABI;
    667   MIPS_AFL_EXT ISAExtension;
    668   MIPS_AFL_ASE ASEs;
    669   MIPS_AFL_FLAGS1 Flags1;
    670   llvm::yaml::Hex32 Flags2;
    671 
    672   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
    673 
    674   static bool classof(const Chunk *S) {
    675     return S->Kind == ChunkKind::MipsABIFlags;
    676   }
    677 };
    678 
    679 struct ProgramHeader {
    680   ELF_PT Type;
    681   ELF_PF Flags;
    682   llvm::yaml::Hex64 VAddr;
    683   llvm::yaml::Hex64 PAddr;
    684   Optional<llvm::yaml::Hex64> Align;
    685   Optional<llvm::yaml::Hex64> FileSize;
    686   Optional<llvm::yaml::Hex64> MemSize;
    687   Optional<llvm::yaml::Hex64> Offset;
    688   Optional<StringRef> FirstSec;
    689   Optional<StringRef> LastSec;
    690 
    691   // This vector contains all chunks from [FirstSec, LastSec].
    692   std::vector<Chunk *> Chunks;
    693 };
    694 
    695 struct Object {
    696   FileHeader Header;
    697   std::vector<ProgramHeader> ProgramHeaders;
    698 
    699   // An object might contain output section descriptions as well as
    700   // custom data that does not belong to any section.
    701   std::vector<std::unique_ptr<Chunk>> Chunks;
    702 
    703   // Although in reality the symbols reside in a section, it is a lot
    704   // cleaner and nicer if we read them from the YAML as a separate
    705   // top-level key, which automatically ensures that invariants like there
    706   // being a single SHT_SYMTAB section are upheld.
    707   Optional<std::vector<Symbol>> Symbols;
    708   Optional<std::vector<Symbol>> DynamicSymbols;
    709   Optional<DWARFYAML::Data> DWARF;
    710 
    711   std::vector<Section *> getSections() {
    712     std::vector<Section *> Ret;
    713     for (const std::unique_ptr<Chunk> &Sec : Chunks)
    714       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
    715         Ret.push_back(S);
    716     return Ret;
    717   }
    718 
    719   const SectionHeaderTable &getSectionHeaderTable() const {
    720     for (const std::unique_ptr<Chunk> &C : Chunks)
    721       if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
    722         return *S;
    723     llvm_unreachable("the section header table chunk must always be present");
    724   }
    725 
    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::CallGraphEntry)
    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::CallGraphEntry> {
    935   static void mapping(IO &IO, ELFYAML::CallGraphEntry &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