diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/include/llvm/ObjectYAML | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
download | src-e8d8bef961a50d4dc22501cde4fb9fb0be1b2532.tar.gz src-e8d8bef961a50d4dc22501cde4fb9fb0be1b2532.zip |
Diffstat (limited to 'contrib/llvm-project/llvm/include/llvm/ObjectYAML')
9 files changed, 513 insertions, 123 deletions
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ArchiveYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ArchiveYAML.h new file mode 100644 index 000000000000..8d05feedcc62 --- /dev/null +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ArchiveYAML.h @@ -0,0 +1,77 @@ +//===- ArchiveYAML.h - Archive YAMLIO implementation ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file declares classes for handling the YAML representation of archives. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_ARCHIVEYAML_H +#define LLVM_OBJECTYAML_ARCHIVEYAML_H + +#include "llvm/Support/YAMLTraits.h" +#include "llvm/ObjectYAML/YAML.h" +#include "llvm/ADT/MapVector.h" + +namespace llvm { +namespace ArchYAML { + +struct Archive { + struct Child { + struct Field { + Field() = default; + Field(StringRef Default, unsigned Length) + : DefaultValue(Default), MaxLength(Length) {} + StringRef Value; + StringRef DefaultValue; + unsigned MaxLength; + }; + + Child() { + Fields["Name"] = {"", 16}; + Fields["LastModified"] = {"0", 12}; + Fields["UID"] = {"0", 6}; + Fields["GID"] = {"0", 6}; + Fields["AccessMode"] = {"0", 8}; + Fields["Size"] = {"0", 10}; + Fields["Terminator"] = {"`\n", 2}; + } + + MapVector<StringRef, Field> Fields; + + Optional<yaml::BinaryRef> Content; + Optional<llvm::yaml::Hex8> PaddingByte; + }; + + StringRef Magic; + Optional<std::vector<Child>> Members; + Optional<yaml::BinaryRef> Content; +}; + +} // end namespace ArchYAML +} // end namespace llvm + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ArchYAML::Archive::Child) + +namespace llvm { +namespace yaml { + +template <> struct MappingTraits<ArchYAML::Archive> { + static void mapping(IO &IO, ArchYAML::Archive &A); + static std::string validate(IO &, ArchYAML::Archive &A); +}; + +template <> struct MappingTraits<ArchYAML::Archive::Child> { + static void mapping(IO &IO, ArchYAML::Archive::Child &C); + static std::string validate(IO &, ArchYAML::Archive::Child &C); +}; + +} // end namespace yaml +} // end namespace llvm + +#endif // LLVM_OBJECTYAML_ARCHIVEYAML_H diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h index 0ec3f90e1686..eb56d1e29326 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h @@ -33,15 +33,23 @@ Error emitDebugStr(raw_ostream &OS, const Data &DI); Error emitDebugAranges(raw_ostream &OS, const Data &DI); Error emitDebugRanges(raw_ostream &OS, const Data &DI); -Error emitPubSection(raw_ostream &OS, const PubSection &Sect, - bool IsLittleEndian, bool IsGNUPubSec = false); +Error emitDebugPubnames(raw_ostream &OS, const Data &DI); +Error emitDebugPubtypes(raw_ostream &OS, const Data &DI); +Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI); +Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI); Error emitDebugInfo(raw_ostream &OS, const Data &DI); Error emitDebugLine(raw_ostream &OS, const Data &DI); Error emitDebugAddr(raw_ostream &OS, const Data &DI); +Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI); +Error emitDebugRnglists(raw_ostream &OS, const Data &DI); +Error emitDebugLoclists(raw_ostream &OS, const Data &DI); +std::function<Error(raw_ostream &, const Data &)> +getDWARFEmitterByName(StringRef SecName); Expected<StringMap<std::unique_ptr<MemoryBuffer>>> -emitDebugSections(StringRef YAMLString, bool ApplyFixups = false, - bool IsLittleEndian = sys::IsLittleEndianHost); +emitDebugSections(StringRef YAMLString, + bool IsLittleEndian = sys::IsLittleEndianHost, + bool Is64BitAddrSize = true); } // end namespace DWARFYAML } // end namespace llvm diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h index 9f62a4a2be57..856cea9a1535 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -18,33 +18,15 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/YAMLTraits.h" #include <cstdint> +#include <unordered_map> #include <vector> namespace llvm { namespace DWARFYAML { -struct InitialLength { - uint32_t TotalLength; - uint64_t TotalLength64; - - bool isDWARF64() const { return TotalLength == UINT32_MAX; } - - uint64_t getLength() const { - return isDWARF64() ? TotalLength64 : TotalLength; - } - - void setLength(uint64_t Len) { - if (Len >= (uint64_t)UINT32_MAX) { - TotalLength64 = Len; - TotalLength = UINT32_MAX; - } else { - TotalLength = Len; - } - } -}; - struct AttributeAbbrev { llvm::dwarf::Attribute Attribute; llvm::dwarf::Form Form; @@ -58,18 +40,23 @@ struct Abbrev { std::vector<AttributeAbbrev> Attributes; }; +struct AbbrevTable { + Optional<uint64_t> ID; + std::vector<Abbrev> Table; +}; + struct ARangeDescriptor { llvm::yaml::Hex64 Address; - uint64_t Length; + yaml::Hex64 Length; }; struct ARange { dwarf::DwarfFormat Format; - uint64_t Length; + Optional<yaml::Hex64> Length; uint16_t Version; - uint32_t CuOffset; - uint8_t AddrSize; - uint8_t SegSize; + yaml::Hex64 CuOffset; + Optional<yaml::Hex8> AddrSize; + yaml::Hex8 SegSize; std::vector<ARangeDescriptor> Descriptors; }; @@ -94,7 +81,8 @@ struct PubEntry { }; struct PubSection { - InitialLength Length; + dwarf::DwarfFormat Format; + yaml::Hex64 Length; uint16_t Version; uint32_t UnitOffset; uint32_t UnitSize; @@ -120,11 +108,12 @@ struct DWARFContext { struct Unit { dwarf::DwarfFormat Format; - uint64_t Length; + Optional<yaml::Hex64> Length; uint16_t Version; + Optional<uint8_t> AddrSize; llvm::dwarf::UnitType Type; // Added in DWARF 5 - yaml::Hex64 AbbrOffset; - uint8_t AddrSize; + Optional<uint64_t> AbbrevTableID; + Optional<yaml::Hex64> AbbrOffset; std::vector<Entry> Entries; }; @@ -137,7 +126,7 @@ struct File { struct LineTableOpcode { dwarf::LineNumberOps Opcode; - uint64_t ExtLen; + Optional<uint64_t> ExtLen; dwarf::LineNumberExtendedOps SubOpcode; uint64_t Data; int64_t SData; @@ -148,16 +137,16 @@ struct LineTableOpcode { struct LineTable { dwarf::DwarfFormat Format; - uint64_t Length; + Optional<uint64_t> Length; uint16_t Version; - uint64_t PrologueLength; + Optional<uint64_t> PrologueLength; uint8_t MinInstLength; uint8_t MaxOpsPerInst; uint8_t DefaultIsStmt; uint8_t LineBase; uint8_t LineRange; - uint8_t OpcodeBase; - std::vector<uint8_t> StandardOpcodeLengths; + Optional<uint8_t> OpcodeBase; + Optional<std::vector<uint8_t>> StandardOpcodeLengths; std::vector<StringRef> IncludeDirs; std::vector<File> Files; std::vector<LineTableOpcode> Opcodes; @@ -177,14 +166,56 @@ struct AddrTableEntry { std::vector<SegAddrPair> SegAddrPairs; }; +struct StringOffsetsTable { + dwarf::DwarfFormat Format; + Optional<yaml::Hex64> Length; + yaml::Hex16 Version; + yaml::Hex16 Padding; + std::vector<yaml::Hex64> Offsets; +}; + +struct DWARFOperation { + dwarf::LocationAtom Operator; + std::vector<yaml::Hex64> Values; +}; + +struct RnglistEntry { + dwarf::RnglistEntries Operator; + std::vector<yaml::Hex64> Values; +}; + +struct LoclistEntry { + dwarf::LoclistEntries Operator; + std::vector<yaml::Hex64> Values; + Optional<yaml::Hex64> DescriptionsLength; + std::vector<DWARFOperation> Descriptions; +}; + +template <typename EntryType> struct ListEntries { + Optional<std::vector<EntryType>> Entries; + Optional<yaml::BinaryRef> Content; +}; + +template <typename EntryType> struct ListTable { + dwarf::DwarfFormat Format; + Optional<yaml::Hex64> Length; + yaml::Hex16 Version; + Optional<yaml::Hex8> AddrSize; + yaml::Hex8 SegSelectorSize; + Optional<uint32_t> OffsetEntryCount; + Optional<std::vector<yaml::Hex64>> Offsets; + std::vector<ListEntries<EntryType>> Lists; +}; + struct Data { bool IsLittleEndian; bool Is64BitAddrSize; - std::vector<Abbrev> AbbrevDecls; - std::vector<StringRef> DebugStrings; - std::vector<ARange> ARanges; - std::vector<Ranges> DebugRanges; - std::vector<AddrTableEntry> DebugAddr; + std::vector<AbbrevTable> DebugAbbrev; + Optional<std::vector<StringRef>> DebugStrings; + Optional<std::vector<StringOffsetsTable>> DebugStrOffsets; + Optional<std::vector<ARange>> DebugAranges; + Optional<std::vector<Ranges>> DebugRanges; + Optional<std::vector<AddrTableEntry>> DebugAddr; Optional<PubSection> PubNames; Optional<PubSection> PubTypes; @@ -194,10 +225,23 @@ struct Data { std::vector<Unit> CompileUnits; std::vector<LineTable> DebugLines; + Optional<std::vector<ListTable<RnglistEntry>>> DebugRnglists; + Optional<std::vector<ListTable<LoclistEntry>>> DebugLoclists; bool isEmpty() const; - SetVector<StringRef> getUsedSectionNames() const; + SetVector<StringRef> getNonEmptySectionNames() const; + + struct AbbrevTableInfo { + uint64_t Index; + uint64_t Offset; + }; + Expected<AbbrevTableInfo> getAbbrevTableInfoByID(uint64_t ID) const; + StringRef getAbbrevTableContentByIndex(uint64_t Index) const; + +private: + mutable std::unordered_map<uint64_t, AbbrevTableInfo> AbbrevTableInfoMap; + mutable std::unordered_map<uint64_t, std::string> AbbrevTableContents; }; } // end namespace DWARFYAML @@ -205,6 +249,7 @@ struct Data { LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AbbrevTable) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RangeEntry) @@ -218,6 +263,18 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::SegAddrPair) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AddrTableEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::StringOffsetsTable) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListTable<DWARFYAML::RnglistEntry>) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListEntries<DWARFYAML::RnglistEntry>) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListTable<DWARFYAML::LoclistEntry>) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListEntries<DWARFYAML::LoclistEntry>) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LoclistEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::DWARFOperation) namespace llvm { namespace yaml { @@ -226,6 +283,10 @@ template <> struct MappingTraits<DWARFYAML::Data> { static void mapping(IO &IO, DWARFYAML::Data &DWARF); }; +template <> struct MappingTraits<DWARFYAML::AbbrevTable> { + static void mapping(IO &IO, DWARFYAML::AbbrevTable &AbbrevTable); +}; + template <> struct MappingTraits<DWARFYAML::Abbrev> { static void mapping(IO &IO, DWARFYAML::Abbrev &Abbrev); }; @@ -286,12 +347,36 @@ template <> struct MappingTraits<DWARFYAML::SegAddrPair> { static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair); }; +template <> struct MappingTraits<DWARFYAML::DWARFOperation> { + static void mapping(IO &IO, DWARFYAML::DWARFOperation &DWARFOperation); +}; + +template <typename EntryType> +struct MappingTraits<DWARFYAML::ListTable<EntryType>> { + static void mapping(IO &IO, DWARFYAML::ListTable<EntryType> &ListTable); +}; + +template <typename EntryType> +struct MappingTraits<DWARFYAML::ListEntries<EntryType>> { + static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries); + static std::string validate(IO &IO, + DWARFYAML::ListEntries<EntryType> &ListEntries); +}; + +template <> struct MappingTraits<DWARFYAML::RnglistEntry> { + static void mapping(IO &IO, DWARFYAML::RnglistEntry &RnglistEntry); +}; + +template <> struct MappingTraits<DWARFYAML::LoclistEntry> { + static void mapping(IO &IO, DWARFYAML::LoclistEntry &LoclistEntry); +}; + template <> struct MappingTraits<DWARFYAML::AddrTableEntry> { static void mapping(IO &IO, DWARFYAML::AddrTableEntry &AddrTable); }; -template <> struct MappingTraits<DWARFYAML::InitialLength> { - static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF); +template <> struct MappingTraits<DWARFYAML::StringOffsetsTable> { + static void mapping(IO &IO, DWARFYAML::StringOffsetsTable &StrOffsetsTable); }; template <> struct ScalarEnumerationTraits<dwarf::DwarfFormat> { @@ -369,6 +454,34 @@ template <> struct ScalarEnumerationTraits<dwarf::Constants> { } }; +#define HANDLE_DW_RLE(unused, name) \ + io.enumCase(value, "DW_RLE_" #name, dwarf::DW_RLE_##name); + +template <> struct ScalarEnumerationTraits<dwarf::RnglistEntries> { + static void enumeration(IO &io, dwarf::RnglistEntries &value) { +#include "llvm/BinaryFormat/Dwarf.def" + } +}; + +#define HANDLE_DW_LLE(unused, name) \ + io.enumCase(value, "DW_LLE_" #name, dwarf::DW_LLE_##name); + +template <> struct ScalarEnumerationTraits<dwarf::LoclistEntries> { + static void enumeration(IO &io, dwarf::LoclistEntries &value) { +#include "llvm/BinaryFormat/Dwarf.def" + } +}; + +#define HANDLE_DW_OP(id, name, version, vendor) \ + io.enumCase(value, "DW_OP_" #name, dwarf::DW_OP_##name); + +template <> struct ScalarEnumerationTraits<dwarf::LocationAtom> { + static void enumeration(IO &io, dwarf::LocationAtom &value) { +#include "llvm/BinaryFormat/Dwarf.def" + io.enumFallback<yaml::Hex8>(value); + } +}; + } // end namespace yaml } // end namespace llvm diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h index b1ffb20681ea..4f3c76bbd82c 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -16,6 +16,8 @@ #define LLVM_OBJECTYAML_ELFYAML_H #include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Object/ELFTypes.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/YAMLTraits.h" @@ -69,6 +71,41 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA) LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString) LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt) +template <class ELFT> +unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType, + StringRef SecName) { + if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS) + return sizeof(object::Elf_Mips_ABIFlags<ELFT>); + + switch (SecType) { + case ELF::SHT_SYMTAB: + case ELF::SHT_DYNSYM: + return sizeof(typename ELFT::Sym); + case ELF::SHT_GROUP: + return sizeof(typename ELFT::Word); + case ELF::SHT_REL: + return sizeof(typename ELFT::Rel); + case ELF::SHT_RELA: + return sizeof(typename ELFT::Rela); + case ELF::SHT_RELR: + return sizeof(typename ELFT::Relr); + case ELF::SHT_DYNAMIC: + return sizeof(typename ELFT::Dyn); + case ELF::SHT_HASH: + return sizeof(typename ELFT::Word); + case ELF::SHT_SYMTAB_SHNDX: + return sizeof(typename ELFT::Word); + case ELF::SHT_GNU_versym: + return sizeof(typename ELFT::Half); + case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: + return sizeof(object::Elf_CGProfile_Impl<ELFT>); + default: + if (SecName == ".debug_str") + return 1; + return 0; + } +} + // For now, hardcode 64 bits everywhere that 32 or 64 would be needed // since 64-bit can hold 32-bit values too. struct FileHeader { @@ -77,7 +114,7 @@ struct FileHeader { ELF_ELFOSABI OSABI; llvm::yaml::Hex8 ABIVersion; ELF_ET Type; - ELF_EM Machine; + Optional<ELF_EM> Machine; ELF_EF Flags; llvm::yaml::Hex64 Entry; @@ -94,24 +131,14 @@ struct SectionHeader { StringRef Name; }; -struct SectionHeaderTable { - Optional<std::vector<SectionHeader>> Sections; - Optional<std::vector<SectionHeader>> Excluded; - Optional<bool> NoHeaders; -}; - -struct SectionName { - StringRef Section; -}; - struct Symbol { StringRef Name; ELF_STT Type; - StringRef Section; + Optional<StringRef> Section; Optional<ELF_SHN> Index; ELF_STB Binding; - llvm::yaml::Hex64 Value; - llvm::yaml::Hex64 Size; + Optional<llvm::yaml::Hex64> Value; + Optional<llvm::yaml::Hex64> Size; Optional<uint8_t> Other; Optional<uint32_t> StName; @@ -126,6 +153,16 @@ struct DynamicEntry { llvm::yaml::Hex64 Val; }; +struct BBAddrMapEntry { + struct BBEntry { + llvm::yaml::Hex32 AddressOffset; + llvm::yaml::Hex32 Size; + llvm::yaml::Hex32 Metadata; + }; + llvm::yaml::Hex64 Address; + Optional<std::vector<BBEntry>> BBEntries; +}; + struct StackSizeEntry { llvm::yaml::Hex64 Address; llvm::yaml::Hex64 Size; @@ -153,19 +190,29 @@ struct Chunk { StackSizes, SymtabShndxSection, Symver, + ARMIndexTable, MipsABIFlags, Addrsig, - Fill, LinkerOptions, DependentLibraries, - CallGraphProfile + CallGraphProfile, + BBAddrMap, + + // Special chunks. + SpecialChunksStart, + Fill = SpecialChunksStart, + SectionHeaderTable, }; ChunkKind Kind; StringRef Name; Optional<llvm::yaml::Hex64> Offset; - Chunk(ChunkKind K) : Kind(K) {} + // Usually chunks are not created implicitly, but rather loaded from YAML. + // This flag is used to signal whether this is the case or not. + bool IsImplicit; + + Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {} virtual ~Chunk(); }; @@ -173,25 +220,35 @@ struct Section : public Chunk { ELF_SHT Type; Optional<ELF_SHF> Flags; Optional<llvm::yaml::Hex64> Address; - StringRef Link; + Optional<StringRef> Link; llvm::yaml::Hex64 AddressAlign; Optional<llvm::yaml::Hex64> EntSize; - // Usually sections are not created implicitly, but loaded from YAML. - // When they are, this flag is used to signal about that. - bool IsImplicit; + Optional<yaml::BinaryRef> Content; + Optional<llvm::yaml::Hex64> Size; // Holds the original section index. unsigned OriginalSecNdx; - Section(ChunkKind Kind, bool IsImplicit = false) - : Chunk(Kind), IsImplicit(IsImplicit) {} + Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {} - static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; } + static bool classof(const Chunk *S) { + return S->Kind < ChunkKind::SpecialChunksStart; + } + + // Some derived sections might have their own special entries. This method + // returns a vector of <entry name, is used> pairs. It is used for section + // validation. + virtual std::vector<std::pair<StringRef, bool>> getEntries() const { + return {}; + }; // The following members are used to override section fields which is // useful for creating invalid objects. + // This can be used to override the sh_addralign field. + Optional<llvm::yaml::Hex64> ShAddrAlign; + // This can be used to override the offset stored in the sh_name field. // It does not affect the name stored in the string table. Optional<llvm::yaml::Hex64> ShName; @@ -206,6 +263,12 @@ struct Section : public Chunk { // This can be used to override the sh_flags field. Optional<llvm::yaml::Hex64> ShFlags; + + // This can be used to override the sh_type field. It is useful when we + // want to use specific YAML keys for a section of a particular type to + // describe the content, but still want to have a different final type + // for the section. + Optional<ELF_SHT> ShType; }; // Fill is a block of data which is placed outside of sections. It is @@ -215,18 +278,57 @@ struct Fill : Chunk { Optional<yaml::BinaryRef> Pattern; llvm::yaml::Hex64 Size; - Fill() : Chunk(ChunkKind::Fill) {} + Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {} static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; } }; +struct SectionHeaderTable : Chunk { + SectionHeaderTable(bool IsImplicit) + : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {} + + static bool classof(const Chunk *S) { + return S->Kind == ChunkKind::SectionHeaderTable; + } + + Optional<std::vector<SectionHeader>> Sections; + Optional<std::vector<SectionHeader>> Excluded; + Optional<bool> NoHeaders; + + size_t getNumHeaders(size_t SectionsNum) const { + if (IsImplicit) + return SectionsNum; + if (NoHeaders) + return (*NoHeaders) ? 0 : SectionsNum; + return (Sections ? Sections->size() : 0) + /*Null section*/ 1; + } + + static constexpr StringRef TypeStr = "SectionHeaderTable"; +}; + +struct BBAddrMapSection : Section { + Optional<std::vector<BBAddrMapEntry>> Entries; + + BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {} + + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + + static bool classof(const Chunk *S) { + return S->Kind == ChunkKind::BBAddrMap; + } +}; + struct StackSizesSection : Section { - Optional<yaml::BinaryRef> Content; - Optional<llvm::yaml::Hex64> Size; Optional<std::vector<StackSizeEntry>> Entries; StackSizesSection() : Section(ChunkKind::StackSizes) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::StackSizes; } @@ -237,17 +339,18 @@ struct StackSizesSection : Section { }; struct DynamicSection : Section { - std::vector<DynamicEntry> Entries; - Optional<yaml::BinaryRef> Content; + Optional<std::vector<DynamicEntry>> Entries; DynamicSection() : Section(ChunkKind::Dynamic) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; } }; struct RawContentSection : Section { - Optional<yaml::BinaryRef> Content; - Optional<llvm::yaml::Hex64> Size; Optional<llvm::yaml::Hex64> Info; RawContentSection() : Section(ChunkKind::RawContent) {} @@ -261,29 +364,31 @@ struct RawContentSection : Section { }; struct NoBitsSection : Section { - llvm::yaml::Hex64 Size; - NoBitsSection() : Section(ChunkKind::NoBits) {} static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; } }; struct NoteSection : Section { - Optional<yaml::BinaryRef> Content; - Optional<llvm::yaml::Hex64> Size; Optional<std::vector<ELFYAML::NoteEntry>> Notes; NoteSection() : Section(ChunkKind::Note) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Notes", Notes.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; } }; struct HashSection : Section { - Optional<yaml::BinaryRef> Content; - Optional<llvm::yaml::Hex64> Size; Optional<std::vector<uint32_t>> Bucket; Optional<std::vector<uint32_t>> Chain; + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}}; + }; + // The following members are used to override section fields. // This is useful for creating invalid objects. Optional<llvm::yaml::Hex64> NBucket; @@ -315,8 +420,6 @@ struct GnuHashHeader { }; struct GnuHashSection : Section { - Optional<yaml::BinaryRef> Content; - Optional<GnuHashHeader> Header; Optional<std::vector<llvm::yaml::Hex64>> BloomFilter; Optional<std::vector<llvm::yaml::Hex32>> HashBuckets; @@ -324,6 +427,13 @@ struct GnuHashSection : Section { GnuHashSection() : Section(ChunkKind::GnuHash) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Header", Header.hasValue()}, + {"BloomFilter", BloomFilter.hasValue()}, + {"HashBuckets", HashBuckets.hasValue()}, + {"HashValues", HashValues.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; } }; @@ -341,24 +451,29 @@ struct VerneedEntry { }; struct VerneedSection : Section { - Optional<yaml::BinaryRef> Content; Optional<std::vector<VerneedEntry>> VerneedV; - llvm::yaml::Hex64 Info; + Optional<llvm::yaml::Hex64> Info; VerneedSection() : Section(ChunkKind::Verneed) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Dependencies", VerneedV.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verneed; } }; struct AddrsigSection : Section { - Optional<yaml::BinaryRef> Content; - Optional<llvm::yaml::Hex64> Size; Optional<std::vector<YAMLFlowString>> Symbols; AddrsigSection() : Section(ChunkKind::Addrsig) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Symbols", Symbols.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; } }; @@ -369,10 +484,13 @@ struct LinkerOption { struct LinkerOptionsSection : Section { Optional<std::vector<LinkerOption>> Options; - Optional<yaml::BinaryRef> Content; LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Options", Options.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::LinkerOptions; } @@ -380,10 +498,13 @@ struct LinkerOptionsSection : Section { struct DependentLibrariesSection : Section { Optional<std::vector<YAMLFlowString>> Libs; - Optional<yaml::BinaryRef> Content; DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Libraries", Libs.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::DependentLibraries; } @@ -401,49 +522,62 @@ struct CallGraphEntry { struct CallGraphProfileSection : Section { Optional<std::vector<CallGraphEntry>> Entries; - Optional<yaml::BinaryRef> Content; CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::CallGraphProfile; } }; struct SymverSection : Section { - std::vector<uint16_t> Entries; + Optional<std::vector<uint16_t>> Entries; SymverSection() : Section(ChunkKind::Symver) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; } }; struct VerdefEntry { - uint16_t Version; - uint16_t Flags; - uint16_t VersionNdx; - uint32_t Hash; + Optional<uint16_t> Version; + Optional<uint16_t> Flags; + Optional<uint16_t> VersionNdx; + Optional<uint32_t> Hash; std::vector<StringRef> VerNames; }; struct VerdefSection : Section { Optional<std::vector<VerdefEntry>> Entries; - Optional<yaml::BinaryRef> Content; - - llvm::yaml::Hex64 Info; + Optional<llvm::yaml::Hex64> Info; VerdefSection() : Section(ChunkKind::Verdef) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; } }; -struct Group : Section { +struct GroupSection : Section { // Members of a group contain a flag and a list of section indices // that are part of the group. - std::vector<SectionOrType> Members; + Optional<std::vector<SectionOrType>> Members; Optional<StringRef> Signature; /* Info */ - Group() : Section(ChunkKind::Group) {} + GroupSection() : Section(ChunkKind::Group) {} + + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Members", Members.hasValue()}}; + }; static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; } }; @@ -456,11 +590,15 @@ struct Relocation { }; struct RelocationSection : Section { - std::vector<Relocation> Relocations; + Optional<std::vector<Relocation>> Relocations; StringRef RelocatableSec; /* Info */ RelocationSection() : Section(ChunkKind::Relocation) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Relocations", Relocations.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Relocation; } @@ -468,25 +606,51 @@ struct RelocationSection : Section { struct RelrSection : Section { Optional<std::vector<llvm::yaml::Hex64>> Entries; - Optional<yaml::BinaryRef> Content; RelrSection() : Section(ChunkKind::Relr) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Relr; } }; struct SymtabShndxSection : Section { - std::vector<uint32_t> Entries; + Optional<std::vector<uint32_t>> Entries; SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {} + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + static bool classof(const Chunk *S) { return S->Kind == ChunkKind::SymtabShndxSection; } }; +struct ARMIndexTableEntry { + llvm::yaml::Hex32 Offset; + llvm::yaml::Hex32 Value; +}; + +struct ARMIndexTableSection : Section { + Optional<std::vector<ARMIndexTableEntry>> Entries; + + ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {} + + std::vector<std::pair<StringRef, bool>> getEntries() const override { + return {{"Entries", Entries.hasValue()}}; + }; + + static bool classof(const Chunk *S) { + return S->Kind == ChunkKind::ARMIndexTable; + } +}; + // Represents .MIPS.abiflags section struct MipsABIFlags : Section { llvm::yaml::Hex16 Version; @@ -517,15 +681,15 @@ struct ProgramHeader { Optional<llvm::yaml::Hex64> FileSize; Optional<llvm::yaml::Hex64> MemSize; Optional<llvm::yaml::Hex64> Offset; + Optional<StringRef> FirstSec; + Optional<StringRef> LastSec; - std::vector<SectionName> Sections; - // This vector is parallel to Sections and contains corresponding chunks. + // This vector contains all chunks from [FirstSec, LastSec]. std::vector<Chunk *> Chunks; }; struct Object { FileHeader Header; - Optional<SectionHeaderTable> SectionHeaders; std::vector<ProgramHeader> ProgramHeaders; // An object might contain output section descriptions as well as @@ -547,12 +711,26 @@ struct Object { Ret.push_back(S); return Ret; } + + const SectionHeaderTable &getSectionHeaderTable() const { + for (const std::unique_ptr<Chunk> &C : Chunks) + if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) + return *S; + llvm_unreachable("the section header table chunk must always be present"); + } + + unsigned getMachine() const; }; +bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs, + const NoBitsSection &S); + } // end namespace ELFYAML } // end namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry) @@ -566,7 +744,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry) namespace llvm { namespace yaml { @@ -690,29 +868,33 @@ struct MappingTraits<ELFYAML::FileHeader> { static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); }; -template <> struct MappingTraits<ELFYAML::SectionHeaderTable> { - static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable); - static StringRef validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable); -}; - template <> struct MappingTraits<ELFYAML::SectionHeader> { static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr); }; template <> struct MappingTraits<ELFYAML::ProgramHeader> { static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr); + static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr); }; template <> struct MappingTraits<ELFYAML::Symbol> { static void mapping(IO &IO, ELFYAML::Symbol &Symbol); - static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol); + static std::string validate(IO &IO, ELFYAML::Symbol &Symbol); }; template <> struct MappingTraits<ELFYAML::StackSizeEntry> { static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel); }; +template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> { + static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel); +}; + +template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> { + static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel); +}; + template <> struct MappingTraits<ELFYAML::GnuHashHeader> { static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel); }; @@ -749,9 +931,13 @@ template <> struct MappingTraits<ELFYAML::Relocation> { static void mapping(IO &IO, ELFYAML::Relocation &Rel); }; +template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> { + static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E); +}; + template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> { static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C); - static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C); + static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C); }; template <> @@ -763,10 +949,6 @@ template <> struct MappingTraits<ELFYAML::SectionOrType> { static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType); }; -template <> struct MappingTraits<ELFYAML::SectionName> { - static void mapping(IO &IO, ELFYAML::SectionName §ionName); -}; - } // end namespace yaml } // end namespace llvm diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h index fb6780b6d0ed..94e66c5ae787 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h @@ -220,7 +220,7 @@ template <> struct MappingTraits<MachOYAML::Relocation> { template <> struct MappingTraits<MachOYAML::Section> { static void mapping(IO &IO, MachOYAML::Section &Section); - static StringRef validate(IO &io, MachOYAML::Section &Section); + static std::string validate(IO &io, MachOYAML::Section &Section); }; template <> struct MappingTraits<MachOYAML::NListEntry> { diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MinidumpYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MinidumpYAML.h index c1711a28dd84..b0cee541cef2 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MinidumpYAML.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MinidumpYAML.h @@ -236,7 +236,7 @@ template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> { template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> { static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S); - static StringRef validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S); + static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S); }; template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> { diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ObjectYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ObjectYAML.h index 0015fd3dc501..dd26ce3e9703 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ObjectYAML.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ObjectYAML.h @@ -9,6 +9,7 @@ #ifndef LLVM_OBJECTYAML_OBJECTYAML_H #define LLVM_OBJECTYAML_OBJECTYAML_H +#include "llvm/ObjectYAML/ArchiveYAML.h" #include "llvm/ObjectYAML/COFFYAML.h" #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/ObjectYAML/MachOYAML.h" @@ -23,6 +24,7 @@ namespace yaml { class IO; struct YamlObjectFile { + std::unique_ptr<ArchYAML::Archive> Arch; std::unique_ptr<ELFYAML::Object> Elf; std::unique_ptr<COFFYAML::Object> Coff; std::unique_ptr<MachOYAML::Object> MachO; diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h index bffb314e2d3b..80f1b4006205 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h @@ -53,6 +53,7 @@ struct Limits { struct Table { TableType ElemType; Limits TableLimits; + uint32_t Index; }; struct Export { @@ -220,6 +221,8 @@ struct NameSection : CustomSection { } std::vector<NameEntry> FunctionNames; + std::vector<NameEntry> GlobalNames; + std::vector<NameEntry> DataSegmentNames; }; struct LinkingSection : CustomSection { diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h index 34def363a55b..1f693475c946 100644 --- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h +++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h @@ -40,12 +40,17 @@ namespace WasmYAML { struct Object; } +namespace ArchYAML { +struct Archive; +} + namespace yaml { class Input; struct YamlObjectFile; using ErrorHandler = llvm::function_ref<void(const Twine &Msg)>; +bool yaml2archive(ArchYAML::Archive &Doc, raw_ostream &Out, ErrorHandler EH); bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH); bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, uint64_t MaxSize); |