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