Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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