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