1 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file declares classes for handling the YAML representation 11 /// of ELF. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_OBJECTYAML_ELFYAML_H 16 #define LLVM_OBJECTYAML_ELFYAML_H 17 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ObjectYAML/YAML.h" 20 #include "llvm/Support/YAMLTraits.h" 21 #include <cstdint> 22 #include <memory> 23 #include <vector> 24 25 namespace llvm { 26 namespace ELFYAML { 27 28 // These types are invariant across 32/64-bit ELF, so for simplicity just 29 // directly give them their exact sizes. We don't need to worry about 30 // endianness because these are just the types in the YAMLIO structures, 31 // and are appropriately converted to the necessary endianness when 32 // reading/generating binary object files. 33 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is 34 // the common prefix of the respective constants. E.g. ELF_EM corresponds 35 // to the `e_machine` constants, like `EM_X86_64`. 36 // In the future, these would probably be better suited by C++11 enum 37 // class's with appropriate fixed underlying type. 38 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET) 39 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT) 40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM) 41 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS) 42 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA) 43 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI) 44 // Just use 64, since it can hold 32-bit values too. 45 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF) 46 // Just use 64, since it can hold 32-bit values too. 47 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG) 48 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF) 49 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) 50 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL) 51 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS) 52 // Just use 64, since it can hold 32-bit values too. 53 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF) 54 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN) 55 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB) 56 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) 57 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV) 58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO) 59 60 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) 61 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) 62 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) 63 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) 64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) 65 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA) 66 67 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed 68 // since 64-bit can hold 32-bit values too. 69 struct FileHeader { 70 ELF_ELFCLASS Class; 71 ELF_ELFDATA Data; 72 ELF_ELFOSABI OSABI; 73 llvm::yaml::Hex8 ABIVersion; 74 ELF_ET Type; 75 ELF_EM Machine; 76 ELF_EF Flags; 77 llvm::yaml::Hex64 Entry; 78 79 Optional<llvm::yaml::Hex16> SHEntSize; 80 Optional<llvm::yaml::Hex16> SHOffset; 81 Optional<llvm::yaml::Hex16> SHNum; 82 Optional<llvm::yaml::Hex16> SHStrNdx; 83 }; 84 85 struct SectionName { 86 StringRef Section; 87 }; 88 89 struct ProgramHeader { 90 ELF_PT Type; 91 ELF_PF Flags; 92 llvm::yaml::Hex64 VAddr; 93 llvm::yaml::Hex64 PAddr; 94 Optional<llvm::yaml::Hex64> Align; 95 Optional<llvm::yaml::Hex64> FileSize; 96 Optional<llvm::yaml::Hex64> MemSize; 97 Optional<llvm::yaml::Hex64> Offset; 98 std::vector<SectionName> Sections; 99 }; 100 101 struct Symbol { 102 StringRef Name; 103 Optional<uint32_t> NameIndex; 104 ELF_STT Type; 105 StringRef Section; 106 Optional<ELF_SHN> Index; 107 ELF_STB Binding; 108 llvm::yaml::Hex64 Value; 109 llvm::yaml::Hex64 Size; 110 uint8_t Other; 111 }; 112 113 struct SectionOrType { 114 StringRef sectionNameOrType; 115 }; 116 117 struct DynamicEntry { 118 ELF_DYNTAG Tag; 119 llvm::yaml::Hex64 Val; 120 }; 121 122 struct Section { 123 enum class SectionKind { 124 Dynamic, 125 Group, 126 RawContent, 127 Relocation, 128 NoBits, 129 Verdef, 130 Verneed, 131 Symver, 132 MipsABIFlags 133 }; 134 SectionKind Kind; 135 StringRef Name; 136 ELF_SHT Type; 137 Optional<ELF_SHF> Flags; 138 llvm::yaml::Hex64 Address; 139 StringRef Link; 140 llvm::yaml::Hex64 AddressAlign; 141 Optional<llvm::yaml::Hex64> EntSize; 142 143 // This can be used to override the sh_offset field. It does not place the 144 // section data at the offset specified. Useful for creating invalid objects. 145 Optional<llvm::yaml::Hex64> ShOffset; 146 147 // This can be used to override the sh_size field. It does not affect the 148 // content written. 149 Optional<llvm::yaml::Hex64> ShSize; 150 151 Section(SectionKind Kind) : Kind(Kind) {} 152 virtual ~Section(); 153 }; 154 155 struct DynamicSection : Section { 156 std::vector<DynamicEntry> Entries; 157 Optional<yaml::BinaryRef> Content; 158 159 DynamicSection() : Section(SectionKind::Dynamic) {} 160 161 static bool classof(const Section *S) { 162 return S->Kind == SectionKind::Dynamic; 163 } 164 }; 165 166 struct RawContentSection : Section { 167 Optional<yaml::BinaryRef> Content; 168 Optional<llvm::yaml::Hex64> Size; 169 Optional<llvm::yaml::Hex64> Info; 170 171 RawContentSection() : Section(SectionKind::RawContent) {} 172 173 static bool classof(const Section *S) { 174 return S->Kind == SectionKind::RawContent; 175 } 176 }; 177 178 struct NoBitsSection : Section { 179 llvm::yaml::Hex64 Size; 180 181 NoBitsSection() : Section(SectionKind::NoBits) {} 182 183 static bool classof(const Section *S) { 184 return S->Kind == SectionKind::NoBits; 185 } 186 }; 187 188 struct VernauxEntry { 189 uint32_t Hash; 190 uint16_t Flags; 191 uint16_t Other; 192 StringRef Name; 193 }; 194 195 struct VerneedEntry { 196 uint16_t Version; 197 StringRef File; 198 std::vector<VernauxEntry> AuxV; 199 }; 200 201 struct VerneedSection : Section { 202 std::vector<VerneedEntry> VerneedV; 203 llvm::yaml::Hex64 Info; 204 205 VerneedSection() : Section(SectionKind::Verneed) {} 206 207 static bool classof(const Section *S) { 208 return S->Kind == SectionKind::Verneed; 209 } 210 }; 211 212 struct SymverSection : Section { 213 std::vector<uint16_t> Entries; 214 215 SymverSection() : Section(SectionKind::Symver) {} 216 217 static bool classof(const Section *S) { 218 return S->Kind == SectionKind::Symver; 219 } 220 }; 221 222 struct VerdefEntry { 223 uint16_t Version; 224 uint16_t Flags; 225 uint16_t VersionNdx; 226 uint32_t Hash; 227 std::vector<StringRef> VerNames; 228 }; 229 230 struct VerdefSection : Section { 231 std::vector<VerdefEntry> Entries; 232 llvm::yaml::Hex64 Info; 233 234 VerdefSection() : Section(SectionKind::Verdef) {} 235 236 static bool classof(const Section *S) { 237 return S->Kind == SectionKind::Verdef; 238 } 239 }; 240 241 struct Group : Section { 242 // Members of a group contain a flag and a list of section indices 243 // that are part of the group. 244 std::vector<SectionOrType> Members; 245 StringRef Signature; /* Info */ 246 247 Group() : Section(SectionKind::Group) {} 248 249 static bool classof(const Section *S) { 250 return S->Kind == SectionKind::Group; 251 } 252 }; 253 254 struct Relocation { 255 llvm::yaml::Hex64 Offset; 256 int64_t Addend; 257 ELF_REL Type; 258 Optional<StringRef> Symbol; 259 }; 260 261 struct RelocationSection : Section { 262 std::vector<Relocation> Relocations; 263 StringRef RelocatableSec; /* Info */ 264 265 RelocationSection() : Section(SectionKind::Relocation) {} 266 267 static bool classof(const Section *S) { 268 return S->Kind == SectionKind::Relocation; 269 } 270 }; 271 272 // Represents .MIPS.abiflags section 273 struct MipsABIFlags : Section { 274 llvm::yaml::Hex16 Version; 275 MIPS_ISA ISALevel; 276 llvm::yaml::Hex8 ISARevision; 277 MIPS_AFL_REG GPRSize; 278 MIPS_AFL_REG CPR1Size; 279 MIPS_AFL_REG CPR2Size; 280 MIPS_ABI_FP FpABI; 281 MIPS_AFL_EXT ISAExtension; 282 MIPS_AFL_ASE ASEs; 283 MIPS_AFL_FLAGS1 Flags1; 284 llvm::yaml::Hex32 Flags2; 285 286 MipsABIFlags() : Section(SectionKind::MipsABIFlags) {} 287 288 static bool classof(const Section *S) { 289 return S->Kind == SectionKind::MipsABIFlags; 290 } 291 }; 292 293 struct Object { 294 FileHeader Header; 295 std::vector<ProgramHeader> ProgramHeaders; 296 std::vector<std::unique_ptr<Section>> Sections; 297 // Although in reality the symbols reside in a section, it is a lot 298 // cleaner and nicer if we read them from the YAML as a separate 299 // top-level key, which automatically ensures that invariants like there 300 // being a single SHT_SYMTAB section are upheld. 301 std::vector<Symbol> Symbols; 302 std::vector<Symbol> DynamicSymbols; 303 }; 304 305 } // end namespace ELFYAML 306 } // end namespace llvm 307 308 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry) 309 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader) 310 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>) 311 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) 312 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry) 313 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry) 314 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry) 315 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) 316 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType) 317 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName) 318 319 namespace llvm { 320 namespace yaml { 321 322 template <> 323 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> { 324 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value); 325 }; 326 327 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> { 328 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value); 329 }; 330 331 template <> 332 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> { 333 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value); 334 }; 335 336 template <> 337 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> { 338 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value); 339 }; 340 341 template <> 342 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> { 343 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value); 344 }; 345 346 template <> 347 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> { 348 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value); 349 }; 350 351 template <> 352 struct ScalarBitSetTraits<ELFYAML::ELF_EF> { 353 static void bitset(IO &IO, ELFYAML::ELF_EF &Value); 354 }; 355 356 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> { 357 static void bitset(IO &IO, ELFYAML::ELF_PF &Value); 358 }; 359 360 template <> 361 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> { 362 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value); 363 }; 364 365 template <> 366 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> { 367 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); 368 }; 369 370 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> { 371 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value); 372 }; 373 374 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> { 375 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value); 376 }; 377 378 template <> 379 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { 380 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); 381 }; 382 383 template <> 384 struct ScalarEnumerationTraits<ELFYAML::ELF_STV> { 385 static void enumeration(IO &IO, ELFYAML::ELF_STV &Value); 386 }; 387 388 template <> 389 struct ScalarBitSetTraits<ELFYAML::ELF_STO> { 390 static void bitset(IO &IO, ELFYAML::ELF_STO &Value); 391 }; 392 393 template <> 394 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> { 395 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); 396 }; 397 398 template <> 399 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> { 400 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value); 401 }; 402 403 template <> 404 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> { 405 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value); 406 }; 407 408 template <> 409 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> { 410 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value); 411 }; 412 413 template <> 414 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> { 415 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value); 416 }; 417 418 template <> 419 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> { 420 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value); 421 }; 422 423 template <> 424 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> { 425 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value); 426 }; 427 428 template <> 429 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> { 430 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value); 431 }; 432 433 template <> 434 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> { 435 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value); 436 }; 437 438 template <> 439 struct MappingTraits<ELFYAML::FileHeader> { 440 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); 441 }; 442 443 template <> struct MappingTraits<ELFYAML::ProgramHeader> { 444 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr); 445 }; 446 447 template <> 448 struct MappingTraits<ELFYAML::Symbol> { 449 static void mapping(IO &IO, ELFYAML::Symbol &Symbol); 450 static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol); 451 }; 452 453 template <> struct MappingTraits<ELFYAML::DynamicEntry> { 454 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel); 455 }; 456 457 template <> struct MappingTraits<ELFYAML::VerdefEntry> { 458 static void mapping(IO &IO, ELFYAML::VerdefEntry &E); 459 }; 460 461 template <> struct MappingTraits<ELFYAML::VerneedEntry> { 462 static void mapping(IO &IO, ELFYAML::VerneedEntry &E); 463 }; 464 465 template <> struct MappingTraits<ELFYAML::VernauxEntry> { 466 static void mapping(IO &IO, ELFYAML::VernauxEntry &E); 467 }; 468 469 template <> struct MappingTraits<ELFYAML::Relocation> { 470 static void mapping(IO &IO, ELFYAML::Relocation &Rel); 471 }; 472 473 template <> 474 struct MappingTraits<std::unique_ptr<ELFYAML::Section>> { 475 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section); 476 static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section); 477 }; 478 479 template <> 480 struct MappingTraits<ELFYAML::Object> { 481 static void mapping(IO &IO, ELFYAML::Object &Object); 482 }; 483 484 template <> struct MappingTraits<ELFYAML::SectionOrType> { 485 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType); 486 }; 487 488 template <> struct MappingTraits<ELFYAML::SectionName> { 489 static void mapping(IO &IO, ELFYAML::SectionName §ionName); 490 }; 491 492 } // end namespace yaml 493 } // end namespace llvm 494 495 #endif // LLVM_OBJECTYAML_ELFYAML_H 496