Home | History | Annotate | Download | only in ObjectYAML
      1 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief This file declares classes for handling the YAML representation
     12 /// of ELF.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_OBJECTYAML_ELFYAML_H
     17 #define LLVM_OBJECTYAML_ELFYAML_H
     18 
     19 #include "llvm/ObjectYAML/YAML.h"
     20 #include "llvm/Support/ELF.h"
     21 
     22 namespace llvm {
     23 namespace ELFYAML {
     24 
     25 // These types are invariant across 32/64-bit ELF, so for simplicity just
     26 // directly give them their exact sizes. We don't need to worry about
     27 // endianness because these are just the types in the YAMLIO structures,
     28 // and are appropriately converted to the necessary endianness when
     29 // reading/generating binary object files.
     30 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
     31 // the common prefix of the respective constants. E.g. ELF_EM corresponds
     32 // to the `e_machine` constants, like `EM_X86_64`.
     33 // In the future, these would probably be better suited by C++11 enum
     34 // class's with appropriate fixed underlying type.
     35 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
     36 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
     37 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
     38 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
     39 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
     40 // Just use 64, since it can hold 32-bit values too.
     41 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
     42 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
     43 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
     44 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
     45 // Just use 64, since it can hold 32-bit values too.
     46 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
     47 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
     48 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
     49 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)
     50 
     51 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
     52 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
     53 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
     54 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
     55 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
     56 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
     57 
     58 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
     59 // since 64-bit can hold 32-bit values too.
     60 struct FileHeader {
     61   ELF_ELFCLASS Class;
     62   ELF_ELFDATA Data;
     63   ELF_ELFOSABI OSABI;
     64   ELF_ET Type;
     65   ELF_EM Machine;
     66   ELF_EF Flags;
     67   llvm::yaml::Hex64 Entry;
     68 };
     69 struct Symbol {
     70   StringRef Name;
     71   ELF_STT Type;
     72   StringRef Section;
     73   llvm::yaml::Hex64 Value;
     74   llvm::yaml::Hex64 Size;
     75   uint8_t Other;
     76 };
     77 struct LocalGlobalWeakSymbols {
     78   std::vector<Symbol> Local;
     79   std::vector<Symbol> Global;
     80   std::vector<Symbol> Weak;
     81 };
     82 
     83 struct SectionOrType {
     84   StringRef sectionNameOrType;
     85 };
     86 
     87 struct Section {
     88   enum class SectionKind {
     89     Group,
     90     RawContent,
     91     Relocation,
     92     NoBits,
     93     MipsABIFlags
     94   };
     95   SectionKind Kind;
     96   StringRef Name;
     97   ELF_SHT Type;
     98   ELF_SHF Flags;
     99   llvm::yaml::Hex64 Address;
    100   StringRef Link;
    101   StringRef Info;
    102   llvm::yaml::Hex64 AddressAlign;
    103   Section(SectionKind Kind) : Kind(Kind) {}
    104   virtual ~Section();
    105 };
    106 struct RawContentSection : Section {
    107   yaml::BinaryRef Content;
    108   llvm::yaml::Hex64 Size;
    109   RawContentSection() : Section(SectionKind::RawContent) {}
    110   static bool classof(const Section *S) {
    111     return S->Kind == SectionKind::RawContent;
    112   }
    113 };
    114 
    115 struct NoBitsSection : Section {
    116   llvm::yaml::Hex64 Size;
    117   NoBitsSection() : Section(SectionKind::NoBits) {}
    118   static bool classof(const Section *S) {
    119     return S->Kind == SectionKind::NoBits;
    120   }
    121 };
    122 
    123 struct Group : Section {
    124   // Members of a group contain a flag and a list of section indices
    125   // that are part of the group.
    126   std::vector<SectionOrType> Members;
    127   Group() : Section(SectionKind::Group) {}
    128   static bool classof(const Section *S) {
    129     return S->Kind == SectionKind::Group;
    130   }
    131 };
    132 
    133 struct Relocation {
    134   llvm::yaml::Hex64 Offset;
    135   int64_t Addend;
    136   ELF_REL Type;
    137   StringRef Symbol;
    138 };
    139 struct RelocationSection : Section {
    140   std::vector<Relocation> Relocations;
    141   RelocationSection() : Section(SectionKind::Relocation) {}
    142   static bool classof(const Section *S) {
    143     return S->Kind == SectionKind::Relocation;
    144   }
    145 };
    146 
    147 // Represents .MIPS.abiflags section
    148 struct MipsABIFlags : Section {
    149   llvm::yaml::Hex16 Version;
    150   MIPS_ISA ISALevel;
    151   llvm::yaml::Hex8 ISARevision;
    152   MIPS_AFL_REG GPRSize;
    153   MIPS_AFL_REG CPR1Size;
    154   MIPS_AFL_REG CPR2Size;
    155   MIPS_ABI_FP FpABI;
    156   MIPS_AFL_EXT ISAExtension;
    157   MIPS_AFL_ASE ASEs;
    158   MIPS_AFL_FLAGS1 Flags1;
    159   llvm::yaml::Hex32 Flags2;
    160   MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
    161   static bool classof(const Section *S) {
    162     return S->Kind == SectionKind::MipsABIFlags;
    163   }
    164 };
    165 
    166 struct Object {
    167   FileHeader Header;
    168   std::vector<std::unique_ptr<Section>> Sections;
    169   // Although in reality the symbols reside in a section, it is a lot
    170   // cleaner and nicer if we read them from the YAML as a separate
    171   // top-level key, which automatically ensures that invariants like there
    172   // being a single SHT_SYMTAB section are upheld.
    173   LocalGlobalWeakSymbols Symbols;
    174 };
    175 
    176 } // end namespace ELFYAML
    177 } // end namespace llvm
    178 
    179 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
    180 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
    181 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
    182 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
    183 
    184 namespace llvm {
    185 namespace yaml {
    186 
    187 template <>
    188 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
    189   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
    190 };
    191 
    192 template <>
    193 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
    194   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
    195 };
    196 
    197 template <>
    198 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
    199   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
    200 };
    201 
    202 template <>
    203 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
    204   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
    205 };
    206 
    207 template <>
    208 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
    209   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
    210 };
    211 
    212 template <>
    213 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
    214   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
    215 };
    216 
    217 template <>
    218 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
    219   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
    220 };
    221 
    222 template <>
    223 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
    224   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
    225 };
    226 
    227 template <>
    228 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
    229   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
    230 };
    231 
    232 template <>
    233 struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
    234   static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
    235 };
    236 
    237 template <>
    238 struct ScalarBitSetTraits<ELFYAML::ELF_STO> {
    239   static void bitset(IO &IO, ELFYAML::ELF_STO &Value);
    240 };
    241 
    242 template <>
    243 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
    244   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
    245 };
    246 
    247 template <>
    248 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
    249   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
    250 };
    251 
    252 template <>
    253 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
    254   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
    255 };
    256 
    257 template <>
    258 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
    259   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
    260 };
    261 
    262 template <>
    263 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
    264   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
    265 };
    266 
    267 template <>
    268 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
    269   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
    270 };
    271 
    272 template <>
    273 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
    274   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
    275 };
    276 
    277 template <>
    278 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
    279   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
    280 };
    281 
    282 template <>
    283 struct MappingTraits<ELFYAML::FileHeader> {
    284   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
    285 };
    286 
    287 template <>
    288 struct MappingTraits<ELFYAML::Symbol> {
    289   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
    290 };
    291 
    292 template <>
    293 struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
    294   static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
    295 };
    296 
    297 template <> struct MappingTraits<ELFYAML::Relocation> {
    298   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
    299 };
    300 
    301 template <>
    302 struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
    303   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
    304   static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
    305 };
    306 
    307 template <>
    308 struct MappingTraits<ELFYAML::Object> {
    309   static void mapping(IO &IO, ELFYAML::Object &Object);
    310 };
    311 
    312 template <> struct MappingTraits<ELFYAML::SectionOrType> {
    313   static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
    314 };
    315 
    316 } // end namespace yaml
    317 } // end namespace llvm
    318 
    319 #endif
    320