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 §ionOrType); 314 }; 315 316 } // end namespace yaml 317 } // end namespace llvm 318 319 #endif 320