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