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/BinaryFormat/ELF.h" 20 #include "llvm/Object/ELFTypes.h" 21 #include "llvm/ObjectYAML/DWARFYAML.h" 22 #include "llvm/ObjectYAML/YAML.h" 23 #include "llvm/Support/YAMLTraits.h" 24 #include <cstdint> 25 #include <memory> 26 #include <optional> 27 #include <vector> 28 29 namespace llvm { 30 namespace ELFYAML { 31 32 StringRef dropUniqueSuffix(StringRef S); 33 std::string appendUniqueSuffix(StringRef Name, const Twine& Msg); 34 35 // These types are invariant across 32/64-bit ELF, so for simplicity just 36 // directly give them their exact sizes. We don't need to worry about 37 // endianness because these are just the types in the YAMLIO structures, 38 // and are appropriately converted to the necessary endianness when 39 // reading/generating binary object files. 40 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is 41 // the common prefix of the respective constants. E.g. ELF_EM corresponds 42 // to the `e_machine` constants, like `EM_X86_64`. 43 // In the future, these would probably be better suited by C++11 enum 44 // class's with appropriate fixed underlying type. 45 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET) 46 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT) 47 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM) 48 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS) 49 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA) 50 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI) 51 // Just use 64, since it can hold 32-bit values too. 52 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF) 53 // Just use 64, since it can hold 32-bit values too. 54 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG) 55 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF) 56 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) 57 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL) 58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS) 59 // Just use 64, since it can hold 32-bit values too. 60 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF) 61 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN) 62 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB) 63 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) 64 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT) 65 66 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) 67 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) 68 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) 69 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) 70 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) 71 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA) 72 73 LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString) 74 LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt) 75 76 template <class ELFT> 77 unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType, 78 StringRef SecName) { 79 if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS) 80 return sizeof(object::Elf_Mips_ABIFlags<ELFT>); 81 82 switch (SecType) { 83 case ELF::SHT_SYMTAB: 84 case ELF::SHT_DYNSYM: 85 return sizeof(typename ELFT::Sym); 86 case ELF::SHT_GROUP: 87 return sizeof(typename ELFT::Word); 88 case ELF::SHT_REL: 89 return sizeof(typename ELFT::Rel); 90 case ELF::SHT_RELA: 91 return sizeof(typename ELFT::Rela); 92 case ELF::SHT_RELR: 93 return sizeof(typename ELFT::Relr); 94 case ELF::SHT_DYNAMIC: 95 return sizeof(typename ELFT::Dyn); 96 case ELF::SHT_HASH: 97 return sizeof(typename ELFT::Word); 98 case ELF::SHT_SYMTAB_SHNDX: 99 return sizeof(typename ELFT::Word); 100 case ELF::SHT_GNU_versym: 101 return sizeof(typename ELFT::Half); 102 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 103 return sizeof(object::Elf_CGProfile_Impl<ELFT>); 104 default: 105 if (SecName == ".debug_str") 106 return 1; 107 return 0; 108 } 109 } 110 111 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed 112 // since 64-bit can hold 32-bit values too. 113 struct FileHeader { 114 ELF_ELFCLASS Class; 115 ELF_ELFDATA Data; 116 ELF_ELFOSABI OSABI; 117 llvm::yaml::Hex8 ABIVersion; 118 ELF_ET Type; 119 std::optional<ELF_EM> Machine; 120 ELF_EF Flags; 121 llvm::yaml::Hex64 Entry; 122 std::optional<StringRef> SectionHeaderStringTable; 123 124 std::optional<llvm::yaml::Hex64> EPhOff; 125 std::optional<llvm::yaml::Hex16> EPhEntSize; 126 std::optional<llvm::yaml::Hex16> EPhNum; 127 std::optional<llvm::yaml::Hex16> EShEntSize; 128 std::optional<llvm::yaml::Hex64> EShOff; 129 std::optional<llvm::yaml::Hex16> EShNum; 130 std::optional<llvm::yaml::Hex16> EShStrNdx; 131 }; 132 133 struct SectionHeader { 134 StringRef Name; 135 }; 136 137 struct Symbol { 138 StringRef Name; 139 ELF_STT Type; 140 std::optional<StringRef> Section; 141 std::optional<ELF_SHN> Index; 142 ELF_STB Binding; 143 std::optional<llvm::yaml::Hex64> Value; 144 std::optional<llvm::yaml::Hex64> Size; 145 std::optional<uint8_t> Other; 146 147 std::optional<uint32_t> StName; 148 }; 149 150 struct SectionOrType { 151 StringRef sectionNameOrType; 152 }; 153 154 struct DynamicEntry { 155 ELF_DYNTAG Tag; 156 llvm::yaml::Hex64 Val; 157 }; 158 159 struct BBAddrMapEntry { 160 struct BBEntry { 161 uint32_t ID; 162 llvm::yaml::Hex64 AddressOffset; 163 llvm::yaml::Hex64 Size; 164 llvm::yaml::Hex64 Metadata; 165 }; 166 uint8_t Version; 167 llvm::yaml::Hex8 Feature; 168 llvm::yaml::Hex64 Address; 169 std::optional<uint64_t> NumBlocks; 170 std::optional<std::vector<BBEntry>> BBEntries; 171 }; 172 173 struct StackSizeEntry { 174 llvm::yaml::Hex64 Address; 175 llvm::yaml::Hex64 Size; 176 }; 177 178 struct NoteEntry { 179 StringRef Name; 180 yaml::BinaryRef Desc; 181 ELF_NT Type; 182 }; 183 184 struct Chunk { 185 enum class ChunkKind { 186 Dynamic, 187 Group, 188 RawContent, 189 Relocation, 190 Relr, 191 NoBits, 192 Note, 193 Hash, 194 GnuHash, 195 Verdef, 196 Verneed, 197 StackSizes, 198 SymtabShndxSection, 199 Symver, 200 ARMIndexTable, 201 MipsABIFlags, 202 Addrsig, 203 LinkerOptions, 204 DependentLibraries, 205 CallGraphProfile, 206 BBAddrMap, 207 208 // Special chunks. 209 SpecialChunksStart, 210 Fill = SpecialChunksStart, 211 SectionHeaderTable, 212 }; 213 214 ChunkKind Kind; 215 StringRef Name; 216 std::optional<llvm::yaml::Hex64> Offset; 217 218 // Usually chunks are not created implicitly, but rather loaded from YAML. 219 // This flag is used to signal whether this is the case or not. 220 bool IsImplicit; 221 222 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {} 223 virtual ~Chunk(); 224 }; 225 226 struct Section : public Chunk { 227 ELF_SHT Type; 228 std::optional<ELF_SHF> Flags; 229 std::optional<llvm::yaml::Hex64> Address; 230 std::optional<StringRef> Link; 231 llvm::yaml::Hex64 AddressAlign; 232 std::optional<llvm::yaml::Hex64> EntSize; 233 234 std::optional<yaml::BinaryRef> Content; 235 std::optional<llvm::yaml::Hex64> Size; 236 237 // Holds the original section index. 238 unsigned OriginalSecNdx; 239 240 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {} 241 242 static bool classof(const Chunk *S) { 243 return S->Kind < ChunkKind::SpecialChunksStart; 244 } 245 246 // Some derived sections might have their own special entries. This method 247 // returns a vector of <entry name, is used> pairs. It is used for section 248 // validation. 249 virtual std::vector<std::pair<StringRef, bool>> getEntries() const { 250 return {}; 251 }; 252 253 // The following members are used to override section fields which is 254 // useful for creating invalid objects. 255 256 // This can be used to override the sh_addralign field. 257 std::optional<llvm::yaml::Hex64> ShAddrAlign; 258 259 // This can be used to override the offset stored in the sh_name field. 260 // It does not affect the name stored in the string table. 261 std::optional<llvm::yaml::Hex64> ShName; 262 263 // This can be used to override the sh_offset field. It does not place the 264 // section data at the offset specified. 265 std::optional<llvm::yaml::Hex64> ShOffset; 266 267 // This can be used to override the sh_size field. It does not affect the 268 // content written. 269 std::optional<llvm::yaml::Hex64> ShSize; 270 271 // This can be used to override the sh_flags field. 272 std::optional<llvm::yaml::Hex64> ShFlags; 273 274 // This can be used to override the sh_type field. It is useful when we 275 // want to use specific YAML keys for a section of a particular type to 276 // describe the content, but still want to have a different final type 277 // for the section. 278 std::optional<ELF_SHT> ShType; 279 }; 280 281 // Fill is a block of data which is placed outside of sections. It is 282 // not present in the sections header table, but it might affect the output file 283 // size and program headers produced. 284 struct Fill : Chunk { 285 std::optional<yaml::BinaryRef> Pattern; 286 llvm::yaml::Hex64 Size; 287 288 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {} 289 290 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; } 291 }; 292 293 struct SectionHeaderTable : Chunk { 294 SectionHeaderTable(bool IsImplicit) 295 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {} 296 297 static bool classof(const Chunk *S) { 298 return S->Kind == ChunkKind::SectionHeaderTable; 299 } 300 301 std::optional<std::vector<SectionHeader>> Sections; 302 std::optional<std::vector<SectionHeader>> Excluded; 303 std::optional<bool> NoHeaders; 304 305 size_t getNumHeaders(size_t SectionsNum) const { 306 if (IsImplicit || isDefault()) 307 return SectionsNum; 308 if (NoHeaders) 309 return (*NoHeaders) ? 0 : SectionsNum; 310 return (Sections ? Sections->size() : 0) + /*Null section*/ 1; 311 } 312 313 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; } 314 315 static constexpr StringRef TypeStr = "SectionHeaderTable"; 316 }; 317 318 struct BBAddrMapSection : Section { 319 std::optional<std::vector<BBAddrMapEntry>> Entries; 320 321 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {} 322 323 std::vector<std::pair<StringRef, bool>> getEntries() const override { 324 return {{"Entries", Entries.has_value()}}; 325 }; 326 327 static bool classof(const Chunk *S) { 328 return S->Kind == ChunkKind::BBAddrMap; 329 } 330 }; 331 332 struct StackSizesSection : Section { 333 std::optional<std::vector<StackSizeEntry>> Entries; 334 335 StackSizesSection() : Section(ChunkKind::StackSizes) {} 336 337 std::vector<std::pair<StringRef, bool>> getEntries() const override { 338 return {{"Entries", Entries.has_value()}}; 339 }; 340 341 static bool classof(const Chunk *S) { 342 return S->Kind == ChunkKind::StackSizes; 343 } 344 345 static bool nameMatches(StringRef Name) { 346 return Name == ".stack_sizes"; 347 } 348 }; 349 350 struct DynamicSection : Section { 351 std::optional<std::vector<DynamicEntry>> Entries; 352 353 DynamicSection() : Section(ChunkKind::Dynamic) {} 354 355 std::vector<std::pair<StringRef, bool>> getEntries() const override { 356 return {{"Entries", Entries.has_value()}}; 357 }; 358 359 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; } 360 }; 361 362 struct RawContentSection : Section { 363 std::optional<llvm::yaml::Hex64> Info; 364 365 RawContentSection() : Section(ChunkKind::RawContent) {} 366 367 static bool classof(const Chunk *S) { 368 return S->Kind == ChunkKind::RawContent; 369 } 370 371 // Is used when a content is read as an array of bytes. 372 std::optional<std::vector<uint8_t>> ContentBuf; 373 }; 374 375 struct NoBitsSection : Section { 376 NoBitsSection() : Section(ChunkKind::NoBits) {} 377 378 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; } 379 }; 380 381 struct NoteSection : Section { 382 std::optional<std::vector<ELFYAML::NoteEntry>> Notes; 383 384 NoteSection() : Section(ChunkKind::Note) {} 385 386 std::vector<std::pair<StringRef, bool>> getEntries() const override { 387 return {{"Notes", Notes.has_value()}}; 388 }; 389 390 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; } 391 }; 392 393 struct HashSection : Section { 394 std::optional<std::vector<uint32_t>> Bucket; 395 std::optional<std::vector<uint32_t>> Chain; 396 397 std::vector<std::pair<StringRef, bool>> getEntries() const override { 398 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}}; 399 }; 400 401 // The following members are used to override section fields. 402 // This is useful for creating invalid objects. 403 std::optional<llvm::yaml::Hex64> NBucket; 404 std::optional<llvm::yaml::Hex64> NChain; 405 406 HashSection() : Section(ChunkKind::Hash) {} 407 408 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; } 409 }; 410 411 struct GnuHashHeader { 412 // The number of hash buckets. 413 // Not used when dumping the object, but can be used to override 414 // the real number of buckets when emiting an object from a YAML document. 415 std::optional<llvm::yaml::Hex32> NBuckets; 416 417 // Index of the first symbol in the dynamic symbol table 418 // included in the hash table. 419 llvm::yaml::Hex32 SymNdx; 420 421 // The number of words in the Bloom filter. 422 // Not used when dumping the object, but can be used to override the real 423 // number of words in the Bloom filter when emiting an object from a YAML 424 // document. 425 std::optional<llvm::yaml::Hex32> MaskWords; 426 427 // A shift constant used by the Bloom filter. 428 llvm::yaml::Hex32 Shift2; 429 }; 430 431 struct GnuHashSection : Section { 432 std::optional<GnuHashHeader> Header; 433 std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter; 434 std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets; 435 std::optional<std::vector<llvm::yaml::Hex32>> HashValues; 436 437 GnuHashSection() : Section(ChunkKind::GnuHash) {} 438 439 std::vector<std::pair<StringRef, bool>> getEntries() const override { 440 return {{"Header", Header.has_value()}, 441 {"BloomFilter", BloomFilter.has_value()}, 442 {"HashBuckets", HashBuckets.has_value()}, 443 {"HashValues", HashValues.has_value()}}; 444 }; 445 446 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; } 447 }; 448 449 struct VernauxEntry { 450 uint32_t Hash; 451 uint16_t Flags; 452 uint16_t Other; 453 StringRef Name; 454 }; 455 456 struct VerneedEntry { 457 uint16_t Version; 458 StringRef File; 459 std::vector<VernauxEntry> AuxV; 460 }; 461 462 struct VerneedSection : Section { 463 std::optional<std::vector<VerneedEntry>> VerneedV; 464 std::optional<llvm::yaml::Hex64> Info; 465 466 VerneedSection() : Section(ChunkKind::Verneed) {} 467 468 std::vector<std::pair<StringRef, bool>> getEntries() const override { 469 return {{"Dependencies", VerneedV.has_value()}}; 470 }; 471 472 static bool classof(const Chunk *S) { 473 return S->Kind == ChunkKind::Verneed; 474 } 475 }; 476 477 struct AddrsigSection : Section { 478 std::optional<std::vector<YAMLFlowString>> Symbols; 479 480 AddrsigSection() : Section(ChunkKind::Addrsig) {} 481 482 std::vector<std::pair<StringRef, bool>> getEntries() const override { 483 return {{"Symbols", Symbols.has_value()}}; 484 }; 485 486 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; } 487 }; 488 489 struct LinkerOption { 490 StringRef Key; 491 StringRef Value; 492 }; 493 494 struct LinkerOptionsSection : Section { 495 std::optional<std::vector<LinkerOption>> Options; 496 497 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {} 498 499 std::vector<std::pair<StringRef, bool>> getEntries() const override { 500 return {{"Options", Options.has_value()}}; 501 }; 502 503 static bool classof(const Chunk *S) { 504 return S->Kind == ChunkKind::LinkerOptions; 505 } 506 }; 507 508 struct DependentLibrariesSection : Section { 509 std::optional<std::vector<YAMLFlowString>> Libs; 510 511 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {} 512 513 std::vector<std::pair<StringRef, bool>> getEntries() const override { 514 return {{"Libraries", Libs.has_value()}}; 515 }; 516 517 static bool classof(const Chunk *S) { 518 return S->Kind == ChunkKind::DependentLibraries; 519 } 520 }; 521 522 // Represents the call graph profile section entry. 523 struct CallGraphEntryWeight { 524 // The weight of the edge. 525 uint64_t Weight; 526 }; 527 528 struct CallGraphProfileSection : Section { 529 std::optional<std::vector<CallGraphEntryWeight>> Entries; 530 531 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {} 532 533 std::vector<std::pair<StringRef, bool>> getEntries() const override { 534 return {{"Entries", Entries.has_value()}}; 535 }; 536 537 static bool classof(const Chunk *S) { 538 return S->Kind == ChunkKind::CallGraphProfile; 539 } 540 }; 541 542 struct SymverSection : Section { 543 std::optional<std::vector<uint16_t>> Entries; 544 545 SymverSection() : Section(ChunkKind::Symver) {} 546 547 std::vector<std::pair<StringRef, bool>> getEntries() const override { 548 return {{"Entries", Entries.has_value()}}; 549 }; 550 551 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; } 552 }; 553 554 struct VerdefEntry { 555 std::optional<uint16_t> Version; 556 std::optional<uint16_t> Flags; 557 std::optional<uint16_t> VersionNdx; 558 std::optional<uint32_t> Hash; 559 std::vector<StringRef> VerNames; 560 }; 561 562 struct VerdefSection : Section { 563 std::optional<std::vector<VerdefEntry>> Entries; 564 std::optional<llvm::yaml::Hex64> Info; 565 566 VerdefSection() : Section(ChunkKind::Verdef) {} 567 568 std::vector<std::pair<StringRef, bool>> getEntries() const override { 569 return {{"Entries", Entries.has_value()}}; 570 }; 571 572 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; } 573 }; 574 575 struct GroupSection : Section { 576 // Members of a group contain a flag and a list of section indices 577 // that are part of the group. 578 std::optional<std::vector<SectionOrType>> Members; 579 std::optional<StringRef> Signature; /* Info */ 580 581 GroupSection() : Section(ChunkKind::Group) {} 582 583 std::vector<std::pair<StringRef, bool>> getEntries() const override { 584 return {{"Members", Members.has_value()}}; 585 }; 586 587 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; } 588 }; 589 590 struct Relocation { 591 llvm::yaml::Hex64 Offset; 592 YAMLIntUInt Addend; 593 ELF_REL Type; 594 std::optional<StringRef> Symbol; 595 }; 596 597 struct RelocationSection : Section { 598 std::optional<std::vector<Relocation>> Relocations; 599 StringRef RelocatableSec; /* Info */ 600 601 RelocationSection() : Section(ChunkKind::Relocation) {} 602 603 std::vector<std::pair<StringRef, bool>> getEntries() const override { 604 return {{"Relocations", Relocations.has_value()}}; 605 }; 606 607 static bool classof(const Chunk *S) { 608 return S->Kind == ChunkKind::Relocation; 609 } 610 }; 611 612 struct RelrSection : Section { 613 std::optional<std::vector<llvm::yaml::Hex64>> Entries; 614 615 RelrSection() : Section(ChunkKind::Relr) {} 616 617 std::vector<std::pair<StringRef, bool>> getEntries() const override { 618 return {{"Entries", Entries.has_value()}}; 619 }; 620 621 static bool classof(const Chunk *S) { 622 return S->Kind == ChunkKind::Relr; 623 } 624 }; 625 626 struct SymtabShndxSection : Section { 627 std::optional<std::vector<uint32_t>> Entries; 628 629 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {} 630 631 std::vector<std::pair<StringRef, bool>> getEntries() const override { 632 return {{"Entries", Entries.has_value()}}; 633 }; 634 635 static bool classof(const Chunk *S) { 636 return S->Kind == ChunkKind::SymtabShndxSection; 637 } 638 }; 639 640 struct ARMIndexTableEntry { 641 llvm::yaml::Hex32 Offset; 642 llvm::yaml::Hex32 Value; 643 }; 644 645 struct ARMIndexTableSection : Section { 646 std::optional<std::vector<ARMIndexTableEntry>> Entries; 647 648 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {} 649 650 std::vector<std::pair<StringRef, bool>> getEntries() const override { 651 return {{"Entries", Entries.has_value()}}; 652 }; 653 654 static bool classof(const Chunk *S) { 655 return S->Kind == ChunkKind::ARMIndexTable; 656 } 657 }; 658 659 // Represents .MIPS.abiflags section 660 struct MipsABIFlags : Section { 661 llvm::yaml::Hex16 Version; 662 MIPS_ISA ISALevel; 663 llvm::yaml::Hex8 ISARevision; 664 MIPS_AFL_REG GPRSize; 665 MIPS_AFL_REG CPR1Size; 666 MIPS_AFL_REG CPR2Size; 667 MIPS_ABI_FP FpABI; 668 MIPS_AFL_EXT ISAExtension; 669 MIPS_AFL_ASE ASEs; 670 MIPS_AFL_FLAGS1 Flags1; 671 llvm::yaml::Hex32 Flags2; 672 673 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {} 674 675 static bool classof(const Chunk *S) { 676 return S->Kind == ChunkKind::MipsABIFlags; 677 } 678 }; 679 680 struct ProgramHeader { 681 ELF_PT Type; 682 ELF_PF Flags; 683 llvm::yaml::Hex64 VAddr; 684 llvm::yaml::Hex64 PAddr; 685 std::optional<llvm::yaml::Hex64> Align; 686 std::optional<llvm::yaml::Hex64> FileSize; 687 std::optional<llvm::yaml::Hex64> MemSize; 688 std::optional<llvm::yaml::Hex64> Offset; 689 std::optional<StringRef> FirstSec; 690 std::optional<StringRef> LastSec; 691 692 // This vector contains all chunks from [FirstSec, LastSec]. 693 std::vector<Chunk *> Chunks; 694 }; 695 696 struct Object { 697 FileHeader Header; 698 std::vector<ProgramHeader> ProgramHeaders; 699 700 // An object might contain output section descriptions as well as 701 // custom data that does not belong to any section. 702 std::vector<std::unique_ptr<Chunk>> Chunks; 703 704 // Although in reality the symbols reside in a section, it is a lot 705 // cleaner and nicer if we read them from the YAML as a separate 706 // top-level key, which automatically ensures that invariants like there 707 // being a single SHT_SYMTAB section are upheld. 708 std::optional<std::vector<Symbol>> Symbols; 709 std::optional<std::vector<Symbol>> DynamicSymbols; 710 std::optional<DWARFYAML::Data> DWARF; 711 712 std::vector<Section *> getSections() { 713 std::vector<Section *> Ret; 714 for (const std::unique_ptr<Chunk> &Sec : Chunks) 715 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get())) 716 Ret.push_back(S); 717 return Ret; 718 } 719 720 const SectionHeaderTable &getSectionHeaderTable() const { 721 for (const std::unique_ptr<Chunk> &C : Chunks) 722 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) 723 return *S; 724 llvm_unreachable("the section header table chunk must always be present"); 725 } 726 727 ELF_ELFOSABI getOSAbi() const; 728 unsigned getMachine() const; 729 }; 730 731 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs, 732 const NoBitsSection &S); 733 734 } // end namespace ELFYAML 735 } // end namespace llvm 736 737 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry) 738 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry) 739 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry) 740 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry) 741 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption) 742 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight) 743 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry) 744 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader) 745 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader) 746 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>) 747 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) 748 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry) 749 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry) 750 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry) 751 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) 752 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType) 753 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry) 754 755 namespace llvm { 756 namespace yaml { 757 758 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> { 759 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx, 760 raw_ostream &Out); 761 static StringRef input(StringRef Scalar, void *Ctx, 762 ELFYAML::YAMLIntUInt &Val); 763 static QuotingType mustQuote(StringRef) { return QuotingType::None; } 764 }; 765 766 template <> 767 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> { 768 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value); 769 }; 770 771 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> { 772 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value); 773 }; 774 775 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> { 776 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value); 777 }; 778 779 template <> 780 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> { 781 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value); 782 }; 783 784 template <> 785 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> { 786 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value); 787 }; 788 789 template <> 790 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> { 791 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value); 792 }; 793 794 template <> 795 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> { 796 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value); 797 }; 798 799 template <> 800 struct ScalarBitSetTraits<ELFYAML::ELF_EF> { 801 static void bitset(IO &IO, ELFYAML::ELF_EF &Value); 802 }; 803 804 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> { 805 static void bitset(IO &IO, ELFYAML::ELF_PF &Value); 806 }; 807 808 template <> 809 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> { 810 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value); 811 }; 812 813 template <> 814 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> { 815 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); 816 }; 817 818 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> { 819 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value); 820 }; 821 822 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> { 823 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value); 824 }; 825 826 template <> 827 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { 828 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); 829 }; 830 831 template <> 832 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> { 833 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); 834 }; 835 836 template <> 837 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> { 838 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value); 839 }; 840 841 template <> 842 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> { 843 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value); 844 }; 845 846 template <> 847 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> { 848 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value); 849 }; 850 851 template <> 852 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> { 853 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value); 854 }; 855 856 template <> 857 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> { 858 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value); 859 }; 860 861 template <> 862 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> { 863 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value); 864 }; 865 866 template <> 867 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> { 868 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value); 869 }; 870 871 template <> 872 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> { 873 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value); 874 }; 875 876 template <> 877 struct MappingTraits<ELFYAML::FileHeader> { 878 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); 879 }; 880 881 template <> struct MappingTraits<ELFYAML::SectionHeader> { 882 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr); 883 }; 884 885 template <> struct MappingTraits<ELFYAML::ProgramHeader> { 886 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr); 887 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr); 888 }; 889 890 template <> 891 struct MappingTraits<ELFYAML::Symbol> { 892 static void mapping(IO &IO, ELFYAML::Symbol &Symbol); 893 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol); 894 }; 895 896 template <> struct MappingTraits<ELFYAML::StackSizeEntry> { 897 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel); 898 }; 899 900 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> { 901 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel); 902 }; 903 904 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> { 905 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel); 906 }; 907 908 template <> struct MappingTraits<ELFYAML::GnuHashHeader> { 909 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel); 910 }; 911 912 template <> struct MappingTraits<ELFYAML::DynamicEntry> { 913 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel); 914 }; 915 916 template <> struct MappingTraits<ELFYAML::NoteEntry> { 917 static void mapping(IO &IO, ELFYAML::NoteEntry &N); 918 }; 919 920 template <> struct MappingTraits<ELFYAML::VerdefEntry> { 921 static void mapping(IO &IO, ELFYAML::VerdefEntry &E); 922 }; 923 924 template <> struct MappingTraits<ELFYAML::VerneedEntry> { 925 static void mapping(IO &IO, ELFYAML::VerneedEntry &E); 926 }; 927 928 template <> struct MappingTraits<ELFYAML::VernauxEntry> { 929 static void mapping(IO &IO, ELFYAML::VernauxEntry &E); 930 }; 931 932 template <> struct MappingTraits<ELFYAML::LinkerOption> { 933 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym); 934 }; 935 936 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> { 937 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E); 938 }; 939 940 template <> struct MappingTraits<ELFYAML::Relocation> { 941 static void mapping(IO &IO, ELFYAML::Relocation &Rel); 942 }; 943 944 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> { 945 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E); 946 }; 947 948 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> { 949 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C); 950 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C); 951 }; 952 953 template <> 954 struct MappingTraits<ELFYAML::Object> { 955 static void mapping(IO &IO, ELFYAML::Object &Object); 956 }; 957 958 template <> struct MappingTraits<ELFYAML::SectionOrType> { 959 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType); 960 }; 961 962 } // end namespace yaml 963 } // end namespace llvm 964 965 #endif // LLVM_OBJECTYAML_ELFYAML_H 966