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::optional<uint16_t> VDAux; 586 std::vector<StringRef> VerNames; 587 }; 588 589 struct VerdefSection : Section { 590 std::optional<std::vector<VerdefEntry>> Entries; 591 std::optional<llvm::yaml::Hex64> Info; 592 593 VerdefSection() : Section(ChunkKind::Verdef) {} 594 595 std::vector<std::pair<StringRef, bool>> getEntries() const override { 596 return {{"Entries", Entries.has_value()}}; 597 }; 598 599 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; } 600 }; 601 602 struct GroupSection : Section { 603 // Members of a group contain a flag and a list of section indices 604 // that are part of the group. 605 std::optional<std::vector<SectionOrType>> Members; 606 std::optional<StringRef> Signature; /* Info */ 607 608 GroupSection() : Section(ChunkKind::Group) {} 609 610 std::vector<std::pair<StringRef, bool>> getEntries() const override { 611 return {{"Members", Members.has_value()}}; 612 }; 613 614 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; } 615 }; 616 617 struct Relocation { 618 llvm::yaml::Hex64 Offset; 619 YAMLIntUInt Addend; 620 ELF_REL Type; 621 std::optional<StringRef> Symbol; 622 }; 623 624 struct RelocationSection : Section { 625 std::optional<std::vector<Relocation>> Relocations; 626 StringRef RelocatableSec; /* Info */ 627 628 RelocationSection() : Section(ChunkKind::Relocation) {} 629 630 std::vector<std::pair<StringRef, bool>> getEntries() const override { 631 return {{"Relocations", Relocations.has_value()}}; 632 }; 633 634 static bool classof(const Chunk *S) { 635 return S->Kind == ChunkKind::Relocation; 636 } 637 }; 638 639 struct RelrSection : Section { 640 std::optional<std::vector<llvm::yaml::Hex64>> Entries; 641 642 RelrSection() : Section(ChunkKind::Relr) {} 643 644 std::vector<std::pair<StringRef, bool>> getEntries() const override { 645 return {{"Entries", Entries.has_value()}}; 646 }; 647 648 static bool classof(const Chunk *S) { 649 return S->Kind == ChunkKind::Relr; 650 } 651 }; 652 653 struct SymtabShndxSection : Section { 654 std::optional<std::vector<uint32_t>> Entries; 655 656 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {} 657 658 std::vector<std::pair<StringRef, bool>> getEntries() const override { 659 return {{"Entries", Entries.has_value()}}; 660 }; 661 662 static bool classof(const Chunk *S) { 663 return S->Kind == ChunkKind::SymtabShndxSection; 664 } 665 }; 666 667 struct ARMIndexTableEntry { 668 llvm::yaml::Hex32 Offset; 669 llvm::yaml::Hex32 Value; 670 }; 671 672 struct ARMIndexTableSection : Section { 673 std::optional<std::vector<ARMIndexTableEntry>> Entries; 674 675 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {} 676 677 std::vector<std::pair<StringRef, bool>> getEntries() const override { 678 return {{"Entries", Entries.has_value()}}; 679 }; 680 681 static bool classof(const Chunk *S) { 682 return S->Kind == ChunkKind::ARMIndexTable; 683 } 684 }; 685 686 // Represents .MIPS.abiflags section 687 struct MipsABIFlags : Section { 688 llvm::yaml::Hex16 Version; 689 MIPS_ISA ISALevel; 690 llvm::yaml::Hex8 ISARevision; 691 MIPS_AFL_REG GPRSize; 692 MIPS_AFL_REG CPR1Size; 693 MIPS_AFL_REG CPR2Size; 694 MIPS_ABI_FP FpABI; 695 MIPS_AFL_EXT ISAExtension; 696 MIPS_AFL_ASE ASEs; 697 MIPS_AFL_FLAGS1 Flags1; 698 llvm::yaml::Hex32 Flags2; 699 700 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {} 701 702 static bool classof(const Chunk *S) { 703 return S->Kind == ChunkKind::MipsABIFlags; 704 } 705 }; 706 707 struct ProgramHeader { 708 ELF_PT Type; 709 ELF_PF Flags; 710 llvm::yaml::Hex64 VAddr; 711 llvm::yaml::Hex64 PAddr; 712 std::optional<llvm::yaml::Hex64> Align; 713 std::optional<llvm::yaml::Hex64> FileSize; 714 std::optional<llvm::yaml::Hex64> MemSize; 715 std::optional<llvm::yaml::Hex64> Offset; 716 std::optional<StringRef> FirstSec; 717 std::optional<StringRef> LastSec; 718 719 // This vector contains all chunks from [FirstSec, LastSec]. 720 std::vector<Chunk *> Chunks; 721 }; 722 723 struct Object { 724 FileHeader Header; 725 std::vector<ProgramHeader> ProgramHeaders; 726 727 // An object might contain output section descriptions as well as 728 // custom data that does not belong to any section. 729 std::vector<std::unique_ptr<Chunk>> Chunks; 730 731 // Although in reality the symbols reside in a section, it is a lot 732 // cleaner and nicer if we read them from the YAML as a separate 733 // top-level key, which automatically ensures that invariants like there 734 // being a single SHT_SYMTAB section are upheld. 735 std::optional<std::vector<Symbol>> Symbols; 736 std::optional<std::vector<Symbol>> DynamicSymbols; 737 std::optional<DWARFYAML::Data> DWARF; 738 739 std::vector<Section *> getSections() { 740 std::vector<Section *> Ret; 741 for (const std::unique_ptr<Chunk> &Sec : Chunks) 742 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get())) 743 Ret.push_back(S); 744 return Ret; 745 } 746 747 const SectionHeaderTable &getSectionHeaderTable() const { 748 for (const std::unique_ptr<Chunk> &C : Chunks) 749 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) 750 return *S; 751 llvm_unreachable("the section header table chunk must always be present"); 752 } 753 754 ELF_ELFOSABI getOSAbi() const; 755 unsigned getMachine() const; 756 }; 757 758 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs, 759 const NoBitsSection &S); 760 761 } // end namespace ELFYAML 762 } // end namespace llvm 763 764 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry) 765 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry) 766 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry) 767 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry) 768 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry) 769 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry) 770 LLVM_YAML_IS_SEQUENCE_VECTOR( 771 llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry) 772 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry) 773 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption) 774 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight) 775 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry) 776 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader) 777 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader) 778 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>) 779 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) 780 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry) 781 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry) 782 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry) 783 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) 784 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType) 785 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry) 786 787 namespace llvm { 788 namespace yaml { 789 790 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> { 791 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx, 792 raw_ostream &Out); 793 static StringRef input(StringRef Scalar, void *Ctx, 794 ELFYAML::YAMLIntUInt &Val); 795 static QuotingType mustQuote(StringRef) { return QuotingType::None; } 796 }; 797 798 template <> 799 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> { 800 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value); 801 }; 802 803 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> { 804 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value); 805 }; 806 807 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> { 808 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value); 809 }; 810 811 template <> 812 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> { 813 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value); 814 }; 815 816 template <> 817 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> { 818 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value); 819 }; 820 821 template <> 822 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> { 823 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value); 824 }; 825 826 template <> 827 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> { 828 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value); 829 }; 830 831 template <> 832 struct ScalarBitSetTraits<ELFYAML::ELF_EF> { 833 static void bitset(IO &IO, ELFYAML::ELF_EF &Value); 834 }; 835 836 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> { 837 static void bitset(IO &IO, ELFYAML::ELF_PF &Value); 838 }; 839 840 template <> 841 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> { 842 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value); 843 }; 844 845 template <> 846 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> { 847 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); 848 }; 849 850 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> { 851 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value); 852 }; 853 854 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> { 855 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value); 856 }; 857 858 template <> 859 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { 860 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); 861 }; 862 863 template <> 864 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> { 865 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); 866 }; 867 868 template <> 869 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> { 870 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value); 871 }; 872 873 template <> 874 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> { 875 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value); 876 }; 877 878 template <> 879 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> { 880 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value); 881 }; 882 883 template <> 884 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> { 885 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value); 886 }; 887 888 template <> 889 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> { 890 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value); 891 }; 892 893 template <> 894 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> { 895 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value); 896 }; 897 898 template <> 899 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> { 900 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value); 901 }; 902 903 template <> 904 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> { 905 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value); 906 }; 907 908 template <> 909 struct MappingTraits<ELFYAML::FileHeader> { 910 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); 911 }; 912 913 template <> struct MappingTraits<ELFYAML::SectionHeader> { 914 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr); 915 }; 916 917 template <> struct MappingTraits<ELFYAML::ProgramHeader> { 918 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr); 919 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr); 920 }; 921 922 template <> 923 struct MappingTraits<ELFYAML::Symbol> { 924 static void mapping(IO &IO, ELFYAML::Symbol &Symbol); 925 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol); 926 }; 927 928 template <> struct MappingTraits<ELFYAML::StackSizeEntry> { 929 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel); 930 }; 931 932 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> { 933 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E); 934 }; 935 936 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> { 937 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E); 938 }; 939 940 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> { 941 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E); 942 }; 943 944 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> { 945 static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel); 946 }; 947 948 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> { 949 static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel); 950 }; 951 952 template <> 953 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> { 954 static void 955 mapping(IO &IO, 956 ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel); 957 }; 958 959 template <> struct MappingTraits<ELFYAML::GnuHashHeader> { 960 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel); 961 }; 962 963 template <> struct MappingTraits<ELFYAML::DynamicEntry> { 964 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel); 965 }; 966 967 template <> struct MappingTraits<ELFYAML::NoteEntry> { 968 static void mapping(IO &IO, ELFYAML::NoteEntry &N); 969 }; 970 971 template <> struct MappingTraits<ELFYAML::VerdefEntry> { 972 static void mapping(IO &IO, ELFYAML::VerdefEntry &E); 973 }; 974 975 template <> struct MappingTraits<ELFYAML::VerneedEntry> { 976 static void mapping(IO &IO, ELFYAML::VerneedEntry &E); 977 }; 978 979 template <> struct MappingTraits<ELFYAML::VernauxEntry> { 980 static void mapping(IO &IO, ELFYAML::VernauxEntry &E); 981 }; 982 983 template <> struct MappingTraits<ELFYAML::LinkerOption> { 984 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym); 985 }; 986 987 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> { 988 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E); 989 }; 990 991 template <> struct MappingTraits<ELFYAML::Relocation> { 992 static void mapping(IO &IO, ELFYAML::Relocation &Rel); 993 }; 994 995 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> { 996 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E); 997 }; 998 999 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> { 1000 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C); 1001 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C); 1002 }; 1003 1004 template <> 1005 struct MappingTraits<ELFYAML::Object> { 1006 static void mapping(IO &IO, ELFYAML::Object &Object); 1007 }; 1008 1009 template <> struct MappingTraits<ELFYAML::SectionOrType> { 1010 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType); 1011 }; 1012 1013 } // end namespace yaml 1014 } // end namespace llvm 1015 1016 #endif // LLVM_OBJECTYAML_ELFYAML_H 1017