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