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