Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/ObjectYAML/ArchiveYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/ArchiveYAML.h
new file mode 100644
index 0000000..8d05fee
--- /dev/null
+++ b/linux-x64/clang/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/linux-x64/clang/include/llvm/ObjectYAML/DWARFEmitter.h b/linux-x64/clang/include/llvm/ObjectYAML/DWARFEmitter.h
index 2ccc876..eb56d1e 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/DWARFEmitter.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -28,21 +28,28 @@
struct Data;
struct PubSection;
-void EmitDebugAbbrev(raw_ostream &OS, const Data &DI);
-void EmitDebugStr(raw_ostream &OS, const Data &DI);
+Error emitDebugAbbrev(raw_ostream &OS, const Data &DI);
+Error emitDebugStr(raw_ostream &OS, const Data &DI);
-void EmitDebugAranges(raw_ostream &OS, const Data &DI);
-void EmitPubSection(raw_ostream &OS, const PubSection &Sect,
- bool IsLittleEndian);
-void EmitDebugInfo(raw_ostream &OS, const Data &DI);
-void EmitDebugLine(raw_ostream &OS, const Data &DI);
+Error emitDebugAranges(raw_ostream &OS, const Data &DI);
+Error emitDebugRanges(raw_ostream &OS, const Data &DI);
+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);
-StringMap<std::unique_ptr<MemoryBuffer>>
-EmitDebugSections(llvm::DWARFYAML::Data &DI, bool ApplyFixups);
-
+emitDebugSections(StringRef YAMLString,
+ bool IsLittleEndian = sys::IsLittleEndianHost,
+ bool Is64BitAddrSize = true);
} // end namespace DWARFYAML
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/ObjectYAML/DWARFYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/DWARFYAML.h
index 78d736c..856cea9 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/DWARFYAML.h
@@ -15,35 +15,18 @@
#ifndef LLVM_OBJECTYAML_DWARFYAML_H
#define LLVM_OBJECTYAML_DWARFYAML_H
+#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;
@@ -51,26 +34,46 @@
};
struct Abbrev {
- llvm::yaml::Hex32 Code;
+ Optional<yaml::Hex64> Code;
llvm::dwarf::Tag Tag;
llvm::dwarf::Constants Children;
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 {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ 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;
};
+/// Class that describes a range list entry, or a base address selection entry
+/// within a range list in the .debug_ranges section.
+struct RangeEntry {
+ llvm::yaml::Hex64 LowOffset;
+ llvm::yaml::Hex64 HighOffset;
+};
+
+/// Class that describes a single range list inside the .debug_ranges section.
+struct Ranges {
+ Optional<llvm::yaml::Hex64> Offset;
+ Optional<llvm::yaml::Hex8> AddrSize;
+ std::vector<RangeEntry> Entries;
+};
+
struct PubEntry {
llvm::yaml::Hex32 DieOffset;
llvm::yaml::Hex8 Descriptor;
@@ -78,11 +81,11 @@
};
struct PubSection {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ yaml::Hex64 Length;
uint16_t Version;
uint32_t UnitOffset;
uint32_t UnitSize;
- bool IsGNUStyle = false;
std::vector<PubEntry> Entries;
};
@@ -97,12 +100,20 @@
std::vector<FormValue> Values;
};
+/// Class that contains helpful context information when mapping YAML into DWARF
+/// data structures.
+struct DWARFContext {
+ bool IsGNUPubSec = false;
+};
+
struct Unit {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ Optional<yaml::Hex64> Length;
uint16_t Version;
+ Optional<uint8_t> AddrSize;
llvm::dwarf::UnitType Type; // Added in DWARF 5
- uint32_t AbbrOffset;
- uint8_t AddrSize;
+ Optional<uint64_t> AbbrevTableID;
+ Optional<yaml::Hex64> AbbrOffset;
std::vector<Entry> Entries;
};
@@ -115,7 +126,7 @@
struct LineTableOpcode {
dwarf::LineNumberOps Opcode;
- uint64_t ExtLen;
+ Optional<uint64_t> ExtLen;
dwarf::LineNumberExtendedOps SubOpcode;
uint64_t Data;
int64_t SData;
@@ -125,48 +136,124 @@
};
struct LineTable {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ 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;
};
+struct SegAddrPair {
+ yaml::Hex64 Segment;
+ yaml::Hex64 Address;
+};
+
+struct AddrTableEntry {
+ dwarf::DwarfFormat Format;
+ Optional<yaml::Hex64> Length;
+ yaml::Hex16 Version;
+ Optional<yaml::Hex8> AddrSize;
+ yaml::Hex8 SegSelectorSize;
+ 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;
- std::vector<Abbrev> AbbrevDecls;
- std::vector<StringRef> DebugStrings;
- std::vector<ARange> ARanges;
- PubSection PubNames;
- PubSection PubTypes;
+ bool Is64BitAddrSize;
+ 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;
- PubSection GNUPubNames;
- PubSection GNUPubTypes;
+ Optional<PubSection> GNUPubNames;
+ Optional<PubSection> GNUPubTypes;
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> 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
} // end namespace llvm
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
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)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Ranges)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
@@ -174,6 +261,20 @@
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
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 {
@@ -182,6 +283,10 @@
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);
};
@@ -195,7 +300,15 @@
};
template <> struct MappingTraits<DWARFYAML::ARange> {
- static void mapping(IO &IO, DWARFYAML::ARange &Range);
+ static void mapping(IO &IO, DWARFYAML::ARange &ARange);
+};
+
+template <> struct MappingTraits<DWARFYAML::RangeEntry> {
+ static void mapping(IO &IO, DWARFYAML::RangeEntry &Entry);
+};
+
+template <> struct MappingTraits<DWARFYAML::Ranges> {
+ static void mapping(IO &IO, DWARFYAML::Ranges &Ranges);
};
template <> struct MappingTraits<DWARFYAML::PubEntry> {
@@ -230,11 +343,50 @@
static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
};
-template <> struct MappingTraits<DWARFYAML::InitialLength> {
- static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
+template <> struct MappingTraits<DWARFYAML::SegAddrPair> {
+ static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair);
};
-#define HANDLE_DW_TAG(unused, name, unused2, unused3) \
+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::StringOffsetsTable> {
+ static void mapping(IO &IO, DWARFYAML::StringOffsetsTable &StrOffsetsTable);
+};
+
+template <> struct ScalarEnumerationTraits<dwarf::DwarfFormat> {
+ static void enumeration(IO &IO, dwarf::DwarfFormat &Format) {
+ IO.enumCase(Format, "DWARF32", dwarf::DWARF32);
+ IO.enumCase(Format, "DWARF64", dwarf::DWARF64);
+ }
+};
+
+#define HANDLE_DW_TAG(unused, name, unused2, unused3, unused4) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
template <> struct ScalarEnumerationTraits<dwarf::Tag> {
@@ -302,6 +454,34 @@
}
};
+#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/linux-x64/clang/include/llvm/ObjectYAML/ELFYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/ELFYAML.h
index 68a0fc3..c9e9052 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/ELFYAML.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/ELFYAML.h
@@ -16,6 +16,9 @@
#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"
#include <cstdint>
@@ -25,6 +28,9 @@
namespace llvm {
namespace ELFYAML {
+StringRef dropUniqueSuffix(StringRef S);
+std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
+
// These types are invariant across 32/64-bit ELF, so for simplicity just
// directly give them their exact sizes. We don't need to worry about
// endianness because these are just the types in the YAMLIO structures,
@@ -54,8 +60,6 @@
LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
@@ -64,6 +68,41 @@
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
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_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 {
@@ -72,42 +111,40 @@
ELF_ELFOSABI OSABI;
llvm::yaml::Hex8 ABIVersion;
ELF_ET Type;
- ELF_EM Machine;
+ Optional<ELF_EM> Machine;
ELF_EF Flags;
llvm::yaml::Hex64 Entry;
- Optional<llvm::yaml::Hex16> SHEntSize;
- Optional<llvm::yaml::Hex16> SHOffset;
- Optional<llvm::yaml::Hex16> SHNum;
- Optional<llvm::yaml::Hex16> SHStrNdx;
+ Optional<llvm::yaml::Hex64> EPhOff;
+ Optional<llvm::yaml::Hex16> EPhEntSize;
+ Optional<llvm::yaml::Hex16> EPhNum;
+ Optional<llvm::yaml::Hex16> EShEntSize;
+ Optional<llvm::yaml::Hex64> EShOff;
+ Optional<llvm::yaml::Hex16> EShNum;
+ Optional<llvm::yaml::Hex16> EShStrNdx;
};
-struct SectionName {
- StringRef Section;
+struct SectionHeader {
+ StringRef Name;
};
-struct ProgramHeader {
- ELF_PT Type;
- ELF_PF Flags;
- llvm::yaml::Hex64 VAddr;
- llvm::yaml::Hex64 PAddr;
- Optional<llvm::yaml::Hex64> Align;
- Optional<llvm::yaml::Hex64> FileSize;
- Optional<llvm::yaml::Hex64> MemSize;
- Optional<llvm::yaml::Hex64> Offset;
- std::vector<SectionName> Sections;
+struct SectionHeaderTable {
+ Optional<std::vector<SectionHeader>> Sections;
+ Optional<std::vector<SectionHeader>> Excluded;
+ Optional<bool> NoHeaders;
};
struct Symbol {
StringRef Name;
- Optional<uint32_t> NameIndex;
ELF_STT Type;
- StringRef Section;
+ Optional<StringRef> Section;
Optional<ELF_SHN> Index;
ELF_STB Binding;
- llvm::yaml::Hex64 Value;
- llvm::yaml::Hex64 Size;
- uint8_t Other;
+ Optional<llvm::yaml::Hex64> Value;
+ Optional<llvm::yaml::Hex64> Size;
+ Optional<uint8_t> Other;
+
+ Optional<uint32_t> StName;
};
struct SectionOrType {
@@ -119,66 +156,260 @@
llvm::yaml::Hex64 Val;
};
-struct Section {
- enum class SectionKind {
+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;
+};
+
+struct NoteEntry {
+ StringRef Name;
+ yaml::BinaryRef Desc;
+ llvm::yaml::Hex32 Type;
+};
+
+struct Chunk {
+ enum class ChunkKind {
Dynamic,
Group,
RawContent,
Relocation,
+ Relr,
NoBits,
+ Note,
+ Hash,
+ GnuHash,
Verdef,
Verneed,
+ StackSizes,
+ SymtabShndxSection,
Symver,
- MipsABIFlags
+ ARMIndexTable,
+ MipsABIFlags,
+ Addrsig,
+ Fill,
+ LinkerOptions,
+ DependentLibraries,
+ CallGraphProfile,
+ BBAddrMap
};
- SectionKind Kind;
+
+ ChunkKind Kind;
StringRef Name;
+ Optional<llvm::yaml::Hex64> Offset;
+
+ Chunk(ChunkKind K) : Kind(K) {}
+ virtual ~Chunk();
+};
+
+struct Section : public Chunk {
ELF_SHT Type;
Optional<ELF_SHF> Flags;
- llvm::yaml::Hex64 Address;
- StringRef Link;
+ Optional<llvm::yaml::Hex64> Address;
+ Optional<StringRef> Link;
llvm::yaml::Hex64 AddressAlign;
Optional<llvm::yaml::Hex64> EntSize;
+ Optional<yaml::BinaryRef> Content;
+ Optional<llvm::yaml::Hex64> Size;
+
+ // Usually sections are not created implicitly, but loaded from YAML.
+ // When they are, this flag is used to signal about that.
+ bool IsImplicit;
+
+ // Holds the original section index.
+ unsigned OriginalSecNdx;
+
+ Section(ChunkKind Kind, bool IsImplicit = false)
+ : Chunk(Kind), IsImplicit(IsImplicit) {}
+
+ static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
+
+ // 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;
+
// This can be used to override the sh_offset field. It does not place the
- // section data at the offset specified. Useful for creating invalid objects.
+ // section data at the offset specified.
Optional<llvm::yaml::Hex64> ShOffset;
- Section(SectionKind Kind) : Kind(Kind) {}
- virtual ~Section();
+ // This can be used to override the sh_size field. It does not affect the
+ // content written.
+ Optional<llvm::yaml::Hex64> ShSize;
+
+ // 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
+// not present in the sections header table, but it might affect the output file
+// size and program headers produced.
+struct Fill : Chunk {
+ Optional<yaml::BinaryRef> Pattern;
+ llvm::yaml::Hex64 Size;
+
+ Fill() : Chunk(ChunkKind::Fill) {}
+
+ static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
+};
+
+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<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;
+ }
+
+ static bool nameMatches(StringRef Name) {
+ return Name == ".stack_sizes";
+ }
};
struct DynamicSection : Section {
- std::vector<DynamicEntry> Entries;
- Optional<yaml::BinaryRef> Content;
+ Optional<std::vector<DynamicEntry>> Entries;
- DynamicSection() : Section(SectionKind::Dynamic) {}
+ DynamicSection() : Section(ChunkKind::Dynamic) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::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(SectionKind::RawContent) {}
+ RawContentSection() : Section(ChunkKind::RawContent) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::RawContent;
+ static bool classof(const Chunk *S) {
+ return S->Kind == ChunkKind::RawContent;
}
+
+ // Is used when a content is read as an array of bytes.
+ Optional<std::vector<uint8_t>> ContentBuf;
};
struct NoBitsSection : Section {
- llvm::yaml::Hex64 Size;
+ NoBitsSection() : Section(ChunkKind::NoBits) {}
- NoBitsSection() : Section(SectionKind::NoBits) {}
+ static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
+};
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::NoBits;
- }
+struct NoteSection : Section {
+ 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<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;
+ Optional<llvm::yaml::Hex64> NChain;
+
+ HashSection() : Section(ChunkKind::Hash) {}
+
+ static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
+};
+
+struct GnuHashHeader {
+ // The number of hash buckets.
+ // Not used when dumping the object, but can be used to override
+ // the real number of buckets when emiting an object from a YAML document.
+ Optional<llvm::yaml::Hex32> NBuckets;
+
+ // Index of the first symbol in the dynamic symbol table
+ // included in the hash table.
+ llvm::yaml::Hex32 SymNdx;
+
+ // The number of words in the Bloom filter.
+ // Not used when dumping the object, but can be used to override the real
+ // number of words in the Bloom filter when emiting an object from a YAML
+ // document.
+ Optional<llvm::yaml::Hex32> MaskWords;
+
+ // A shift constant used by the Bloom filter.
+ llvm::yaml::Hex32 Shift2;
+};
+
+struct GnuHashSection : Section {
+ Optional<GnuHashHeader> Header;
+ Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
+ Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
+ Optional<std::vector<llvm::yaml::Hex32>> HashValues;
+
+ 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; }
};
struct VernauxEntry {
@@ -195,73 +426,204 @@
};
struct VerneedSection : Section {
- std::vector<VerneedEntry> VerneedV;
+ Optional<std::vector<VerneedEntry>> VerneedV;
llvm::yaml::Hex64 Info;
- VerneedSection() : Section(SectionKind::Verneed) {}
+ VerneedSection() : Section(ChunkKind::Verneed) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::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<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; }
+};
+
+struct LinkerOption {
+ StringRef Key;
+ StringRef Value;
+};
+
+struct LinkerOptionsSection : Section {
+ Optional<std::vector<LinkerOption>> Options;
+
+ 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;
+ }
+};
+
+struct DependentLibrariesSection : Section {
+ Optional<std::vector<YAMLFlowString>> Libs;
+
+ 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;
+ }
+};
+
+// Represents the call graph profile section entry.
+struct CallGraphEntry {
+ // The symbol of the source of the edge.
+ StringRef From;
+ // The symbol index of the destination of the edge.
+ StringRef To;
+ // The weight of the edge.
+ uint64_t Weight;
+};
+
+struct CallGraphProfileSection : Section {
+ Optional<std::vector<CallGraphEntry>> Entries;
+
+ 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(SectionKind::Symver) {}
+ SymverSection() : Section(ChunkKind::Symver) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::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 {
- std::vector<VerdefEntry> Entries;
+ Optional<std::vector<VerdefEntry>> Entries;
+
llvm::yaml::Hex64 Info;
- VerdefSection() : Section(SectionKind::Verdef) {}
+ VerdefSection() : Section(ChunkKind::Verdef) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::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;
- StringRef Signature; /* Info */
+ Optional<std::vector<SectionOrType>> Members;
+ Optional<StringRef> Signature; /* Info */
- Group() : Section(SectionKind::Group) {}
+ GroupSection() : Section(ChunkKind::Group) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::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; }
};
struct Relocation {
llvm::yaml::Hex64 Offset;
- int64_t Addend;
+ YAMLIntUInt Addend;
ELF_REL Type;
Optional<StringRef> Symbol;
};
struct RelocationSection : Section {
- std::vector<Relocation> Relocations;
+ Optional<std::vector<Relocation>> Relocations;
StringRef RelocatableSec; /* Info */
- RelocationSection() : Section(SectionKind::Relocation) {}
+ RelocationSection() : Section(ChunkKind::Relocation) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::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;
+ }
+};
+
+struct RelrSection : Section {
+ Optional<std::vector<llvm::yaml::Hex64>> Entries;
+
+ 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 {
+ 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;
}
};
@@ -279,42 +641,92 @@
MIPS_AFL_FLAGS1 Flags1;
llvm::yaml::Hex32 Flags2;
- MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
+ MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::MipsABIFlags;
+ static bool classof(const Chunk *S) {
+ return S->Kind == ChunkKind::MipsABIFlags;
}
};
+struct ProgramHeader {
+ ELF_PT Type;
+ ELF_PF Flags;
+ llvm::yaml::Hex64 VAddr;
+ llvm::yaml::Hex64 PAddr;
+ Optional<llvm::yaml::Hex64> Align;
+ Optional<llvm::yaml::Hex64> FileSize;
+ Optional<llvm::yaml::Hex64> MemSize;
+ Optional<llvm::yaml::Hex64> Offset;
+ Optional<StringRef> FirstSec;
+ Optional<StringRef> LastSec;
+
+ // This vector contains all chunks from [FirstSec, LastSec].
+ std::vector<Chunk *> Chunks;
+};
+
struct Object {
FileHeader Header;
+ Optional<SectionHeaderTable> SectionHeaders;
std::vector<ProgramHeader> ProgramHeaders;
- std::vector<std::unique_ptr<Section>> Sections;
+
+ // An object might contain output section descriptions as well as
+ // custom data that does not belong to any section.
+ std::vector<std::unique_ptr<Chunk>> Chunks;
+
// Although in reality the symbols reside in a section, it is a lot
// cleaner and nicer if we read them from the YAML as a separate
// top-level key, which automatically ensures that invariants like there
// being a single SHT_SYMTAB section are upheld.
- std::vector<Symbol> Symbols;
- std::vector<Symbol> DynamicSymbols;
+ Optional<std::vector<Symbol>> Symbols;
+ Optional<std::vector<Symbol>> DynamicSymbols;
+ Optional<DWARFYAML::Data> DWARF;
+
+ std::vector<Section *> getSections() {
+ std::vector<Section *> Ret;
+ for (const std::unique_ptr<Chunk> &Sec : Chunks)
+ if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
+ Ret.push_back(S);
+ return Ret;
+ }
+
+ 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)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
-LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
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 {
+template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
+ static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
+ raw_ostream &Out);
+ static StringRef input(StringRef Scalar, void *Ctx,
+ ELFYAML::YAMLIntUInt &Val);
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
+};
+
template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
@@ -377,16 +789,6 @@
};
template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
- static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<ELFYAML::ELF_STO> {
- static void bitset(IO &IO, ELFYAML::ELF_STO &Value);
-};
-
-template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
};
@@ -436,20 +838,50 @@
static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
};
+template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
+ static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
+ static std::string 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);
};
template <> struct MappingTraits<ELFYAML::DynamicEntry> {
static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
};
+template <> struct MappingTraits<ELFYAML::NoteEntry> {
+ static void mapping(IO &IO, ELFYAML::NoteEntry &N);
+};
+
template <> struct MappingTraits<ELFYAML::VerdefEntry> {
static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
};
@@ -462,14 +894,25 @@
static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
};
+template <> struct MappingTraits<ELFYAML::LinkerOption> {
+ static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
+};
+
+template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
+ static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
+};
+
template <> struct MappingTraits<ELFYAML::Relocation> {
static void mapping(IO &IO, ELFYAML::Relocation &Rel);
};
-template <>
-struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
- static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
- static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
+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 std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
};
template <>
@@ -481,10 +924,6 @@
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/linux-x64/clang/include/llvm/ObjectYAML/MachOYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/MachOYAML.h
index d7e1c03..94e66c5 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/MachOYAML.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/MachOYAML.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
+#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
#include <cstdint>
#include <string>
@@ -26,6 +27,20 @@
namespace llvm {
namespace MachOYAML {
+struct Relocation {
+ // Offset in the section to what is being relocated.
+ llvm::yaml::Hex32 address;
+ // Symbol index if r_extern == 1 else section index.
+ uint32_t symbolnum;
+ bool is_pcrel;
+ // Real length = 2 ^ length.
+ uint8_t length;
+ bool is_extern;
+ uint8_t type;
+ bool is_scattered;
+ int32_t value;
+};
+
struct Section {
char sectname[16];
char segname[16];
@@ -39,6 +54,8 @@
llvm::yaml::Hex32 reserved1;
llvm::yaml::Hex32 reserved2;
llvm::yaml::Hex32 reserved3;
+ Optional<llvm::yaml::BinaryRef> content;
+ std::vector<Relocation> relocations;
};
struct FileHeader {
@@ -141,6 +158,7 @@
} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Relocation)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
@@ -196,8 +214,13 @@
static void mapping(IO &IO, MachOYAML::ExportEntry &ExportEntry);
};
+template <> struct MappingTraits<MachOYAML::Relocation> {
+ static void mapping(IO &IO, MachOYAML::Relocation &R);
+};
+
template <> struct MappingTraits<MachOYAML::Section> {
static void mapping(IO &IO, MachOYAML::Section &Section);
+ static std::string validate(IO &io, MachOYAML::Section &Section);
};
template <> struct MappingTraits<MachOYAML::NListEntry> {
diff --git a/linux-x64/clang/include/llvm/ObjectYAML/MinidumpYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/MinidumpYAML.h
index 39fdd62..b0cee54 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/MinidumpYAML.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/MinidumpYAML.h
@@ -26,6 +26,8 @@
/// from Types to Kinds is fixed and given by the static getKind function.
struct Stream {
enum class StreamKind {
+ Exception,
+ MemoryInfoList,
MemoryList,
ModuleList,
RawContent,
@@ -102,6 +104,45 @@
using ThreadListStream = detail::ListStream<detail::ParsedThread>;
using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
+/// ExceptionStream minidump stream.
+struct ExceptionStream : public Stream {
+ minidump::ExceptionStream MDExceptionStream;
+ yaml::BinaryRef ThreadContext;
+
+ ExceptionStream()
+ : Stream(StreamKind::Exception, minidump::StreamType::Exception),
+ MDExceptionStream({}) {}
+
+ explicit ExceptionStream(const minidump::ExceptionStream &MDExceptionStream,
+ ArrayRef<uint8_t> ThreadContext)
+ : Stream(StreamKind::Exception, minidump::StreamType::Exception),
+ MDExceptionStream(MDExceptionStream), ThreadContext(ThreadContext) {}
+
+ static bool classof(const Stream *S) {
+ return S->Kind == StreamKind::Exception;
+ }
+};
+
+/// A structure containing the list of MemoryInfo entries comprising a
+/// MemoryInfoList stream.
+struct MemoryInfoListStream : public Stream {
+ std::vector<minidump::MemoryInfo> Infos;
+
+ MemoryInfoListStream()
+ : Stream(StreamKind::MemoryInfoList,
+ minidump::StreamType::MemoryInfoList) {}
+
+ explicit MemoryInfoListStream(
+ iterator_range<object::MinidumpFile::MemoryInfoIterator> Range)
+ : Stream(StreamKind::MemoryInfoList,
+ minidump::StreamType::MemoryInfoList),
+ Infos(Range.begin(), Range.end()) {}
+
+ static bool classof(const Stream *S) {
+ return S->Kind == StreamKind::MemoryInfoList;
+ }
+};
+
/// A minidump stream represented as a sequence of hex bytes. This is used as a
/// fallback when no other stream kind is suitable.
struct RawContentStream : public Stream {
@@ -122,16 +163,16 @@
minidump::SystemInfo Info;
std::string CSDVersion;
- explicit SystemInfoStream(const minidump::SystemInfo &Info,
- std::string CSDVersion)
- : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
- Info(Info), CSDVersion(std::move(CSDVersion)) {}
-
SystemInfoStream()
: Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo) {
memset(&Info, 0, sizeof(Info));
}
+ explicit SystemInfoStream(const minidump::SystemInfo &Info,
+ std::string CSDVersion)
+ : Stream(StreamKind::SystemInfo, minidump::StreamType::SystemInfo),
+ Info(Info), CSDVersion(std::move(CSDVersion)) {}
+
static bool classof(const Stream *S) {
return S->Kind == StreamKind::SystemInfo;
}
@@ -177,12 +218,6 @@
static Expected<Object> create(const object::MinidumpFile &File);
};
-/// Serialize the minidump file represented by Obj to OS in binary form.
-void writeAsBinary(Object &Obj, raw_ostream &OS);
-
-/// Serialize the yaml string as a minidump file to OS in binary form.
-Error writeAsBinary(StringRef Yaml, raw_ostream &OS);
-
} // namespace MinidumpYAML
namespace yaml {
@@ -201,7 +236,7 @@
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> {
@@ -213,6 +248,10 @@
} // namespace llvm
+LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryProtection)
+LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryState)
+LLVM_YAML_DECLARE_BITSET_TRAITS(llvm::minidump::MemoryType)
+
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::ProcessorArchitecture)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::OSPlatform)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::minidump::StreamType)
@@ -220,6 +259,8 @@
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::ArmInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::OtherInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::Exception)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(
@@ -233,6 +274,7 @@
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
diff --git a/linux-x64/clang/include/llvm/ObjectYAML/ObjectYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/ObjectYAML.h
index 0015fd3..dd26ce3 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/ObjectYAML.h
+++ b/linux-x64/clang/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 @@
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/linux-x64/clang/include/llvm/ObjectYAML/WasmYAML.h b/linux-x64/clang/include/llvm/ObjectYAML/WasmYAML.h
index 2411dc7..80f1b40 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/WasmYAML.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/WasmYAML.h
@@ -53,6 +53,7 @@
struct Table {
TableType ElemType;
Limits TableLimits;
+ uint32_t Index;
};
struct Export {
@@ -107,8 +108,10 @@
struct Relocation {
RelocType Type;
uint32_t Index;
+ // TODO(wvo): this would strictly be better as Hex64, but that will change
+ // all existing obj2yaml output.
yaml::Hex32 Offset;
- int32_t Addend;
+ int64_t Addend;
};
struct DataSegment {
@@ -145,7 +148,7 @@
uint32_t Index;
SignatureForm Form = wasm::WASM_TYPE_FUNC;
std::vector<ValueType> ParamTypes;
- ValueType ReturnType;
+ std::vector<ValueType> ReturnTypes;
};
struct SymbolInfo {
@@ -218,6 +221,8 @@
}
std::vector<NameEntry> FunctionNames;
+ std::vector<NameEntry> GlobalNames;
+ std::vector<NameEntry> DataSegmentNames;
};
struct LinkingSection : CustomSection {
@@ -309,16 +314,6 @@
std::vector<Limits> Memories;
};
-struct GlobalSection : Section {
- GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
-
- static bool classof(const Section *S) {
- return S->Type == wasm::WASM_SEC_GLOBAL;
- }
-
- std::vector<Global> Globals;
-};
-
struct EventSection : Section {
EventSection() : Section(wasm::WASM_SEC_EVENT) {}
@@ -329,6 +324,16 @@
std::vector<Event> Events;
};
+struct GlobalSection : Section {
+ GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
+
+ static bool classof(const Section *S) {
+ return S->Type == wasm::WASM_SEC_GLOBAL;
+ }
+
+ std::vector<Global> Globals;
+};
+
struct ExportSection : Section {
ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
diff --git a/linux-x64/clang/include/llvm/ObjectYAML/YAML.h b/linux-x64/clang/include/llvm/ObjectYAML/YAML.h
index 3701410..3bf6527 100644
--- a/linux-x64/clang/include/llvm/ObjectYAML/YAML.h
+++ b/linux-x64/clang/include/llvm/ObjectYAML/YAML.h
@@ -85,7 +85,8 @@
/// Write the contents (regardless of whether it is binary or a
/// hex string) as binary to the given raw_ostream.
- void writeAsBinary(raw_ostream &OS) const;
+ /// N can be used to specify the maximum number of bytes.
+ void writeAsBinary(raw_ostream &OS, uint64_t N = UINT64_MAX) const;
/// Write the contents (regardless of whether it is binary or a
/// hex string) as hex to the given raw_ostream.
diff --git a/linux-x64/clang/include/llvm/ObjectYAML/yaml2obj.h b/linux-x64/clang/include/llvm/ObjectYAML/yaml2obj.h
new file mode 100644
index 0000000..1f69347
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ObjectYAML/yaml2obj.h
@@ -0,0 +1,73 @@
+//===--- yaml2obj.h - -------------------------------------------*- 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
+/// Common declarations for yaml2obj
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TOOLS_YAML2OBJ_YAML2OBJ_H
+#define LLVM_TOOLS_YAML2OBJ_YAML2OBJ_H
+
+#include "llvm/ADT/STLExtras.h"
+#include <memory>
+
+namespace llvm {
+class raw_ostream;
+template <typename T> class SmallVectorImpl;
+class StringRef;
+class Twine;
+
+namespace object {
+class ObjectFile;
+}
+
+namespace COFFYAML {
+struct Object;
+}
+
+namespace ELFYAML {
+struct Object;
+}
+
+namespace MinidumpYAML {
+struct Object;
+}
+
+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);
+bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out, ErrorHandler EH);
+bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out,
+ ErrorHandler EH);
+bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
+
+bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
+ unsigned DocNum = 1, uint64_t MaxSize = UINT64_MAX);
+
+/// Convenience function for tests.
+std::unique_ptr<object::ObjectFile>
+yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml,
+ ErrorHandler ErrHandler);
+
+} // namespace yaml
+} // namespace llvm
+
+#endif