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