Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:21

0001 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file declares classes for handling the YAML representation
0011 /// of ELF.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_OBJECTYAML_ELFYAML_H
0016 #define LLVM_OBJECTYAML_ELFYAML_H
0017 
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/BinaryFormat/ELF.h"
0020 #include "llvm/Object/ELFTypes.h"
0021 #include "llvm/ObjectYAML/DWARFYAML.h"
0022 #include "llvm/ObjectYAML/YAML.h"
0023 #include "llvm/Support/YAMLTraits.h"
0024 #include <cstdint>
0025 #include <memory>
0026 #include <optional>
0027 #include <vector>
0028 
0029 namespace llvm {
0030 namespace ELFYAML {
0031 
0032 StringRef dropUniqueSuffix(StringRef S);
0033 std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
0034 
0035 // These types are invariant across 32/64-bit ELF, so for simplicity just
0036 // directly give them their exact sizes. We don't need to worry about
0037 // endianness because these are just the types in the YAMLIO structures,
0038 // and are appropriately converted to the necessary endianness when
0039 // reading/generating binary object files.
0040 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
0041 // the common prefix of the respective constants. E.g. ELF_EM corresponds
0042 // to the `e_machine` constants, like `EM_X86_64`.
0043 // In the future, these would probably be better suited by C++11 enum
0044 // class's with appropriate fixed underlying type.
0045 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
0046 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
0047 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
0048 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
0049 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
0050 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
0051 // Just use 64, since it can hold 32-bit values too.
0052 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
0053 // Just use 64, since it can hold 32-bit values too.
0054 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
0055 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
0056 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
0057 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
0058 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
0059 // Just use 64, since it can hold 32-bit values too.
0060 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
0061 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
0062 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
0063 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
0064 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)
0065 
0066 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
0067 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
0068 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
0069 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
0070 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
0071 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
0072 
0073 LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
0074 LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
0075 
0076 template <class ELFT>
0077 unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
0078                              StringRef SecName) {
0079   if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
0080     return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
0081 
0082   switch (SecType) {
0083   case ELF::SHT_SYMTAB:
0084   case ELF::SHT_DYNSYM:
0085     return sizeof(typename ELFT::Sym);
0086   case ELF::SHT_GROUP:
0087     return sizeof(typename ELFT::Word);
0088   case ELF::SHT_REL:
0089     return sizeof(typename ELFT::Rel);
0090   case ELF::SHT_RELA:
0091     return sizeof(typename ELFT::Rela);
0092   case ELF::SHT_RELR:
0093     return sizeof(typename ELFT::Relr);
0094   case ELF::SHT_DYNAMIC:
0095     return sizeof(typename ELFT::Dyn);
0096   case ELF::SHT_HASH:
0097     return sizeof(typename ELFT::Word);
0098   case ELF::SHT_SYMTAB_SHNDX:
0099     return sizeof(typename ELFT::Word);
0100   case ELF::SHT_GNU_versym:
0101     return sizeof(typename ELFT::Half);
0102   case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
0103     return sizeof(object::Elf_CGProfile_Impl<ELFT>);
0104   default:
0105     if (SecName == ".debug_str")
0106       return 1;
0107     return 0;
0108   }
0109 }
0110 
0111 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
0112 // since 64-bit can hold 32-bit values too.
0113 struct FileHeader {
0114   ELF_ELFCLASS Class;
0115   ELF_ELFDATA Data;
0116   ELF_ELFOSABI OSABI;
0117   llvm::yaml::Hex8 ABIVersion;
0118   ELF_ET Type;
0119   std::optional<ELF_EM> Machine;
0120   ELF_EF Flags;
0121   llvm::yaml::Hex64 Entry;
0122   std::optional<StringRef> SectionHeaderStringTable;
0123 
0124   std::optional<llvm::yaml::Hex64> EPhOff;
0125   std::optional<llvm::yaml::Hex16> EPhEntSize;
0126   std::optional<llvm::yaml::Hex16> EPhNum;
0127   std::optional<llvm::yaml::Hex16> EShEntSize;
0128   std::optional<llvm::yaml::Hex64> EShOff;
0129   std::optional<llvm::yaml::Hex16> EShNum;
0130   std::optional<llvm::yaml::Hex16> EShStrNdx;
0131 };
0132 
0133 struct SectionHeader {
0134   StringRef Name;
0135 };
0136 
0137 struct Symbol {
0138   StringRef Name;
0139   ELF_STT Type;
0140   std::optional<StringRef> Section;
0141   std::optional<ELF_SHN> Index;
0142   ELF_STB Binding;
0143   std::optional<llvm::yaml::Hex64> Value;
0144   std::optional<llvm::yaml::Hex64> Size;
0145   std::optional<uint8_t> Other;
0146 
0147   std::optional<uint32_t> StName;
0148 };
0149 
0150 struct SectionOrType {
0151   StringRef sectionNameOrType;
0152 };
0153 
0154 struct DynamicEntry {
0155   ELF_DYNTAG Tag;
0156   llvm::yaml::Hex64 Val;
0157 };
0158 
0159 struct BBAddrMapEntry {
0160   struct BBEntry {
0161     uint32_t ID;
0162     llvm::yaml::Hex64 AddressOffset;
0163     llvm::yaml::Hex64 Size;
0164     llvm::yaml::Hex64 Metadata;
0165   };
0166   uint8_t Version;
0167   llvm::yaml::Hex8 Feature;
0168 
0169   struct BBRangeEntry {
0170     llvm::yaml::Hex64 BaseAddress;
0171     std::optional<uint64_t> NumBlocks;
0172     std::optional<std::vector<BBEntry>> BBEntries;
0173   };
0174 
0175   std::optional<uint64_t> NumBBRanges;
0176   std::optional<std::vector<BBRangeEntry>> BBRanges;
0177 
0178   llvm::yaml::Hex64 getFunctionAddress() const {
0179     if (!BBRanges || BBRanges->empty())
0180       return 0;
0181     return BBRanges->front().BaseAddress;
0182   }
0183 };
0184 
0185 struct PGOAnalysisMapEntry {
0186   struct PGOBBEntry {
0187     struct SuccessorEntry {
0188       uint32_t ID;
0189       llvm::yaml::Hex32 BrProb;
0190     };
0191     std::optional<uint64_t> BBFreq;
0192     std::optional<std::vector<SuccessorEntry>> Successors;
0193   };
0194   std::optional<uint64_t> FuncEntryCount;
0195   std::optional<std::vector<PGOBBEntry>> PGOBBEntries;
0196 };
0197 
0198 struct StackSizeEntry {
0199   llvm::yaml::Hex64 Address;
0200   llvm::yaml::Hex64 Size;
0201 };
0202 
0203 struct NoteEntry {
0204   StringRef Name;
0205   yaml::BinaryRef Desc;
0206   ELF_NT Type;
0207 };
0208 
0209 struct Chunk {
0210   enum class ChunkKind {
0211     Dynamic,
0212     Group,
0213     RawContent,
0214     Relocation,
0215     Relr,
0216     NoBits,
0217     Note,
0218     Hash,
0219     GnuHash,
0220     Verdef,
0221     Verneed,
0222     StackSizes,
0223     SymtabShndxSection,
0224     Symver,
0225     ARMIndexTable,
0226     MipsABIFlags,
0227     Addrsig,
0228     LinkerOptions,
0229     DependentLibraries,
0230     CallGraphProfile,
0231     BBAddrMap,
0232 
0233     // Special chunks.
0234     SpecialChunksStart,
0235     Fill = SpecialChunksStart,
0236     SectionHeaderTable,
0237   };
0238 
0239   ChunkKind Kind;
0240   StringRef Name;
0241   std::optional<llvm::yaml::Hex64> Offset;
0242 
0243   // Usually chunks are not created implicitly, but rather loaded from YAML.
0244   // This flag is used to signal whether this is the case or not.
0245   bool IsImplicit;
0246 
0247   Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
0248   virtual ~Chunk();
0249 };
0250 
0251 struct Section : public Chunk {
0252   ELF_SHT Type;
0253   std::optional<ELF_SHF> Flags;
0254   std::optional<llvm::yaml::Hex64> Address;
0255   std::optional<StringRef> Link;
0256   llvm::yaml::Hex64 AddressAlign;
0257   std::optional<llvm::yaml::Hex64> EntSize;
0258 
0259   std::optional<yaml::BinaryRef> Content;
0260   std::optional<llvm::yaml::Hex64> Size;
0261 
0262   // Holds the original section index.
0263   unsigned OriginalSecNdx;
0264 
0265   Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
0266 
0267   static bool classof(const Chunk *S) {
0268     return S->Kind < ChunkKind::SpecialChunksStart;
0269   }
0270 
0271   // Some derived sections might have their own special entries. This method
0272   // returns a vector of <entry name, is used> pairs. It is used for section
0273   // validation.
0274   virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
0275     return {};
0276   };
0277 
0278   // The following members are used to override section fields which is
0279   // useful for creating invalid objects.
0280 
0281   // This can be used to override the sh_addralign field.
0282   std::optional<llvm::yaml::Hex64> ShAddrAlign;
0283 
0284   // This can be used to override the offset stored in the sh_name field.
0285   // It does not affect the name stored in the string table.
0286   std::optional<llvm::yaml::Hex64> ShName;
0287 
0288   // This can be used to override the sh_offset field. It does not place the
0289   // section data at the offset specified.
0290   std::optional<llvm::yaml::Hex64> ShOffset;
0291 
0292   // This can be used to override the sh_size field. It does not affect the
0293   // content written.
0294   std::optional<llvm::yaml::Hex64> ShSize;
0295 
0296   // This can be used to override the sh_flags field.
0297   std::optional<llvm::yaml::Hex64> ShFlags;
0298 
0299   // This can be used to override the sh_type field. It is useful when we
0300   // want to use specific YAML keys for a section of a particular type to
0301   // describe the content, but still want to have a different final type
0302   // for the section.
0303   std::optional<ELF_SHT> ShType;
0304 };
0305 
0306 // Fill is a block of data which is placed outside of sections. It is
0307 // not present in the sections header table, but it might affect the output file
0308 // size and program headers produced.
0309 struct Fill : Chunk {
0310   std::optional<yaml::BinaryRef> Pattern;
0311   llvm::yaml::Hex64 Size;
0312 
0313   Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
0314 
0315   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
0316 };
0317 
0318 struct SectionHeaderTable : Chunk {
0319   SectionHeaderTable(bool IsImplicit)
0320       : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
0321 
0322   static bool classof(const Chunk *S) {
0323     return S->Kind == ChunkKind::SectionHeaderTable;
0324   }
0325 
0326   std::optional<std::vector<SectionHeader>> Sections;
0327   std::optional<std::vector<SectionHeader>> Excluded;
0328   std::optional<bool> NoHeaders;
0329 
0330   size_t getNumHeaders(size_t SectionsNum) const {
0331     if (IsImplicit || isDefault())
0332       return SectionsNum;
0333     if (NoHeaders)
0334       return (*NoHeaders) ? 0 : SectionsNum;
0335     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
0336   }
0337 
0338   bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
0339 
0340   static constexpr StringRef TypeStr = "SectionHeaderTable";
0341 };
0342 
0343 struct BBAddrMapSection : Section {
0344   std::optional<std::vector<BBAddrMapEntry>> Entries;
0345   std::optional<std::vector<PGOAnalysisMapEntry>> PGOAnalyses;
0346 
0347   BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
0348 
0349   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0350     return {{"Entries", Entries.has_value()}};
0351   };
0352 
0353   static bool classof(const Chunk *S) {
0354     return S->Kind == ChunkKind::BBAddrMap;
0355   }
0356 };
0357 
0358 struct StackSizesSection : Section {
0359   std::optional<std::vector<StackSizeEntry>> Entries;
0360 
0361   StackSizesSection() : Section(ChunkKind::StackSizes) {}
0362 
0363   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0364     return {{"Entries", Entries.has_value()}};
0365   };
0366 
0367   static bool classof(const Chunk *S) {
0368     return S->Kind == ChunkKind::StackSizes;
0369   }
0370 
0371   static bool nameMatches(StringRef Name) {
0372     return Name == ".stack_sizes";
0373   }
0374 };
0375 
0376 struct DynamicSection : Section {
0377   std::optional<std::vector<DynamicEntry>> Entries;
0378 
0379   DynamicSection() : Section(ChunkKind::Dynamic) {}
0380 
0381   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0382     return {{"Entries", Entries.has_value()}};
0383   };
0384 
0385   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
0386 };
0387 
0388 struct RawContentSection : Section {
0389   std::optional<llvm::yaml::Hex64> Info;
0390 
0391   RawContentSection() : Section(ChunkKind::RawContent) {}
0392 
0393   static bool classof(const Chunk *S) {
0394     return S->Kind == ChunkKind::RawContent;
0395   }
0396 
0397   // Is used when a content is read as an array of bytes.
0398   std::optional<std::vector<uint8_t>> ContentBuf;
0399 };
0400 
0401 struct NoBitsSection : Section {
0402   NoBitsSection() : Section(ChunkKind::NoBits) {}
0403 
0404   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
0405 };
0406 
0407 struct NoteSection : Section {
0408   std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
0409 
0410   NoteSection() : Section(ChunkKind::Note) {}
0411 
0412   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0413     return {{"Notes", Notes.has_value()}};
0414   };
0415 
0416   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
0417 };
0418 
0419 struct HashSection : Section {
0420   std::optional<std::vector<uint32_t>> Bucket;
0421   std::optional<std::vector<uint32_t>> Chain;
0422 
0423   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0424     return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
0425   };
0426 
0427   // The following members are used to override section fields.
0428   // This is useful for creating invalid objects.
0429   std::optional<llvm::yaml::Hex64> NBucket;
0430   std::optional<llvm::yaml::Hex64> NChain;
0431 
0432   HashSection() : Section(ChunkKind::Hash) {}
0433 
0434   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
0435 };
0436 
0437 struct GnuHashHeader {
0438   // The number of hash buckets.
0439   // Not used when dumping the object, but can be used to override
0440   // the real number of buckets when emiting an object from a YAML document.
0441   std::optional<llvm::yaml::Hex32> NBuckets;
0442 
0443   // Index of the first symbol in the dynamic symbol table
0444   // included in the hash table.
0445   llvm::yaml::Hex32 SymNdx;
0446 
0447   // The number of words in the Bloom filter.
0448   // Not used when dumping the object, but can be used to override the real
0449   // number of words in the Bloom filter when emiting an object from a YAML
0450   // document.
0451   std::optional<llvm::yaml::Hex32> MaskWords;
0452 
0453   // A shift constant used by the Bloom filter.
0454   llvm::yaml::Hex32 Shift2;
0455 };
0456 
0457 struct GnuHashSection : Section {
0458   std::optional<GnuHashHeader> Header;
0459   std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
0460   std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
0461   std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
0462 
0463   GnuHashSection() : Section(ChunkKind::GnuHash) {}
0464 
0465   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0466     return {{"Header", Header.has_value()},
0467             {"BloomFilter", BloomFilter.has_value()},
0468             {"HashBuckets", HashBuckets.has_value()},
0469             {"HashValues", HashValues.has_value()}};
0470   };
0471 
0472   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
0473 };
0474 
0475 struct VernauxEntry {
0476   uint32_t Hash;
0477   uint16_t Flags;
0478   uint16_t Other;
0479   StringRef Name;
0480 };
0481 
0482 struct VerneedEntry {
0483   uint16_t Version;
0484   StringRef File;
0485   std::vector<VernauxEntry> AuxV;
0486 };
0487 
0488 struct VerneedSection : Section {
0489   std::optional<std::vector<VerneedEntry>> VerneedV;
0490   std::optional<llvm::yaml::Hex64> Info;
0491 
0492   VerneedSection() : Section(ChunkKind::Verneed) {}
0493 
0494   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0495     return {{"Dependencies", VerneedV.has_value()}};
0496   };
0497 
0498   static bool classof(const Chunk *S) {
0499     return S->Kind == ChunkKind::Verneed;
0500   }
0501 };
0502 
0503 struct AddrsigSection : Section {
0504   std::optional<std::vector<YAMLFlowString>> Symbols;
0505 
0506   AddrsigSection() : Section(ChunkKind::Addrsig) {}
0507 
0508   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0509     return {{"Symbols", Symbols.has_value()}};
0510   };
0511 
0512   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
0513 };
0514 
0515 struct LinkerOption {
0516   StringRef Key;
0517   StringRef Value;
0518 };
0519 
0520 struct LinkerOptionsSection : Section {
0521   std::optional<std::vector<LinkerOption>> Options;
0522 
0523   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
0524 
0525   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0526     return {{"Options", Options.has_value()}};
0527   };
0528 
0529   static bool classof(const Chunk *S) {
0530     return S->Kind == ChunkKind::LinkerOptions;
0531   }
0532 };
0533 
0534 struct DependentLibrariesSection : Section {
0535   std::optional<std::vector<YAMLFlowString>> Libs;
0536 
0537   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
0538 
0539   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0540     return {{"Libraries", Libs.has_value()}};
0541   };
0542 
0543   static bool classof(const Chunk *S) {
0544     return S->Kind == ChunkKind::DependentLibraries;
0545   }
0546 };
0547 
0548 // Represents the call graph profile section entry.
0549 struct CallGraphEntryWeight {
0550   // The weight of the edge.
0551   uint64_t Weight;
0552 };
0553 
0554 struct CallGraphProfileSection : Section {
0555   std::optional<std::vector<CallGraphEntryWeight>> Entries;
0556 
0557   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
0558 
0559   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0560     return {{"Entries", Entries.has_value()}};
0561   };
0562 
0563   static bool classof(const Chunk *S) {
0564     return S->Kind == ChunkKind::CallGraphProfile;
0565   }
0566 };
0567 
0568 struct SymverSection : Section {
0569   std::optional<std::vector<uint16_t>> Entries;
0570 
0571   SymverSection() : Section(ChunkKind::Symver) {}
0572 
0573   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0574     return {{"Entries", Entries.has_value()}};
0575   };
0576 
0577   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
0578 };
0579 
0580 struct VerdefEntry {
0581   std::optional<uint16_t> Version;
0582   std::optional<uint16_t> Flags;
0583   std::optional<uint16_t> VersionNdx;
0584   std::optional<uint32_t> Hash;
0585   std::optional<uint16_t> VDAux;
0586   std::vector<StringRef> VerNames;
0587 };
0588 
0589 struct VerdefSection : Section {
0590   std::optional<std::vector<VerdefEntry>> Entries;
0591   std::optional<llvm::yaml::Hex64> Info;
0592 
0593   VerdefSection() : Section(ChunkKind::Verdef) {}
0594 
0595   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0596     return {{"Entries", Entries.has_value()}};
0597   };
0598 
0599   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
0600 };
0601 
0602 struct GroupSection : Section {
0603   // Members of a group contain a flag and a list of section indices
0604   // that are part of the group.
0605   std::optional<std::vector<SectionOrType>> Members;
0606   std::optional<StringRef> Signature; /* Info */
0607 
0608   GroupSection() : Section(ChunkKind::Group) {}
0609 
0610   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0611     return {{"Members", Members.has_value()}};
0612   };
0613 
0614   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
0615 };
0616 
0617 struct Relocation {
0618   llvm::yaml::Hex64 Offset;
0619   YAMLIntUInt Addend;
0620   ELF_REL Type;
0621   std::optional<StringRef> Symbol;
0622 };
0623 
0624 struct RelocationSection : Section {
0625   std::optional<std::vector<Relocation>> Relocations;
0626   StringRef RelocatableSec; /* Info */
0627 
0628   RelocationSection() : Section(ChunkKind::Relocation) {}
0629 
0630   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0631     return {{"Relocations", Relocations.has_value()}};
0632   };
0633 
0634   static bool classof(const Chunk *S) {
0635     return S->Kind == ChunkKind::Relocation;
0636   }
0637 };
0638 
0639 struct RelrSection : Section {
0640   std::optional<std::vector<llvm::yaml::Hex64>> Entries;
0641 
0642   RelrSection() : Section(ChunkKind::Relr) {}
0643 
0644   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0645     return {{"Entries", Entries.has_value()}};
0646   };
0647 
0648   static bool classof(const Chunk *S) {
0649     return S->Kind == ChunkKind::Relr;
0650   }
0651 };
0652 
0653 struct SymtabShndxSection : Section {
0654   std::optional<std::vector<uint32_t>> Entries;
0655 
0656   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
0657 
0658   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0659     return {{"Entries", Entries.has_value()}};
0660   };
0661 
0662   static bool classof(const Chunk *S) {
0663     return S->Kind == ChunkKind::SymtabShndxSection;
0664   }
0665 };
0666 
0667 struct ARMIndexTableEntry {
0668   llvm::yaml::Hex32 Offset;
0669   llvm::yaml::Hex32 Value;
0670 };
0671 
0672 struct ARMIndexTableSection : Section {
0673   std::optional<std::vector<ARMIndexTableEntry>> Entries;
0674 
0675   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
0676 
0677   std::vector<std::pair<StringRef, bool>> getEntries() const override {
0678     return {{"Entries", Entries.has_value()}};
0679   };
0680 
0681   static bool classof(const Chunk *S) {
0682     return S->Kind == ChunkKind::ARMIndexTable;
0683   }
0684 };
0685 
0686 // Represents .MIPS.abiflags section
0687 struct MipsABIFlags : Section {
0688   llvm::yaml::Hex16 Version;
0689   MIPS_ISA ISALevel;
0690   llvm::yaml::Hex8 ISARevision;
0691   MIPS_AFL_REG GPRSize;
0692   MIPS_AFL_REG CPR1Size;
0693   MIPS_AFL_REG CPR2Size;
0694   MIPS_ABI_FP FpABI;
0695   MIPS_AFL_EXT ISAExtension;
0696   MIPS_AFL_ASE ASEs;
0697   MIPS_AFL_FLAGS1 Flags1;
0698   llvm::yaml::Hex32 Flags2;
0699 
0700   MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
0701 
0702   static bool classof(const Chunk *S) {
0703     return S->Kind == ChunkKind::MipsABIFlags;
0704   }
0705 };
0706 
0707 struct ProgramHeader {
0708   ELF_PT Type;
0709   ELF_PF Flags;
0710   llvm::yaml::Hex64 VAddr;
0711   llvm::yaml::Hex64 PAddr;
0712   std::optional<llvm::yaml::Hex64> Align;
0713   std::optional<llvm::yaml::Hex64> FileSize;
0714   std::optional<llvm::yaml::Hex64> MemSize;
0715   std::optional<llvm::yaml::Hex64> Offset;
0716   std::optional<StringRef> FirstSec;
0717   std::optional<StringRef> LastSec;
0718 
0719   // This vector contains all chunks from [FirstSec, LastSec].
0720   std::vector<Chunk *> Chunks;
0721 };
0722 
0723 struct Object {
0724   FileHeader Header;
0725   std::vector<ProgramHeader> ProgramHeaders;
0726 
0727   // An object might contain output section descriptions as well as
0728   // custom data that does not belong to any section.
0729   std::vector<std::unique_ptr<Chunk>> Chunks;
0730 
0731   // Although in reality the symbols reside in a section, it is a lot
0732   // cleaner and nicer if we read them from the YAML as a separate
0733   // top-level key, which automatically ensures that invariants like there
0734   // being a single SHT_SYMTAB section are upheld.
0735   std::optional<std::vector<Symbol>> Symbols;
0736   std::optional<std::vector<Symbol>> DynamicSymbols;
0737   std::optional<DWARFYAML::Data> DWARF;
0738 
0739   std::vector<Section *> getSections() {
0740     std::vector<Section *> Ret;
0741     for (const std::unique_ptr<Chunk> &Sec : Chunks)
0742       if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
0743         Ret.push_back(S);
0744     return Ret;
0745   }
0746 
0747   const SectionHeaderTable &getSectionHeaderTable() const {
0748     for (const std::unique_ptr<Chunk> &C : Chunks)
0749       if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
0750         return *S;
0751     llvm_unreachable("the section header table chunk must always be present");
0752   }
0753 
0754   ELF_ELFOSABI getOSAbi() const;
0755   unsigned getMachine() const;
0756 };
0757 
0758 bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
0759                              const NoBitsSection &S);
0760 
0761 } // end namespace ELFYAML
0762 } // end namespace llvm
0763 
0764 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
0765 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
0766 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
0767 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBRangeEntry)
0768 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry)
0769 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry)
0770 LLVM_YAML_IS_SEQUENCE_VECTOR(
0771     llvm::ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry)
0772 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
0773 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
0774 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
0775 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
0776 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
0777 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
0778 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
0779 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
0780 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
0781 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
0782 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
0783 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
0784 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
0785 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
0786 
0787 namespace llvm {
0788 namespace yaml {
0789 
0790 template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
0791   static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
0792                      raw_ostream &Out);
0793   static StringRef input(StringRef Scalar, void *Ctx,
0794                          ELFYAML::YAMLIntUInt &Val);
0795   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
0796 };
0797 
0798 template <>
0799 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
0800   static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
0801 };
0802 
0803 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
0804   static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
0805 };
0806 
0807 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
0808   static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
0809 };
0810 
0811 template <>
0812 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
0813   static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
0814 };
0815 
0816 template <>
0817 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
0818   static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
0819 };
0820 
0821 template <>
0822 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
0823   static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
0824 };
0825 
0826 template <>
0827 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
0828   static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
0829 };
0830 
0831 template <>
0832 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
0833   static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
0834 };
0835 
0836 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
0837   static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
0838 };
0839 
0840 template <>
0841 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
0842   static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
0843 };
0844 
0845 template <>
0846 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
0847   static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
0848 };
0849 
0850 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
0851   static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
0852 };
0853 
0854 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
0855   static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
0856 };
0857 
0858 template <>
0859 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
0860   static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
0861 };
0862 
0863 template <>
0864 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
0865   static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
0866 };
0867 
0868 template <>
0869 struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
0870   static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
0871 };
0872 
0873 template <>
0874 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
0875   static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
0876 };
0877 
0878 template <>
0879 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
0880   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
0881 };
0882 
0883 template <>
0884 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
0885   static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
0886 };
0887 
0888 template <>
0889 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
0890   static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
0891 };
0892 
0893 template <>
0894 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
0895   static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
0896 };
0897 
0898 template <>
0899 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
0900   static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
0901 };
0902 
0903 template <>
0904 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
0905   static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
0906 };
0907 
0908 template <>
0909 struct MappingTraits<ELFYAML::FileHeader> {
0910   static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
0911 };
0912 
0913 template <> struct MappingTraits<ELFYAML::SectionHeader> {
0914   static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
0915 };
0916 
0917 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
0918   static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
0919   static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
0920 };
0921 
0922 template <>
0923 struct MappingTraits<ELFYAML::Symbol> {
0924   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
0925   static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
0926 };
0927 
0928 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
0929   static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
0930 };
0931 
0932 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
0933   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &E);
0934 };
0935 
0936 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry> {
0937   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E);
0938 };
0939 
0940 template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
0941   static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E);
0942 };
0943 
0944 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry> {
0945   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry &Rel);
0946 };
0947 
0948 template <> struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry> {
0949   static void mapping(IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &Rel);
0950 };
0951 
0952 template <>
0953 struct MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry> {
0954   static void
0955   mapping(IO &IO,
0956           ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &Rel);
0957 };
0958 
0959 template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
0960   static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
0961 };
0962 
0963 template <> struct MappingTraits<ELFYAML::DynamicEntry> {
0964   static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
0965 };
0966 
0967 template <> struct MappingTraits<ELFYAML::NoteEntry> {
0968   static void mapping(IO &IO, ELFYAML::NoteEntry &N);
0969 };
0970 
0971 template <> struct MappingTraits<ELFYAML::VerdefEntry> {
0972   static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
0973 };
0974 
0975 template <> struct MappingTraits<ELFYAML::VerneedEntry> {
0976   static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
0977 };
0978 
0979 template <> struct MappingTraits<ELFYAML::VernauxEntry> {
0980   static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
0981 };
0982 
0983 template <> struct MappingTraits<ELFYAML::LinkerOption> {
0984   static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
0985 };
0986 
0987 template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
0988   static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
0989 };
0990 
0991 template <> struct MappingTraits<ELFYAML::Relocation> {
0992   static void mapping(IO &IO, ELFYAML::Relocation &Rel);
0993 };
0994 
0995 template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
0996   static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
0997 };
0998 
0999 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 &sectionOrType);
1011 };
1012 
1013 } // end namespace yaml
1014 } // end namespace llvm
1015 
1016 #endif // LLVM_OBJECTYAML_ELFYAML_H