Home | History | Annotate | Download | only in Object
      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_OBJECT_ELFYAML_H
     17 #define LLVM_OBJECT_ELFYAML_H
     18 
     19 #include "llvm/MC/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(uint8_t, ELF_REL)
     44 // Just use 64, since it can hold 32-bit values too.
     45 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
     46 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
     47 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
     48 
     49 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
     50 // since 64-bit can hold 32-bit values too.
     51 struct FileHeader {
     52   ELF_ELFCLASS Class;
     53   ELF_ELFDATA Data;
     54   ELF_ELFOSABI OSABI;
     55   ELF_ET Type;
     56   ELF_EM Machine;
     57   ELF_EF Flags;
     58   llvm::yaml::Hex64 Entry;
     59 };
     60 struct Symbol {
     61   StringRef Name;
     62   ELF_STT Type;
     63   StringRef Section;
     64   llvm::yaml::Hex64 Value;
     65   llvm::yaml::Hex64 Size;
     66   ELF_STV Visibility;
     67 };
     68 struct LocalGlobalWeakSymbols {
     69   std::vector<Symbol> Local;
     70   std::vector<Symbol> Global;
     71   std::vector<Symbol> Weak;
     72 };
     73 struct Section {
     74   enum class SectionKind { RawContent, Relocation };
     75   SectionKind Kind;
     76   StringRef Name;
     77   ELF_SHT Type;
     78   ELF_SHF Flags;
     79   llvm::yaml::Hex64 Address;
     80   StringRef Link;
     81   llvm::yaml::Hex64 AddressAlign;
     82   Section(SectionKind Kind) : Kind(Kind) {}
     83   virtual ~Section();
     84 };
     85 struct RawContentSection : Section {
     86   yaml::BinaryRef Content;
     87   llvm::yaml::Hex64 Size;
     88   RawContentSection() : Section(SectionKind::RawContent) {}
     89   static bool classof(const Section *S) {
     90     return S->Kind == SectionKind::RawContent;
     91   }
     92 };
     93 struct Relocation {
     94   llvm::yaml::Hex64 Offset;
     95   int64_t Addend;
     96   ELF_REL Type;
     97   StringRef Symbol;
     98 };
     99 struct RelocationSection : Section {
    100   StringRef Info;
    101   std::vector<Relocation> Relocations;
    102   RelocationSection() : Section(SectionKind::Relocation) {}
    103   static bool classof(const Section *S) {
    104     return S->Kind == SectionKind::Relocation;
    105   }
    106 };
    107 struct Object {
    108   FileHeader Header;
    109   std::vector<std::unique_ptr<Section>> Sections;
    110   // Although in reality the symbols reside in a section, it is a lot
    111   // cleaner and nicer if we read them from the YAML as a separate
    112   // top-level key, which automatically ensures that invariants like there
    113   // being a single SHT_SYMTAB section are upheld.
    114   LocalGlobalWeakSymbols Symbols;
    115 };
    116 
    117 } // end namespace ELFYAML
    118 } // end namespace llvm
    119 
    120 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
    121 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
    122 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
    123 
    124 namespace llvm {
    125 namespace yaml {
    126 
    127 template <>
    128 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
    129   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
    130 };
    131 
    132 template <>
    133 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
    134   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
    135 };
    136 
    137 template <>
    138 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
    139   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
    140 };
    141 
    142 template <>
    143 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
    144   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
    145 };
    146 
    147 template <>
    148 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
    149   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
    150 };
    151 
    152 template <>
    153 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
    154   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
    155 };
    156 
    157 template <>
    158 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
    159   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
    160 };
    161 
    162 template <>
    163 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
    164   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
    165 };
    166 
    167 template <>
    168 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
    169   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
    170 };
    171 
    172 template <>
    173 struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
    174   static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
    175 };
    176 
    177 template <>
    178 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
    179   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
    180 };
    181 
    182 template <>
    183 struct MappingTraits<ELFYAML::FileHeader> {
    184   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
    185 };
    186 
    187 template <>
    188 struct MappingTraits<ELFYAML::Symbol> {
    189   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
    190 };
    191 
    192 template <>
    193 struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
    194   static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
    195 };
    196 
    197 template <> struct MappingTraits<ELFYAML::Relocation> {
    198   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
    199 };
    200 
    201 template <>
    202 struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
    203   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
    204   static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
    205 };
    206 
    207 template <>
    208 struct MappingTraits<ELFYAML::Object> {
    209   static void mapping(IO &IO, ELFYAML::Object &Object);
    210 };
    211 
    212 } // end namespace yaml
    213 } // end namespace llvm
    214 
    215 #endif
    216