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 uint8_t Version; 165 llvm::yaml::Hex8 Feature; 166 llvm::yaml::Hex64 Address; 167 Optional<uint64_t> NumBlocks; 168 Optional<std::vector<BBEntry>> BBEntries; 169 }; 170 171 struct StackSizeEntry { 172 llvm::yaml::Hex64 Address; 173 llvm::yaml::Hex64 Size; 174 }; 175 176 struct NoteEntry { 177 StringRef Name; 178 yaml::BinaryRef Desc; 179 ELF_NT Type; 180 }; 181 182 struct Chunk { 183 enum class ChunkKind { 184 Dynamic, 185 Group, 186 RawContent, 187 Relocation, 188 Relr, 189 NoBits, 190 Note, 191 Hash, 192 GnuHash, 193 Verdef, 194 Verneed, 195 StackSizes, 196 SymtabShndxSection, 197 Symver, 198 ARMIndexTable, 199 MipsABIFlags, 200 Addrsig, 201 LinkerOptions, 202 DependentLibraries, 203 CallGraphProfile, 204 BBAddrMap, 205 206 // Special chunks. 207 SpecialChunksStart, 208 Fill = SpecialChunksStart, 209 SectionHeaderTable, 210 }; 211 212 ChunkKind Kind; 213 StringRef Name; 214 Optional<llvm::yaml::Hex64> Offset; 215 216 // Usually chunks are not created implicitly, but rather loaded from YAML. 217 // This flag is used to signal whether this is the case or not. 218 bool IsImplicit; 219 220 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {} 221 virtual ~Chunk(); 222 }; 223 224 struct Section : public Chunk { 225 ELF_SHT Type; 226 Optional<ELF_SHF> Flags; 227 Optional<llvm::yaml::Hex64> Address; 228 Optional<StringRef> Link; 229 llvm::yaml::Hex64 AddressAlign; 230 Optional<llvm::yaml::Hex64> EntSize; 231 232 Optional<yaml::BinaryRef> Content; 233 Optional<llvm::yaml::Hex64> Size; 234 235 // Holds the original section index. 236 unsigned OriginalSecNdx; 237 238 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {} 239 240 static bool classof(const Chunk *S) { 241 return S->Kind < ChunkKind::SpecialChunksStart; 242 } 243 244 // Some derived sections might have their own special entries. This method 245 // returns a vector of <entry name, is used> pairs. It is used for section 246 // validation. 247 virtual std::vector<std::pair<StringRef, bool>> getEntries() const { 248 return {}; 249 }; 250 251 // The following members are used to override section fields which is 252 // useful for creating invalid objects. 253 254 // This can be used to override the sh_addralign field. 255 Optional<llvm::yaml::Hex64> ShAddrAlign; 256 257 // This can be used to override the offset stored in the sh_name field. 258 // It does not affect the name stored in the string table. 259 Optional<llvm::yaml::Hex64> ShName; 260 261 // This can be used to override the sh_offset field. It does not place the 262 // section data at the offset specified. 263 Optional<llvm::yaml::Hex64> ShOffset; 264 265 // This can be used to override the sh_size field. It does not affect the 266 // content written. 267 Optional<llvm::yaml::Hex64> ShSize; 268 269 // This can be used to override the sh_flags field. 270 Optional<llvm::yaml::Hex64> ShFlags; 271 272 // This can be used to override the sh_type field. It is useful when we 273 // want to use specific YAML keys for a section of a particular type to 274 // describe the content, but still want to have a different final type 275 // for the section. 276 Optional<ELF_SHT> ShType; 277 }; 278 279 // Fill is a block of data which is placed outside of sections. It is 280 // not present in the sections header table, but it might affect the output file 281 // size and program headers produced. 282 struct Fill : Chunk { 283 Optional<yaml::BinaryRef> Pattern; 284 llvm::yaml::Hex64 Size; 285 286 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {} 287 288 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; } 289 }; 290 291 struct SectionHeaderTable : Chunk { 292 SectionHeaderTable(bool IsImplicit) 293 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {} 294 295 static bool classof(const Chunk *S) { 296 return S->Kind == ChunkKind::SectionHeaderTable; 297 } 298 299 Optional<std::vector<SectionHeader>> Sections; 300 Optional<std::vector<SectionHeader>> Excluded; 301 Optional<bool> NoHeaders; 302 303 size_t getNumHeaders(size_t SectionsNum) const { 304 if (IsImplicit || isDefault()) 305 return SectionsNum; 306 if (NoHeaders) 307 return (*NoHeaders) ? 0 : SectionsNum; 308 return (Sections ? Sections->size() : 0) + /*Null section*/ 1; 309 } 310 311 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; } 312 313 static constexpr StringRef TypeStr = "SectionHeaderTable"; 314 }; 315 316 struct BBAddrMapSection : Section { 317 Optional<std::vector<BBAddrMapEntry>> Entries; 318 319 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {} 320 321 std::vector<std::pair<StringRef, bool>> getEntries() const override { 322 return {{"Entries", Entries.has_value()}}; 323 }; 324 325 static bool classof(const Chunk *S) { 326 return S->Kind == ChunkKind::BBAddrMap; 327 } 328 }; 329 330 struct StackSizesSection : Section { 331 Optional<std::vector<StackSizeEntry>> Entries; 332 333 StackSizesSection() : Section(ChunkKind::StackSizes) {} 334 335 std::vector<std::pair<StringRef, bool>> getEntries() const override { 336 return {{"Entries", Entries.has_value()}}; 337 }; 338 339 static bool classof(const Chunk *S) { 340 return S->Kind == ChunkKind::StackSizes; 341 } 342 343 static bool nameMatches(StringRef Name) { 344 return Name == ".stack_sizes"; 345 } 346 }; 347 348 struct DynamicSection : Section { 349 Optional<std::vector<DynamicEntry>> Entries; 350 351 DynamicSection() : Section(ChunkKind::Dynamic) {} 352 353 std::vector<std::pair<StringRef, bool>> getEntries() const override { 354 return {{"Entries", Entries.has_value()}}; 355 }; 356 357 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; } 358 }; 359 360 struct RawContentSection : Section { 361 Optional<llvm::yaml::Hex64> Info; 362 363 RawContentSection() : Section(ChunkKind::RawContent) {} 364 365 static bool classof(const Chunk *S) { 366 return S->Kind == ChunkKind::RawContent; 367 } 368 369 // Is used when a content is read as an array of bytes. 370 Optional<std::vector<uint8_t>> ContentBuf; 371 }; 372 373 struct NoBitsSection : Section { 374 NoBitsSection() : Section(ChunkKind::NoBits) {} 375 376 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; } 377 }; 378 379 struct NoteSection : Section { 380 Optional<std::vector<ELFYAML::NoteEntry>> Notes; 381 382 NoteSection() : Section(ChunkKind::Note) {} 383 384 std::vector<std::pair<StringRef, bool>> getEntries() const override { 385 return {{"Notes", Notes.has_value()}}; 386 }; 387 388 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; } 389 }; 390 391 struct HashSection : Section { 392 Optional<std::vector<uint32_t>> Bucket; 393 Optional<std::vector<uint32_t>> Chain; 394 395 std::vector<std::pair<StringRef, bool>> getEntries() const override { 396 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}}; 397 }; 398 399 // The following members are used to override section fields. 400 // This is useful for creating invalid objects. 401 Optional<llvm::yaml::Hex64> NBucket; 402 Optional<llvm::yaml::Hex64> NChain; 403 404 HashSection() : Section(ChunkKind::Hash) {} 405 406 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; } 407 }; 408 409 struct GnuHashHeader { 410 // The number of hash buckets. 411 // Not used when dumping the object, but can be used to override 412 // the real number of buckets when emiting an object from a YAML document. 413 Optional<llvm::yaml::Hex32> NBuckets; 414 415 // Index of the first symbol in the dynamic symbol table 416 // included in the hash table. 417 llvm::yaml::Hex32 SymNdx; 418 419 // The number of words in the Bloom filter. 420 // Not used when dumping the object, but can be used to override the real 421 // number of words in the Bloom filter when emiting an object from a YAML 422 // document. 423 Optional<llvm::yaml::Hex32> MaskWords; 424 425 // A shift constant used by the Bloom filter. 426 llvm::yaml::Hex32 Shift2; 427 }; 428 429 struct GnuHashSection : Section { 430 Optional<GnuHashHeader> Header; 431 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter; 432 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets; 433 Optional<std::vector<llvm::yaml::Hex32>> HashValues; 434 435 GnuHashSection() : Section(ChunkKind::GnuHash) {} 436 437 std::vector<std::pair<StringRef, bool>> getEntries() const override { 438 return {{"Header", Header.has_value()}, 439 {"BloomFilter", BloomFilter.has_value()}, 440 {"HashBuckets", HashBuckets.has_value()}, 441 {"HashValues", HashValues.has_value()}}; 442 }; 443 444 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; } 445 }; 446 447 struct VernauxEntry { 448 uint32_t Hash; 449 uint16_t Flags; 450 uint16_t Other; 451 StringRef Name; 452 }; 453 454 struct VerneedEntry { 455 uint16_t Version; 456 StringRef File; 457 std::vector<VernauxEntry> AuxV; 458 }; 459 460 struct VerneedSection : Section { 461 Optional<std::vector<VerneedEntry>> VerneedV; 462 Optional<llvm::yaml::Hex64> Info; 463 464 VerneedSection() : Section(ChunkKind::Verneed) {} 465 466 std::vector<std::pair<StringRef, bool>> getEntries() const override { 467 return {{"Dependencies", VerneedV.has_value()}}; 468 }; 469 470 static bool classof(const Chunk *S) { 471 return S->Kind == ChunkKind::Verneed; 472 } 473 }; 474 475 struct AddrsigSection : Section { 476 Optional<std::vector<YAMLFlowString>> Symbols; 477 478 AddrsigSection() : Section(ChunkKind::Addrsig) {} 479 480 std::vector<std::pair<StringRef, bool>> getEntries() const override { 481 return {{"Symbols", Symbols.has_value()}}; 482 }; 483 484 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; } 485 }; 486 487 struct LinkerOption { 488 StringRef Key; 489 StringRef Value; 490 }; 491 492 struct LinkerOptionsSection : Section { 493 Optional<std::vector<LinkerOption>> Options; 494 495 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {} 496 497 std::vector<std::pair<StringRef, bool>> getEntries() const override { 498 return {{"Options", Options.has_value()}}; 499 }; 500 501 static bool classof(const Chunk *S) { 502 return S->Kind == ChunkKind::LinkerOptions; 503 } 504 }; 505 506 struct DependentLibrariesSection : Section { 507 Optional<std::vector<YAMLFlowString>> Libs; 508 509 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {} 510 511 std::vector<std::pair<StringRef, bool>> getEntries() const override { 512 return {{"Libraries", Libs.has_value()}}; 513 }; 514 515 static bool classof(const Chunk *S) { 516 return S->Kind == ChunkKind::DependentLibraries; 517 } 518 }; 519 520 // Represents the call graph profile section entry. 521 struct CallGraphEntryWeight { 522 // The weight of the edge. 523 uint64_t Weight; 524 }; 525 526 struct CallGraphProfileSection : Section { 527 Optional<std::vector<CallGraphEntryWeight>> Entries; 528 529 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {} 530 531 std::vector<std::pair<StringRef, bool>> getEntries() const override { 532 return {{"Entries", Entries.has_value()}}; 533 }; 534 535 static bool classof(const Chunk *S) { 536 return S->Kind == ChunkKind::CallGraphProfile; 537 } 538 }; 539 540 struct SymverSection : Section { 541 Optional<std::vector<uint16_t>> Entries; 542 543 SymverSection() : Section(ChunkKind::Symver) {} 544 545 std::vector<std::pair<StringRef, bool>> getEntries() const override { 546 return {{"Entries", Entries.has_value()}}; 547 }; 548 549 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; } 550 }; 551 552 struct VerdefEntry { 553 Optional<uint16_t> Version; 554 Optional<uint16_t> Flags; 555 Optional<uint16_t> VersionNdx; 556 Optional<uint32_t> Hash; 557 std::vector<StringRef> VerNames; 558 }; 559 560 struct VerdefSection : Section { 561 Optional<std::vector<VerdefEntry>> Entries; 562 Optional<llvm::yaml::Hex64> Info; 563 564 VerdefSection() : Section(ChunkKind::Verdef) {} 565 566 std::vector<std::pair<StringRef, bool>> getEntries() const override { 567 return {{"Entries", Entries.has_value()}}; 568 }; 569 570 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; } 571 }; 572 573 struct GroupSection : Section { 574 // Members of a group contain a flag and a list of section indices 575 // that are part of the group. 576 Optional<std::vector<SectionOrType>> Members; 577 Optional<StringRef> Signature; /* Info */ 578 579 GroupSection() : Section(ChunkKind::Group) {} 580 581 std::vector<std::pair<StringRef, bool>> getEntries() const override { 582 return {{"Members", Members.has_value()}}; 583 }; 584 585 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; } 586 }; 587 588 struct Relocation { 589 llvm::yaml::Hex64 Offset; 590 YAMLIntUInt Addend; 591 ELF_REL Type; 592 Optional<StringRef> Symbol; 593 }; 594 595 struct RelocationSection : Section { 596 Optional<std::vector<Relocation>> Relocations; 597 StringRef RelocatableSec; /* Info */ 598 599 RelocationSection() : Section(ChunkKind::Relocation) {} 600 601 std::vector<std::pair<StringRef, bool>> getEntries() const override { 602 return {{"Relocations", Relocations.has_value()}}; 603 }; 604 605 static bool classof(const Chunk *S) { 606 return S->Kind == ChunkKind::Relocation; 607 } 608 }; 609 610 struct RelrSection : Section { 611 Optional<std::vector<llvm::yaml::Hex64>> Entries; 612 613 RelrSection() : Section(ChunkKind::Relr) {} 614 615 std::vector<std::pair<StringRef, bool>> getEntries() const override { 616 return {{"Entries", Entries.has_value()}}; 617 }; 618 619 static bool classof(const Chunk *S) { 620 return S->Kind == ChunkKind::Relr; 621 } 622 }; 623 624 struct SymtabShndxSection : Section { 625 Optional<std::vector<uint32_t>> Entries; 626 627 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {} 628 629 std::vector<std::pair<StringRef, bool>> getEntries() const override { 630 return {{"Entries", Entries.has_value()}}; 631 }; 632 633 static bool classof(const Chunk *S) { 634 return S->Kind == ChunkKind::SymtabShndxSection; 635 } 636 }; 637 638 struct ARMIndexTableEntry { 639 llvm::yaml::Hex32 Offset; 640 llvm::yaml::Hex32 Value; 641 }; 642 643 struct ARMIndexTableSection : Section { 644 Optional<std::vector<ARMIndexTableEntry>> Entries; 645 646 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {} 647 648 std::vector<std::pair<StringRef, bool>> getEntries() const override { 649 return {{"Entries", Entries.has_value()}}; 650 }; 651 652 static bool classof(const Chunk *S) { 653 return S->Kind == ChunkKind::ARMIndexTable; 654 } 655 }; 656 657 // Represents .MIPS.abiflags section 658 struct MipsABIFlags : Section { 659 llvm::yaml::Hex16 Version; 660 MIPS_ISA ISALevel; 661 llvm::yaml::Hex8 ISARevision; 662 MIPS_AFL_REG GPRSize; 663 MIPS_AFL_REG CPR1Size; 664 MIPS_AFL_REG CPR2Size; 665 MIPS_ABI_FP FpABI; 666 MIPS_AFL_EXT ISAExtension; 667 MIPS_AFL_ASE ASEs; 668 MIPS_AFL_FLAGS1 Flags1; 669 llvm::yaml::Hex32 Flags2; 670 671 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {} 672 673 static bool classof(const Chunk *S) { 674 return S->Kind == ChunkKind::MipsABIFlags; 675 } 676 }; 677 678 struct ProgramHeader { 679 ELF_PT Type; 680 ELF_PF Flags; 681 llvm::yaml::Hex64 VAddr; 682 llvm::yaml::Hex64 PAddr; 683 Optional<llvm::yaml::Hex64> Align; 684 Optional<llvm::yaml::Hex64> FileSize; 685 Optional<llvm::yaml::Hex64> MemSize; 686 Optional<llvm::yaml::Hex64> Offset; 687 Optional<StringRef> FirstSec; 688 Optional<StringRef> LastSec; 689 690 // This vector contains all chunks from [FirstSec, LastSec]. 691 std::vector<Chunk *> Chunks; 692 }; 693 694 struct Object { 695 FileHeader Header; 696 std::vector<ProgramHeader> ProgramHeaders; 697 698 // An object might contain output section descriptions as well as 699 // custom data that does not belong to any section. 700 std::vector<std::unique_ptr<Chunk>> Chunks; 701 702 // Although in reality the symbols reside in a section, it is a lot 703 // cleaner and nicer if we read them from the YAML as a separate 704 // top-level key, which automatically ensures that invariants like there 705 // being a single SHT_SYMTAB section are upheld. 706 Optional<std::vector<Symbol>> Symbols; 707 Optional<std::vector<Symbol>> DynamicSymbols; 708 Optional<DWARFYAML::Data> DWARF; 709 710 std::vector<Section *> getSections() { 711 std::vector<Section *> Ret; 712 for (const std::unique_ptr<Chunk> &Sec : Chunks) 713 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get())) 714 Ret.push_back(S); 715 return Ret; 716 } 717 718 const SectionHeaderTable &getSectionHeaderTable() const { 719 for (const std::unique_ptr<Chunk> &C : Chunks) 720 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) 721 return *S; 722 llvm_unreachable("the section header table chunk must always be present"); 723 } 724 725 ELF_ELFOSABI getOSAbi() const; 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::CallGraphEntryWeight) 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::CallGraphEntryWeight> { 935 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &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