Update prebuilt Clang to r365631c1 from Android.
The version we had was segfaulting.
Bug: 132420445
Change-Id: Icb45a6fe0b4e2166f7895e669df1157cec9fb4e0
diff --git a/linux-x64/clang/include/llvm/Object/ArchiveWriter.h b/linux-x64/clang/include/llvm/Object/ArchiveWriter.h
index 4e796eb..9e6daf2 100644
--- a/linux-x64/clang/include/llvm/Object/ArchiveWriter.h
+++ b/linux-x64/clang/include/llvm/Object/ArchiveWriter.h
@@ -26,7 +26,6 @@
sys::TimePoint<std::chrono::seconds> ModTime;
unsigned UID = 0, GID = 0, Perms = 0644;
- bool IsNew = false;
NewArchiveMember() = default;
NewArchiveMember(MemoryBufferRef BufRef);
@@ -37,6 +36,8 @@
bool Deterministic);
};
+Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
+
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
bool WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
diff --git a/linux-x64/clang/include/llvm/Object/Binary.h b/linux-x64/clang/include/llvm/Object/Binary.h
index 8ce2d5a..3c3e977 100644
--- a/linux-x64/clang/include/llvm/Object/Binary.h
+++ b/linux-x64/clang/include/llvm/Object/Binary.h
@@ -13,6 +13,7 @@
#ifndef LLVM_OBJECT_BINARY_H
#define LLVM_OBJECT_BINARY_H
+#include "llvm-c/Types.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/Error.h"
@@ -41,7 +42,9 @@
ID_Archive,
ID_MachOUniversalBinary,
ID_COFFImportFile,
- ID_IR, // LLVM IR
+ ID_IR, // LLVM IR
+
+ ID_Minidump,
ID_WinRes, // Windows resource (.res) file.
@@ -49,6 +52,9 @@
ID_StartObjects,
ID_COFF,
+ ID_XCOFF32, // AIX XCOFF 32-bit
+ ID_XCOFF64, // AIX XCOFF 64-bit
+
ID_ELF32L, // ELF 32-bit, little endian
ID_ELF32B, // ELF 32-bit, big endian
ID_ELF64L, // ELF 64-bit, little endian
@@ -117,6 +123,8 @@
return TypeID == ID_COFF;
}
+ bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
+
bool isWasm() const { return TypeID == ID_Wasm; }
bool isCOFFImportFile() const {
@@ -127,6 +135,8 @@
return TypeID == ID_IR;
}
+ bool isMinidump() const { return TypeID == ID_Minidump; }
+
bool isLittleEndian() const {
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
@@ -155,6 +165,9 @@
}
};
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
+
/// Create a Binary from Source, autodetecting the file type.
///
/// @param Source The data to create the Binary from.
diff --git a/linux-x64/clang/include/llvm/Object/COFF.h b/linux-x64/clang/include/llvm/Object/COFF.h
index c22a482..c53cbc4 100644
--- a/linux-x64/clang/include/llvm/Object/COFF.h
+++ b/linux-x64/clang/include/llvm/Object/COFF.h
@@ -897,13 +897,12 @@
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
- std::error_code getSectionName(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
- std::error_code getSectionContents(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
uint64_t getSectionAlignment(DataRefImpl Sec) const override;
bool isSectionCompressed(DataRefImpl Sec) const override;
bool isSectionText(DataRefImpl Sec) const override;
@@ -1033,10 +1032,10 @@
ArrayRef<coff_relocation> getRelocations(const coff_section *Sec) const;
- std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
+ Expected<StringRef> getSectionName(const coff_section *Sec) const;
uint64_t getSectionSize(const coff_section *Sec) const;
- std::error_code getSectionContents(const coff_section *Sec,
- ArrayRef<uint8_t> &Res) const;
+ Error getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const;
uint64_t getImageBase() const;
std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
diff --git a/linux-x64/clang/include/llvm/Object/COFFImportFile.h b/linux-x64/clang/include/llvm/Object/COFFImportFile.h
index d051d7f..5aa8364 100644
--- a/linux-x64/clang/include/llvm/Object/COFFImportFile.h
+++ b/linux-x64/clang/include/llvm/Object/COFFImportFile.h
@@ -36,12 +36,11 @@
void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
- std::error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const override {
+ Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override {
if (Symb.p == 0)
OS << "__imp_";
OS << StringRef(Data.getBufferStart() + sizeof(coff_import_header));
- return std::error_code();
+ return Error::success();
}
uint32_t getSymbolFlags(DataRefImpl Symb) const override {
@@ -70,9 +69,21 @@
};
struct COFFShortExport {
+ /// The name of the export as specified in the .def file or on the command
+ /// line, i.e. "foo" in "/EXPORT:foo", and "bar" in "/EXPORT:foo=bar". This
+ /// may lack mangling, such as underscore prefixing and stdcall suffixing.
std::string Name;
+
+ /// The external, exported name. Only non-empty when export renaming is in
+ /// effect, i.e. "foo" in "/EXPORT:foo=bar".
std::string ExtName;
+
+ /// The real, mangled symbol name from the object file. Given
+ /// "/export:foo=bar", this could be "_bar@8" if bar is stdcall.
std::string SymbolName;
+
+ /// Creates a weak alias. This is the name of the weak aliasee. In a .def
+ /// file, this is "baz" in "EXPORTS\nfoo = bar == baz".
std::string AliasTarget;
uint16_t Ordinal = 0;
diff --git a/linux-x64/clang/include/llvm/Object/ELF.h b/linux-x64/clang/include/llvm/Object/ELF.h
index 1ba32b4..cab2974 100644
--- a/linux-x64/clang/include/llvm/Object/ELF.h
+++ b/linux-x64/clang/include/llvm/Object/ELF.h
@@ -44,10 +44,26 @@
(uint8_t)Object[ELF::EI_DATA]);
}
-static inline Error createError(StringRef Err) {
+static inline Error createError(const Twine &Err) {
return make_error<StringError>(Err, object_error::parse_failed);
}
+template <class ELFT> class ELFFile;
+
+template <class ELFT>
+std::string getSecIndexForError(const ELFFile<ELFT> *Obj,
+ const typename ELFT::Shdr *Sec) {
+ auto TableOrErr = Obj->sections();
+ if (TableOrErr)
+ return "[index " + std::to_string(Sec - &TableOrErr->front()) + "]";
+ // To make this helper be more convenient for error reporting purposes we
+ // drop the error. But really it should never be triggered. Before this point,
+ // our code should have called 'sections()' and reported a proper error on
+ // failure.
+ llvm::consumeError(TableOrErr.takeError());
+ return "[unknown index]";
+}
+
template <class ELFT>
class ELFFile {
public:
@@ -79,9 +95,7 @@
using Elf_Relr_Range = typename ELFT::RelrRange;
using Elf_Phdr_Range = typename ELFT::PhdrRange;
- const uint8_t *base() const {
- return reinterpret_cast<const uint8_t *>(Buf.data());
- }
+ const uint8_t *base() const { return Buf.bytes_begin(); }
size_t getBufSize() const { return Buf.size(); }
@@ -114,8 +128,8 @@
SmallVectorImpl<char> &Result) const;
uint32_t getRelativeRelocationType() const;
- const char *getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
- const char *getDynamicTagAsString(uint64_t Type) const;
+ std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
+ std::string getDynamicTagAsString(uint64_t Type) const;
/// Get the symbol for a given relocation.
Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
@@ -164,11 +178,16 @@
/// Iterate over program header table.
Expected<Elf_Phdr_Range> program_headers() const {
if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
- return createError("invalid e_phentsize");
+ return createError("invalid e_phentsize: " +
+ Twine(getHeader()->e_phentsize));
if (getHeader()->e_phoff +
(getHeader()->e_phnum * getHeader()->e_phentsize) >
getBufSize())
- return createError("program headers longer than binary");
+ return createError("program headers are longer than binary of size " +
+ Twine(getBufSize()) + ": e_phoff = 0x" +
+ Twine::utohexstr(getHeader()->e_phoff) +
+ ", e_phnum = " + Twine(getHeader()->e_phnum) +
+ ", e_phentsize = " + Twine(getHeader()->e_phentsize));
auto *Begin =
reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
@@ -183,10 +202,12 @@
/// be checked after iteration ends.
Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
if (Phdr.p_type != ELF::PT_NOTE) {
+ // TODO: this error is untested.
Err = createError("attempt to iterate notes of non-note program header");
return Elf_Note_Iterator(Err);
}
if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
+ // TODO: this error is untested.
Err = createError("invalid program header offset/size");
return Elf_Note_Iterator(Err);
}
@@ -202,10 +223,12 @@
/// be checked after iteration ends.
Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
if (Shdr.sh_type != ELF::SHT_NOTE) {
+ // TODO: this error is untested.
Err = createError("attempt to iterate notes of non-note section");
return Elf_Note_Iterator(Err);
}
if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
+ // TODO: this error is untested.
Err = createError("invalid section offset/size");
return Elf_Note_Iterator(Err);
}
@@ -273,7 +296,7 @@
inline Expected<const typename ELFT::Shdr *>
getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
if (Index >= Sections.size())
- return createError("invalid section index");
+ return createError("invalid section index: " + Twine(Index));
return &Sections[Index];
}
@@ -285,7 +308,10 @@
assert(Sym->st_shndx == ELF::SHN_XINDEX);
unsigned Index = Sym - FirstSym;
if (Index >= ShndxTable.size())
- return createError("index past the end of the symbol table");
+ return createError(
+ "extended symbol index (" + Twine(Index) +
+ ") is past the end of the SHT_SYMTAB_SHNDX section of size " +
+ Twine(ShndxTable.size()));
// The size of the table was checked in getSHNDXTable.
return ShndxTable[Index];
@@ -335,6 +361,7 @@
inline Expected<const typename ELFT::Sym *>
getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
if (Index >= Symbols.size())
+ // TODO: this error is untested.
return createError("invalid symbol index");
return &Symbols[Index];
}
@@ -353,18 +380,26 @@
Expected<ArrayRef<T>>
ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
- return createError("invalid sh_entsize");
+ return createError("section " + getSecIndexForError(this, Sec) +
+ " has an invalid sh_entsize: " + Twine(Sec->sh_entsize));
uintX_t Offset = Sec->sh_offset;
uintX_t Size = Sec->sh_size;
if (Size % sizeof(T))
- return createError("size is not a multiple of sh_entsize");
+ return createError("section " + getSecIndexForError(this, Sec) +
+ " has an invalid sh_size (" + Twine(Size) +
+ ") which is not a multiple of its sh_entsize (" +
+ Twine(Sec->sh_entsize) + ")");
if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
Offset + Size > Buf.size())
- return createError("invalid section offset");
+ return createError("section " + getSecIndexForError(this, Sec) +
+ " has a sh_offset (0x" + Twine::utohexstr(Offset) +
+ ") + sh_size (0x" + Twine(Size) +
+ ") that cannot be represented");
if (Offset % alignof(T))
+ // TODO: this error is untested.
return createError("unaligned data");
const T *Start = reinterpret_cast<const T *>(base() + Offset);
@@ -438,6 +473,7 @@
if (!Index) // no section string table.
return "";
if (Index >= Sections.size())
+ // TODO: this error is untested.
return createError("invalid section index");
return getStringTable(&Sections[Index]);
}
@@ -447,7 +483,9 @@
template <class ELFT>
Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
if (sizeof(Elf_Ehdr) > Object.size())
- return createError("Invalid buffer");
+ return createError("invalid buffer: the size (" + Twine(Object.size()) +
+ ") is smaller than an ELF header (" +
+ Twine(sizeof(Elf_Ehdr)) + ")");
return ELFFile(Object);
}
@@ -458,16 +496,18 @@
return ArrayRef<Elf_Shdr>();
if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
- return createError(
- "invalid section header entry size (e_shentsize) in ELF header");
+ return createError("invalid e_shentsize in ELF header: " +
+ Twine(getHeader()->e_shentsize));
const uint64_t FileSize = Buf.size();
-
if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
- return createError("section header table goes past the end of the file");
+ return createError(
+ "section header table goes past the end of the file: e_shoff = 0x" +
+ Twine::utohexstr(SectionTableOffset));
// Invalid address alignment of section headers
if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
+ // TODO: this error is untested.
return createError("invalid alignment of section headers");
const Elf_Shdr *First =
@@ -478,6 +518,7 @@
NumSections = First->sh_size;
if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
+ // TODO: this error is untested.
return createError("section table goes past the end of file");
const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
@@ -504,10 +545,14 @@
Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
uint32_t Entry) const {
if (sizeof(T) != Section->sh_entsize)
+ // TODO: this error is untested.
return createError("invalid sh_entsize");
size_t Pos = Section->sh_offset + Entry * sizeof(T);
if (Pos + sizeof(T) > Buf.size())
- return createError("invalid section offset");
+ return createError("unable to access section " +
+ getSecIndexForError(this, Section) + " data at 0x" +
+ Twine::utohexstr(Pos) +
+ ": offset goes past the end of file");
return reinterpret_cast<const T *>(base() + Pos);
}
@@ -533,6 +578,7 @@
if (*SecNameOrErr == SectionName)
return &Sec;
}
+ // TODO: this error is untested.
return createError("invalid section name");
}
@@ -540,15 +586,24 @@
Expected<StringRef>
ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
if (Section->sh_type != ELF::SHT_STRTAB)
- return createError("invalid sh_type for string table, expected SHT_STRTAB");
+ return createError("invalid sh_type for string table section " +
+ getSecIndexForError(this, Section) +
+ ": expected SHT_STRTAB, but got " +
+ object::getELFSectionTypeName(getHeader()->e_machine,
+ Section->sh_type));
auto V = getSectionContentsAsArray<char>(Section);
if (!V)
return V.takeError();
ArrayRef<char> Data = *V;
if (Data.empty())
+ // TODO: this error is untested.
return createError("empty string table");
if (Data.back() != '\0')
- return createError("string table non-null terminated");
+ return createError(object::getELFSectionTypeName(getHeader()->e_machine,
+ Section->sh_type) +
+ " string table section " +
+ getSecIndexForError(this, Section) +
+ " is non-null terminated");
return StringRef(Data.begin(), Data.size());
}
@@ -576,9 +631,13 @@
const Elf_Shdr &SymTable = **SymTableOrErr;
if (SymTable.sh_type != ELF::SHT_SYMTAB &&
SymTable.sh_type != ELF::SHT_DYNSYM)
+ // TODO: this error is untested.
return createError("invalid sh_type");
if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
- return createError("invalid section contents size");
+ return createError("SHT_SYMTAB_SHNDX section has sh_size (" +
+ Twine(SymTable.sh_size) +
+ ") which is not equal to the number of symbols (" +
+ Twine(V.size()) + ")");
return V;
}
@@ -597,6 +656,7 @@
Elf_Shdr_Range Sections) const {
if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
+ // TODO: this error is untested.
return createError(
"invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
@@ -624,7 +684,11 @@
if (Offset == 0)
return StringRef();
if (Offset >= DotShstrtab.size())
- return createError("invalid string offset");
+ return createError("a section " + getSecIndexForError(this, Section) +
+ " has an invalid sh_name (0x" +
+ Twine::utohexstr(Offset) +
+ ") offset which goes past the end of the "
+ "section name string table");
return StringRef(DotShstrtab.data() + Offset);
}
diff --git a/linux-x64/clang/include/llvm/Object/ELFObjectFile.h b/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
index aab7340..86c015e 100644
--- a/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
+++ b/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
@@ -41,6 +41,9 @@
namespace llvm {
namespace object {
+constexpr int NumElfSymbolTypes = 8;
+extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
+
class elf_symbol_iterator;
class ELFObjectFileBase : public ObjectFile {
@@ -51,8 +54,8 @@
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
- virtual uint16_t getEMachine() const = 0;
virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
+ virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0;
virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
@@ -61,6 +64,7 @@
virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
+ virtual Error getBuildAttributes(ARMAttributeParser &Attributes) const = 0;
public:
using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
@@ -86,6 +90,8 @@
virtual uint16_t getEType() const = 0;
+ virtual uint16_t getEMachine() const = 0;
+
std::vector<std::pair<DataRefImpl, uint64_t>> getPltAddresses() const;
};
@@ -141,6 +147,10 @@
return getObject()->getSymbolSize(getRawDataRefImpl());
}
+ uint8_t getBinding() const {
+ return getObject()->getSymbolBinding(getRawDataRefImpl());
+ }
+
uint8_t getOther() const {
return getObject()->getSymbolOther(getRawDataRefImpl());
}
@@ -148,6 +158,16 @@
uint8_t getELFType() const {
return getObject()->getSymbolELFType(getRawDataRefImpl());
}
+
+ StringRef getELFTypeName() const {
+ uint8_t Type = getELFType();
+ for (auto &EE : ElfSymbolTypes) {
+ if (EE.Value == Type) {
+ return EE.AltName;
+ }
+ }
+ return "";
+ }
};
class elf_symbol_iterator : public symbol_iterator {
@@ -238,6 +258,7 @@
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ uint8_t getSymbolBinding(DataRefImpl Symb) const override;
uint8_t getSymbolOther(DataRefImpl Symb) const override;
uint8_t getSymbolELFType(DataRefImpl Symb) const override;
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
@@ -246,13 +267,12 @@
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
- std::error_code getSectionName(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
- std::error_code getSectionContents(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
uint64_t getSectionAlignment(DataRefImpl Sec) const override;
bool isSectionCompressed(DataRefImpl Sec) const override;
bool isSectionText(DataRefImpl Sec) const override;
@@ -340,6 +360,28 @@
(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
}
+ Error getBuildAttributes(ARMAttributeParser &Attributes) const override {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
+ auto ErrorOrContents = EF.getSectionContents(&Sec);
+ if (!ErrorOrContents)
+ return ErrorOrContents.takeError();
+
+ auto Contents = ErrorOrContents.get();
+ if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
+ return Error::success();
+
+ Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
+ break;
+ }
+ }
+ return Error::success();
+ }
+
// This flag is used for classof, to distinguish ELFObjectFile from
// its subclass. If more subclasses will be created, this flag will
// have to become an enum.
@@ -381,28 +423,6 @@
unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
- std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override {
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return errorToErrorCode(SectionsOrErr.takeError());
-
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
- auto ErrorOrContents = EF.getSectionContents(&Sec);
- if (!ErrorOrContents)
- return errorToErrorCode(ErrorOrContents.takeError());
-
- auto Contents = ErrorOrContents.get();
- if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
- return std::error_code();
-
- Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
- break;
- }
- }
- return std::error_code();
- }
-
const ELFFile<ELFT> *getELFFile() const { return &EF; }
bool isDyldType() const { return isDyldELFObject; }
@@ -541,6 +561,11 @@
}
template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
+ return getSymbol(Symb)->getBinding();
+}
+
+template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
return getSymbol(Symb)->st_other;
}
@@ -662,13 +687,8 @@
}
template <class ELFT>
-std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
- StringRef &Result) const {
- auto Name = EF.getSectionName(&*getSection(Sec));
- if (!Name)
- return errorToErrorCode(Name.takeError());
- Result = *Name;
- return std::error_code();
+Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
+ return EF.getSectionName(&*getSection(Sec));
}
template <class ELFT>
@@ -693,16 +713,15 @@
}
template <class ELFT>
-std::error_code
-ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
- StringRef &Result) const {
+Expected<ArrayRef<uint8_t>>
+ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
const Elf_Shdr *EShdr = getSection(Sec);
if (std::error_code EC =
checkOffset(getMemoryBufferRef(),
(uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
- return EC;
- Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
- return std::error_code();
+ return errorCodeToError(EC);
+ return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
+ EShdr->sh_size);
}
template <class ELFT>
@@ -758,7 +777,7 @@
}
}
for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (is_contained(Offsets, Sec.sh_offset))
+ if (is_contained(Offsets, Sec.sh_addr))
Res.emplace_back(toDRI(&Sec), this);
}
return Res;
@@ -933,15 +952,13 @@
for (const Elf_Shdr &Sec : *SectionsOrErr) {
switch (Sec.sh_type) {
case ELF::SHT_DYNSYM: {
- if (DotDynSymSec)
- return createError("More than one dynamic symbol table!");
- DotDynSymSec = &Sec;
+ if (!DotDynSymSec)
+ DotDynSymSec = &Sec;
break;
}
case ELF::SHT_SYMTAB: {
- if (DotSymtabSec)
- return createError("More than one static symbol table!");
- DotSymtabSec = &Sec;
+ if (!DotSymtabSec)
+ DotSymtabSec = &Sec;
break;
}
case ELF::SHT_SYMTAB_SHNDX: {
@@ -975,7 +992,9 @@
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
- DataRefImpl Sym = toDRI(DotSymtabSec, 0);
+ DataRefImpl Sym =
+ toDRI(DotSymtabSec,
+ DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
return basic_symbol_iterator(SymbolRef(Sym, this));
}
diff --git a/linux-x64/clang/include/llvm/Object/ELFTypes.h b/linux-x64/clang/include/llvm/Object/ELFTypes.h
index 45bbd6c..5552208 100644
--- a/linux-x64/clang/include/llvm/Object/ELFTypes.h
+++ b/linux-x64/clang/include/llvm/Object/ELFTypes.h
@@ -592,9 +592,9 @@
template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
+public:
Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
-public:
/// Get the note's name, excluding the terminating null byte.
StringRef getName() const {
if (!Nhdr.n_namesz)
diff --git a/linux-x64/clang/include/llvm/Object/IRObjectFile.h b/linux-x64/clang/include/llvm/Object/IRObjectFile.h
index 39454b0..08b92f1 100644
--- a/linux-x64/clang/include/llvm/Object/IRObjectFile.h
+++ b/linux-x64/clang/include/llvm/Object/IRObjectFile.h
@@ -37,8 +37,7 @@
public:
~IRObjectFile() override;
void moveSymbolNext(DataRefImpl &Symb) const override;
- std::error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const override;
+ Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
basic_symbol_iterator symbol_begin() const override;
basic_symbol_iterator symbol_end() const override;
diff --git a/linux-x64/clang/include/llvm/Object/IRSymtab.h b/linux-x64/clang/include/llvm/Object/IRSymtab.h
index 0601d99..0bbfc93 100644
--- a/linux-x64/clang/include/llvm/Object/IRSymtab.h
+++ b/linux-x64/clang/include/llvm/Object/IRSymtab.h
@@ -125,12 +125,13 @@
Str SectionName;
};
+
struct Header {
/// Version number of the symtab format. This number should be incremented
/// when the format changes, but it does not need to be incremented if a
/// change to LLVM would cause it to create a different symbol table.
Word Version;
- enum { kCurrentVersion = 1 };
+ enum { kCurrentVersion = 2 };
/// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
/// Consumers should rebuild the symbol table from IR if the producer's
@@ -147,6 +148,9 @@
/// COFF-specific: linker directives.
Str COFFLinkerOpts;
+
+ /// Dependent Library Specifiers
+ Range<Str> DependentLibraries;
};
} // end namespace storage
@@ -231,6 +235,7 @@
ArrayRef<storage::Comdat> Comdats;
ArrayRef<storage::Symbol> Symbols;
ArrayRef<storage::Uncommon> Uncommons;
+ ArrayRef<storage::Str> DependentLibraries;
StringRef str(storage::Str S) const { return S.get(Strtab); }
@@ -251,6 +256,7 @@
Comdats = range(header().Comdats);
Symbols = range(header().Symbols);
Uncommons = range(header().Uncommons);
+ DependentLibraries = range(header().DependentLibraries);
}
using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
@@ -283,6 +289,16 @@
/// COFF-specific: returns linker options specified in the input file.
StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
+
+ /// Returns dependent library specifiers
+ std::vector<StringRef> getDependentLibraries() const {
+ std::vector<StringRef> Specifiers;
+ Specifiers.reserve(DependentLibraries.size());
+ for (auto S : DependentLibraries) {
+ Specifiers.push_back(str(S));
+ }
+ return Specifiers;
+ }
};
/// Ephemeral symbols produced by Reader::symbols() and
diff --git a/linux-x64/clang/include/llvm/Object/MachO.h b/linux-x64/clang/include/llvm/Object/MachO.h
index 79ec8bb..ca9512f 100644
--- a/linux-x64/clang/include/llvm/Object/MachO.h
+++ b/linux-x64/clang/include/llvm/Object/MachO.h
@@ -133,11 +133,9 @@
BindRebaseSegInfo(const MachOObjectFile *Obj);
// Used to check a Mach-O Bind or Rebase entry for errors when iterating.
- const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
- bool endInvalid);
- const char *checkCountAndSkip(uint32_t Count, uint32_t Skip,
- uint8_t PointerSize, int32_t SegIndex,
- uint64_t SegOffset);
+ const char* checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
+ uint8_t PointerSize, uint32_t Count=1,
+ uint32_t Skip=0);
// Used with valid SegIndex/SegOffset values from checked entries.
StringRef segmentName(int32_t SegIndex);
StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
@@ -295,13 +293,12 @@
unsigned getSectionID(SectionRef Sec) const;
void moveSectionNext(DataRefImpl &Sec) const override;
- std::error_code getSectionName(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
- std::error_code getSectionContents(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
uint64_t getSectionAlignment(DataRefImpl Sec) const override;
Expected<SectionRef> getSection(unsigned SectionIndex) const;
Expected<SectionRef> getSection(StringRef SectionName) const;
@@ -412,36 +409,32 @@
bool is64,
MachOBindEntry::Kind);
- /// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
- /// validate a MachOBindEntry.
- const char *BindEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
- bool endInvalid) const {
- return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
- endInvalid);
- }
- /// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
- /// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode.
- const char *BindEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
- uint8_t PointerSize, int32_t SegIndex,
- uint64_t SegOffset) const {
- return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
- SegIndex, SegOffset);
+ // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
+ // that fully contains a pointer at that location. Multiple fixups in a bind
+ // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
+ // be tested via the Count and Skip parameters.
+ //
+ // This is used by MachOBindEntry::moveNext() to validate a MachOBindEntry.
+ const char *BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
+ uint8_t PointerSize, uint32_t Count=1,
+ uint32_t Skip=0) const {
+ return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
+ PointerSize, Count, Skip);
}
- /// For use with a SegIndex,SegOffset pair in MachORebaseEntry::moveNext() to
- /// validate a MachORebaseEntry.
- const char *RebaseEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
- bool endInvalid) const {
- return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
- endInvalid);
- }
- /// For use in MachORebaseEntry::moveNext() to validate a MachORebaseEntry for
- /// the REBASE_OPCODE_DO_*_TIMES* opcodes.
- const char *RebaseEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
- uint8_t PointerSize, int32_t SegIndex,
- uint64_t SegOffset) const {
- return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
- SegIndex, SegOffset);
+ // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
+ // that fully contains a pointer at that location. Multiple fixups in a rebase
+ // (such as with the REBASE_OPCODE_DO_*_TIMES* opcodes) can be tested via the
+ // Count and Skip parameters.
+ //
+ // This is used by MachORebaseEntry::moveNext() to validate a MachORebaseEntry
+ const char *RebaseEntryCheckSegAndOffsets(int32_t SegIndex,
+ uint64_t SegOffset,
+ uint8_t PointerSize,
+ uint32_t Count=1,
+ uint32_t Skip=0) const {
+ return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
+ PointerSize, Count, Skip);
}
/// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
@@ -578,6 +571,7 @@
const char **McpuDefault = nullptr,
const char **ArchFlag = nullptr);
static bool isValidArch(StringRef ArchFlag);
+ static ArrayRef<StringRef> getValidArchs();
static Triple getHostArch();
bool isRelocatableObject() const override;
@@ -615,6 +609,7 @@
case MachO::PLATFORM_TVOS: return "tvos";
case MachO::PLATFORM_WATCHOS: return "watchos";
case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
+ case MachO::PLATFORM_MACCATALYST: return "macCatalyst";
case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator";
case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator";
case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator";
diff --git a/linux-x64/clang/include/llvm/Object/Minidump.h b/linux-x64/clang/include/llvm/Object/Minidump.h
new file mode 100644
index 0000000..470008d
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/Minidump.h
@@ -0,0 +1,165 @@
+//===- Minidump.h - Minidump object file 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MINIDUMP_H
+#define LLVM_OBJECT_MINIDUMP_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/Minidump.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace object {
+
+/// A class providing access to the contents of a minidump file.
+class MinidumpFile : public Binary {
+public:
+ /// Construct a new MinidumpFile object from the given memory buffer. Returns
+ /// an error if this file cannot be identified as a minidump file, or if its
+ /// contents are badly corrupted (i.e. we cannot read the stream directory).
+ static Expected<std::unique_ptr<MinidumpFile>> create(MemoryBufferRef Source);
+
+ static bool classof(const Binary *B) { return B->isMinidump(); }
+
+ /// Returns the contents of the minidump header.
+ const minidump::Header &header() const { return Header; }
+
+ /// Returns the list of streams (stream directory entries) in this file.
+ ArrayRef<minidump::Directory> streams() const { return Streams; }
+
+ /// Returns the raw contents of the stream given by the directory entry.
+ ArrayRef<uint8_t> getRawStream(const minidump::Directory &Stream) const {
+ return getData().slice(Stream.Location.RVA, Stream.Location.DataSize);
+ }
+
+ /// Returns the raw contents of the stream of the given type, or None if the
+ /// file does not contain a stream of this type.
+ Optional<ArrayRef<uint8_t>> getRawStream(minidump::StreamType Type) const;
+
+ /// Returns the raw contents of an object given by the LocationDescriptor. An
+ /// error is returned if the descriptor points outside of the minidump file.
+ Expected<ArrayRef<uint8_t>>
+ getRawData(minidump::LocationDescriptor Desc) const {
+ return getDataSlice(getData(), Desc.RVA, Desc.DataSize);
+ }
+
+ /// Returns the minidump string at the given offset. An error is returned if
+ /// we fail to parse the string, or the string is invalid UTF16.
+ Expected<std::string> getString(size_t Offset) const;
+
+ /// Returns the contents of the SystemInfo stream, cast to the appropriate
+ /// type. An error is returned if the file does not contain this stream, or
+ /// the stream is smaller than the size of the SystemInfo structure. The
+ /// internal consistency of the stream is not checked in any way.
+ Expected<const minidump::SystemInfo &> getSystemInfo() const {
+ return getStream<minidump::SystemInfo>(minidump::StreamType::SystemInfo);
+ }
+
+ /// Returns the module list embedded in the ModuleList stream. An error is
+ /// returned if the file does not contain this stream, or if the stream is
+ /// not large enough to contain the number of modules declared in the stream
+ /// header. The consistency of the Module entries themselves is not checked in
+ /// any way.
+ Expected<ArrayRef<minidump::Module>> getModuleList() const {
+ return getListStream<minidump::Module>(minidump::StreamType::ModuleList);
+ }
+
+ /// Returns the thread list embedded in the ThreadList stream. An error is
+ /// returned if the file does not contain this stream, or if the stream is
+ /// not large enough to contain the number of threads declared in the stream
+ /// header. The consistency of the Thread entries themselves is not checked in
+ /// any way.
+ Expected<ArrayRef<minidump::Thread>> getThreadList() const {
+ return getListStream<minidump::Thread>(minidump::StreamType::ThreadList);
+ }
+
+ /// Returns the list of memory ranges embedded in the MemoryList stream. An
+ /// error is returned if the file does not contain this stream, or if the
+ /// stream is not large enough to contain the number of memory descriptors
+ /// declared in the stream header. The consistency of the MemoryDescriptor
+ /// entries themselves is not checked in any way.
+ Expected<ArrayRef<minidump::MemoryDescriptor>> getMemoryList() const {
+ return getListStream<minidump::MemoryDescriptor>(
+ minidump::StreamType::MemoryList);
+ }
+
+private:
+ static Error createError(StringRef Str) {
+ return make_error<GenericBinaryError>(Str, object_error::parse_failed);
+ }
+
+ static Error createEOFError() {
+ return make_error<GenericBinaryError>("Unexpected EOF",
+ object_error::unexpected_eof);
+ }
+
+ /// Return a slice of the given data array, with bounds checking.
+ static Expected<ArrayRef<uint8_t>> getDataSlice(ArrayRef<uint8_t> Data,
+ size_t Offset, size_t Size);
+
+ /// Return the slice of the given data array as an array of objects of the
+ /// given type. The function checks that the input array is large enough to
+ /// contain the correct number of objects of the given type.
+ template <typename T>
+ static Expected<ArrayRef<T>> getDataSliceAs(ArrayRef<uint8_t> Data,
+ size_t Offset, size_t Count);
+
+ MinidumpFile(MemoryBufferRef Source, const minidump::Header &Header,
+ ArrayRef<minidump::Directory> Streams,
+ DenseMap<minidump::StreamType, std::size_t> StreamMap)
+ : Binary(ID_Minidump, Source), Header(Header), Streams(Streams),
+ StreamMap(std::move(StreamMap)) {}
+
+ ArrayRef<uint8_t> getData() const {
+ return arrayRefFromStringRef(Data.getBuffer());
+ }
+
+ /// Return the stream of the given type, cast to the appropriate type. Checks
+ /// that the stream is large enough to hold an object of this type.
+ template <typename T>
+ Expected<const T &> getStream(minidump::StreamType Stream) const;
+
+ /// Return the contents of a stream which contains a list of fixed-size items,
+ /// prefixed by the list size.
+ template <typename T>
+ Expected<ArrayRef<T>> getListStream(minidump::StreamType Stream) const;
+
+ const minidump::Header &Header;
+ ArrayRef<minidump::Directory> Streams;
+ DenseMap<minidump::StreamType, std::size_t> StreamMap;
+};
+
+template <typename T>
+Expected<const T &> MinidumpFile::getStream(minidump::StreamType Stream) const {
+ if (auto OptionalStream = getRawStream(Stream)) {
+ if (OptionalStream->size() >= sizeof(T))
+ return *reinterpret_cast<const T *>(OptionalStream->data());
+ return createEOFError();
+ }
+ return createError("No such stream");
+}
+
+template <typename T>
+Expected<ArrayRef<T>> MinidumpFile::getDataSliceAs(ArrayRef<uint8_t> Data,
+ size_t Offset,
+ size_t Count) {
+ // Check for overflow.
+ if (Count > std::numeric_limits<size_t>::max() / sizeof(T))
+ return createEOFError();
+ auto ExpectedArray = getDataSlice(Data, Offset, sizeof(T) * Count);
+ if (!ExpectedArray)
+ return ExpectedArray.takeError();
+ return ArrayRef<T>(reinterpret_cast<const T *>(ExpectedArray->data()), Count);
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MINIDUMP_H
diff --git a/linux-x64/clang/include/llvm/Object/ObjectFile.h b/linux-x64/clang/include/llvm/Object/ObjectFile.h
index f13775c..483a348 100644
--- a/linux-x64/clang/include/llvm/Object/ObjectFile.h
+++ b/linux-x64/clang/include/llvm/Object/ObjectFile.h
@@ -13,6 +13,7 @@
#ifndef LLVM_OBJECT_OBJECTFILE_H
#define LLVM_OBJECT_OBJECTFILE_H
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
@@ -97,7 +98,7 @@
uint64_t getAddress() const;
uint64_t getIndex() const;
uint64_t getSize() const;
- std::error_code getContents(StringRef &Result) const;
+ Expected<StringRef> getContents() const;
/// Get the alignment of this section as the actual value (not log 2).
uint64_t getAlignment() const;
@@ -135,6 +136,30 @@
const ObjectFile *getObject() const;
};
+struct SectionedAddress {
+ // TODO: constructors could be removed when C++14 would be adopted.
+ SectionedAddress() {}
+ SectionedAddress(uint64_t Addr, uint64_t SectIdx)
+ : Address(Addr), SectionIndex(SectIdx) {}
+
+ const static uint64_t UndefSection = UINT64_MAX;
+
+ uint64_t Address = 0;
+ uint64_t SectionIndex = UndefSection;
+};
+
+inline bool operator<(const SectionedAddress &LHS,
+ const SectionedAddress &RHS) {
+ return std::tie(LHS.SectionIndex, LHS.Address) <
+ std::tie(RHS.SectionIndex, RHS.Address);
+}
+
+inline bool operator==(const SectionedAddress &LHS,
+ const SectionedAddress &RHS) {
+ return std::tie(LHS.SectionIndex, LHS.Address) ==
+ std::tie(RHS.SectionIndex, RHS.Address);
+}
+
/// This is a value type class that represents a single symbol in the list of
/// symbols in the object file.
class SymbolRef : public BasicSymbolRef {
@@ -219,7 +244,7 @@
friend class SymbolRef;
virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
- std::error_code printSymbolName(raw_ostream &OS,
+ Error printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
@@ -233,13 +258,12 @@
friend class SectionRef;
virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
- virtual std::error_code getSectionName(DataRefImpl Sec,
- StringRef &Res) const = 0;
+ virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
- virtual std::error_code getSectionContents(DataRefImpl Sec,
- StringRef &Res) const = 0;
+ virtual Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
virtual bool isSectionText(DataRefImpl Sec) const = 0;
@@ -307,11 +331,6 @@
/// Create a triple from the data in this object file.
Triple makeTriple() const;
- virtual std::error_code
- getBuildAttributes(ARMAttributeParser &Attributes) const {
- return std::error_code();
- }
-
/// Maps a debug section name to a standard DWARF section name.
virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
@@ -340,6 +359,9 @@
createCOFFObjectFile(MemoryBufferRef Object);
static Expected<std::unique_ptr<ObjectFile>>
+ createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
+
+ static Expected<std::unique_ptr<ObjectFile>>
createELFObjectFile(MemoryBufferRef Object);
static Expected<std::unique_ptr<MachOObjectFile>>
@@ -395,14 +417,16 @@
, OwningObject(Owner) {}
inline bool SectionRef::operator==(const SectionRef &Other) const {
- return SectionPimpl == Other.SectionPimpl;
+ return OwningObject == Other.OwningObject &&
+ SectionPimpl == Other.SectionPimpl;
}
inline bool SectionRef::operator!=(const SectionRef &Other) const {
- return SectionPimpl != Other.SectionPimpl;
+ return !(*this == Other);
}
inline bool SectionRef::operator<(const SectionRef &Other) const {
+ assert(OwningObject == Other.OwningObject);
return SectionPimpl < Other.SectionPimpl;
}
@@ -411,7 +435,11 @@
}
inline std::error_code SectionRef::getName(StringRef &Result) const {
- return OwningObject->getSectionName(SectionPimpl, Result);
+ Expected<StringRef> NameOrErr = OwningObject->getSectionName(SectionPimpl);
+ if (!NameOrErr)
+ return errorToErrorCode(NameOrErr.takeError());
+ Result = *NameOrErr;
+ return std::error_code();
}
inline uint64_t SectionRef::getAddress() const {
@@ -426,8 +454,12 @@
return OwningObject->getSectionSize(SectionPimpl);
}
-inline std::error_code SectionRef::getContents(StringRef &Result) const {
- return OwningObject->getSectionContents(SectionPimpl, Result);
+inline Expected<StringRef> SectionRef::getContents() const {
+ Expected<ArrayRef<uint8_t>> Res =
+ OwningObject->getSectionContents(SectionPimpl);
+ if (!Res)
+ return Res.takeError();
+ return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
}
inline uint64_t SectionRef::getAlignment() const {
@@ -530,6 +562,25 @@
} // end namespace object
+template <> struct DenseMapInfo<object::SectionRef> {
+ static bool isEqual(const object::SectionRef &A,
+ const object::SectionRef &B) {
+ return A == B;
+ }
+ static object::SectionRef getEmptyKey() {
+ return object::SectionRef({}, nullptr);
+ }
+ static object::SectionRef getTombstoneKey() {
+ object::DataRefImpl TS;
+ TS.p = (uintptr_t)-1;
+ return object::SectionRef(TS, nullptr);
+ }
+ static unsigned getHashValue(const object::SectionRef &Sec) {
+ object::DataRefImpl Raw = Sec.getRawDataRefImpl();
+ return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
+ }
+};
+
} // end namespace llvm
#endif // LLVM_OBJECT_OBJECTFILE_H
diff --git a/linux-x64/clang/include/llvm/Object/RelocVisitor.h b/linux-x64/clang/include/llvm/Object/RelocVisitor.h
deleted file mode 100644
index 76f3fab..0000000
--- a/linux-x64/clang/include/llvm/Object/RelocVisitor.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//===- RelocVisitor.h - Visitor for object file relocations -----*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a wrapper around all the different types of relocations
-// in different file formats, such that a client can handle them in a unified
-// manner by only implementing a minimal number of functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_RELOCVISITOR_H
-#define LLVM_OBJECT_RELOCVISITOR_H
-
-#include "llvm/ADT/Triple.h"
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/Wasm.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstdint>
-#include <system_error>
-
-namespace llvm {
-namespace object {
-
-/// Base class for object file relocation visitors.
-class RelocVisitor {
-public:
- explicit RelocVisitor(const ObjectFile &Obj) : ObjToVisit(Obj) {}
-
- // TODO: Should handle multiple applied relocations via either passing in the
- // previously computed value or just count paired relocations as a single
- // visit.
- uint64_t visit(uint32_t Rel, RelocationRef R, uint64_t Value = 0) {
- if (isa<ELFObjectFileBase>(ObjToVisit))
- return visitELF(Rel, R, Value);
- if (isa<COFFObjectFile>(ObjToVisit))
- return visitCOFF(Rel, R, Value);
- if (isa<MachOObjectFile>(ObjToVisit))
- return visitMachO(Rel, R, Value);
- if (isa<WasmObjectFile>(ObjToVisit))
- return visitWasm(Rel, R, Value);
-
- HasError = true;
- return 0;
- }
-
- bool error() { return HasError; }
-
-private:
- const ObjectFile &ObjToVisit;
- bool HasError = false;
-
- uint64_t visitELF(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
- switch (ObjToVisit.getArch()) {
- case Triple::x86_64:
- return visitX86_64(Rel, R, Value);
- case Triple::aarch64:
- case Triple::aarch64_be:
- return visitAarch64(Rel, R, Value);
- case Triple::bpfel:
- case Triple::bpfeb:
- return visitBpf(Rel, R, Value);
- case Triple::mips64el:
- case Triple::mips64:
- return visitMips64(Rel, R, Value);
- case Triple::ppc64le:
- case Triple::ppc64:
- return visitPPC64(Rel, R, Value);
- case Triple::systemz:
- return visitSystemz(Rel, R, Value);
- case Triple::sparcv9:
- return visitSparc64(Rel, R, Value);
- case Triple::amdgcn:
- return visitAmdgpu(Rel, R, Value);
- default:
- HasError = true;
- return 0;
- }
- }
-
- // 32-bit object file
- assert(ObjToVisit.getBytesInAddress() == 4 &&
- "Invalid word size in object file");
-
- switch (ObjToVisit.getArch()) {
- case Triple::x86:
- return visitX86(Rel, R, Value);
- case Triple::ppc:
- return visitPPC32(Rel, R, Value);
- case Triple::arm:
- case Triple::armeb:
- return visitARM(Rel, R, Value);
- case Triple::avr:
- return visitAVR(Rel, R, Value);
- case Triple::lanai:
- return visitLanai(Rel, R, Value);
- case Triple::mipsel:
- case Triple::mips:
- return visitMips32(Rel, R, Value);
- case Triple::sparc:
- return visitSparc32(Rel, R, Value);
- case Triple::hexagon:
- return visitHexagon(Rel, R, Value);
- default:
- HasError = true;
- return 0;
- }
- }
-
- int64_t getELFAddend(RelocationRef R) {
- Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
- handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
- report_fatal_error(EI.message());
- });
- return *AddendOrErr;
- }
-
- uint64_t visitX86_64(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_X86_64_NONE:
- return 0;
- case ELF::R_X86_64_64:
- case ELF::R_X86_64_DTPOFF32:
- case ELF::R_X86_64_DTPOFF64:
- return Value + getELFAddend(R);
- case ELF::R_X86_64_PC32:
- return Value + getELFAddend(R) - R.getOffset();
- case ELF::R_X86_64_32:
- case ELF::R_X86_64_32S:
- return (Value + getELFAddend(R)) & 0xFFFFFFFF;
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitAarch64(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_AARCH64_ABS32: {
- int64_t Res = Value + getELFAddend(R);
- if (Res < INT32_MIN || Res > UINT32_MAX)
- HasError = true;
- return static_cast<uint32_t>(Res);
- }
- case ELF::R_AARCH64_ABS64:
- return Value + getELFAddend(R);
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitBpf(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_BPF_64_32:
- return Value & 0xFFFFFFFF;
- case ELF::R_BPF_64_64:
- return Value;
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitMips64(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_MIPS_32:
- return (Value + getELFAddend(R)) & 0xFFFFFFFF;
- case ELF::R_MIPS_64:
- return Value + getELFAddend(R);
- case ELF::R_MIPS_TLS_DTPREL64:
- return Value + getELFAddend(R) - 0x8000;
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitPPC64(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_PPC64_ADDR32:
- return (Value + getELFAddend(R)) & 0xFFFFFFFF;
- case ELF::R_PPC64_ADDR64:
- return Value + getELFAddend(R);
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitSystemz(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_390_32: {
- int64_t Res = Value + getELFAddend(R);
- if (Res < INT32_MIN || Res > UINT32_MAX)
- HasError = true;
- return static_cast<uint32_t>(Res);
- }
- case ELF::R_390_64:
- return Value + getELFAddend(R);
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitSparc64(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_SPARC_32:
- case ELF::R_SPARC_64:
- case ELF::R_SPARC_UA32:
- case ELF::R_SPARC_UA64:
- return Value + getELFAddend(R);
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitAmdgpu(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_AMDGPU_ABS32:
- case ELF::R_AMDGPU_ABS64:
- return Value + getELFAddend(R);
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitX86(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (Rel) {
- case ELF::R_386_NONE:
- return 0;
- case ELF::R_386_32:
- return Value;
- case ELF::R_386_PC32:
- return Value - R.getOffset();
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitPPC32(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (Rel == ELF::R_PPC_ADDR32)
- return (Value + getELFAddend(R)) & 0xFFFFFFFF;
- HasError = true;
- return 0;
- }
-
- uint64_t visitARM(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (Rel == ELF::R_ARM_ABS32) {
- if ((int64_t)Value < INT32_MIN || (int64_t)Value > UINT32_MAX)
- HasError = true;
- return static_cast<uint32_t>(Value);
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitAVR(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (Rel == ELF::R_AVR_16) {
- return (Value + getELFAddend(R)) & 0xFFFF;
- } else if (Rel == ELF::R_AVR_32) {
- return (Value + getELFAddend(R)) & 0xFFFFFFFF;
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitLanai(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (Rel == ELF::R_LANAI_32)
- return (Value + getELFAddend(R)) & 0xFFFFFFFF;
- HasError = true;
- return 0;
- }
-
- uint64_t visitMips32(uint32_t Rel, RelocationRef R, uint64_t Value) {
- // FIXME: Take in account implicit addends to get correct results.
- if (Rel == ELF::R_MIPS_32)
- return Value & 0xFFFFFFFF;
- if (Rel == ELF::R_MIPS_TLS_DTPREL32)
- return Value & 0xFFFFFFFF;
- HasError = true;
- return 0;
- }
-
- uint64_t visitSparc32(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
- return Value + getELFAddend(R);
- HasError = true;
- return 0;
- }
-
- uint64_t visitHexagon(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (Rel == ELF::R_HEX_32)
- return Value + getELFAddend(R);
- HasError = true;
- return 0;
- }
-
- uint64_t visitCOFF(uint32_t Rel, RelocationRef R, uint64_t Value) {
- switch (ObjToVisit.getArch()) {
- case Triple::x86:
- switch (Rel) {
- case COFF::IMAGE_REL_I386_SECREL:
- case COFF::IMAGE_REL_I386_DIR32:
- return static_cast<uint32_t>(Value);
- }
- break;
- case Triple::x86_64:
- switch (Rel) {
- case COFF::IMAGE_REL_AMD64_SECREL:
- return static_cast<uint32_t>(Value);
- case COFF::IMAGE_REL_AMD64_ADDR64:
- return Value;
- }
- break;
- default:
- break;
- }
- HasError = true;
- return 0;
- }
-
- uint64_t visitMachO(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (ObjToVisit.getArch() == Triple::x86_64 &&
- Rel == MachO::X86_64_RELOC_UNSIGNED)
- return Value;
- HasError = true;
- return 0;
- }
-
- uint64_t visitWasm(uint32_t Rel, RelocationRef R, uint64_t Value) {
- if (ObjToVisit.getArch() == Triple::wasm32) {
- switch (Rel) {
- case wasm::R_WASM_FUNCTION_INDEX_LEB:
- case wasm::R_WASM_TABLE_INDEX_SLEB:
- case wasm::R_WASM_TABLE_INDEX_I32:
- case wasm::R_WASM_MEMORY_ADDR_LEB:
- case wasm::R_WASM_MEMORY_ADDR_SLEB:
- case wasm::R_WASM_MEMORY_ADDR_I32:
- case wasm::R_WASM_TYPE_INDEX_LEB:
- case wasm::R_WASM_GLOBAL_INDEX_LEB:
- case wasm::R_WASM_FUNCTION_OFFSET_I32:
- case wasm::R_WASM_SECTION_OFFSET_I32:
- case wasm::R_WASM_EVENT_INDEX_LEB:
- // For wasm section, its offset at 0 -- ignoring Value
- return 0;
- }
- }
- HasError = true;
- return 0;
- }
-};
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_RELOCVISITOR_H
diff --git a/linux-x64/clang/include/llvm/Object/RelocationResolver.h b/linux-x64/clang/include/llvm/Object/RelocationResolver.h
new file mode 100644
index 0000000..1246dcc
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/RelocationResolver.h
@@ -0,0 +1,42 @@
+//===- RelocVisitor.h - Visitor for object file relocations -----*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around all the different types of relocations
+// in different file formats, such that a client can handle them in a unified
+// manner by only implementing a minimal number of functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_RELOCVISITOR_H
+#define LLVM_OBJECT_RELOCVISITOR_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/Wasm.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+using RelocationResolver = uint64_t (*)(RelocationRef R, uint64_t S, uint64_t A);
+
+std::pair<bool (*)(uint64_t), RelocationResolver>
+getRelocationResolver(const ObjectFile &Obj);
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_RELOCVISITOR_H
diff --git a/linux-x64/clang/include/llvm/Object/StackMapParser.h b/linux-x64/clang/include/llvm/Object/StackMapParser.h
index 8817516..ed44efb 100644
--- a/linux-x64/clang/include/llvm/Object/StackMapParser.h
+++ b/linux-x64/clang/include/llvm/Object/StackMapParser.h
@@ -19,8 +19,9 @@
namespace llvm {
+/// A parser for the latest stackmap format. At the moment, latest=V2.
template <support::endianness Endianness>
-class StackMapV2Parser {
+class StackMapParser {
public:
template <typename AccessorT>
class AccessorIterator {
@@ -49,7 +50,7 @@
/// Accessor for function records.
class FunctionAccessor {
- friend class StackMapV2Parser;
+ friend class StackMapParser;
public:
/// Get the function address.
@@ -81,7 +82,7 @@
/// Accessor for constants.
class ConstantAccessor {
- friend class StackMapV2Parser;
+ friend class StackMapParser;
public:
/// Return the value of this constant.
@@ -105,7 +106,7 @@
/// Accessor for location records.
class LocationAccessor {
- friend class StackMapV2Parser;
+ friend class StackMapParser;
friend class RecordAccessor;
public:
@@ -114,6 +115,12 @@
return LocationKind(P[KindOffset]);
}
+ /// Get the Size for this location.
+ unsigned getSizeInBytes() const {
+ return read<uint16_t>(P + SizeOffset);
+
+ }
+
/// Get the Dwarf register number for this location.
uint16_t getDwarfRegNum() const {
return read<uint16_t>(P + DwarfRegNumOffset);
@@ -148,16 +155,17 @@
}
static const int KindOffset = 0;
- static const int DwarfRegNumOffset = KindOffset + sizeof(uint16_t);
- static const int SmallConstantOffset = DwarfRegNumOffset + sizeof(uint16_t);
- static const int LocationAccessorSize = sizeof(uint64_t);
+ static const int SizeOffset = KindOffset + sizeof(uint16_t);
+ static const int DwarfRegNumOffset = SizeOffset + sizeof(uint16_t);
+ static const int SmallConstantOffset = DwarfRegNumOffset + sizeof(uint32_t);
+ static const int LocationAccessorSize = sizeof(uint64_t) + sizeof(uint32_t);
const uint8_t *P;
};
/// Accessor for stackmap live-out fields.
class LiveOutAccessor {
- friend class StackMapV2Parser;
+ friend class StackMapParser;
friend class RecordAccessor;
public:
@@ -188,7 +196,7 @@
/// Accessor for stackmap records.
class RecordAccessor {
- friend class StackMapV2Parser;
+ friend class StackMapParser;
public:
using location_iterator = AccessorIterator<LocationAccessor>;
@@ -263,8 +271,9 @@
RecordAccessor(const uint8_t *P) : P(P) {}
unsigned getNumLiveOutsOffset() const {
- return LocationListOffset + LocationSize * getNumLocations() +
- sizeof(uint16_t);
+ unsigned LocOffset =
+ ((LocationListOffset + LocationSize * getNumLocations()) + 7) & ~0x7;
+ return LocOffset + sizeof(uint16_t);
}
unsigned getSizeInBytes() const {
@@ -284,7 +293,7 @@
InstructionOffsetOffset + sizeof(uint32_t) + sizeof(uint16_t);
static const unsigned LocationListOffset =
NumLocationsOffset + sizeof(uint16_t);
- static const unsigned LocationSize = sizeof(uint64_t);
+ static const unsigned LocationSize = sizeof(uint64_t) + sizeof(uint32_t);
static const unsigned LiveOutSize = sizeof(uint32_t);
const uint8_t *P;
@@ -292,12 +301,12 @@
/// Construct a parser for a version-2 stackmap. StackMap data will be read
/// from the given array.
- StackMapV2Parser(ArrayRef<uint8_t> StackMapSection)
+ StackMapParser(ArrayRef<uint8_t> StackMapSection)
: StackMapSection(StackMapSection) {
ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize;
- assert(StackMapSection[0] == 2 &&
- "StackMapV2Parser can only parse version 2 stackmaps");
+ assert(StackMapSection[0] == 3 &&
+ "StackMapParser can only parse version 3 stackmaps");
unsigned CurrentRecordOffset =
ConstantsListOffset + getNumConstants() * ConstantSize;
@@ -313,8 +322,8 @@
using constant_iterator = AccessorIterator<ConstantAccessor>;
using record_iterator = AccessorIterator<RecordAccessor>;
- /// Get the version number of this stackmap. (Always returns 2).
- unsigned getVersion() const { return 2; }
+ /// Get the version number of this stackmap. (Always returns 3).
+ unsigned getVersion() const { return 3; }
/// Get the number of functions in the stack map.
uint32_t getNumFunctions() const {
diff --git a/linux-x64/clang/include/llvm/Object/SymbolicFile.h b/linux-x64/clang/include/llvm/Object/SymbolicFile.h
index 6d95d7a..1398fa1 100644
--- a/linux-x64/clang/include/llvm/Object/SymbolicFile.h
+++ b/linux-x64/clang/include/llvm/Object/SymbolicFile.h
@@ -126,7 +126,7 @@
void moveNext();
- std::error_code printName(raw_ostream &OS) const;
+ Error printName(raw_ostream &OS) const;
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
uint32_t getFlags() const;
@@ -145,8 +145,7 @@
// virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
- virtual std::error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const = 0;
+ virtual Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const = 0;
virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
@@ -193,7 +192,7 @@
return OwningObject->moveSymbolNext(SymbolPimpl);
}
-inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
+inline Error BasicSymbolRef::printName(raw_ostream &OS) const {
return OwningObject->printSymbolName(OS, SymbolPimpl);
}
diff --git a/linux-x64/clang/include/llvm/Object/Wasm.h b/linux-x64/clang/include/llvm/Object/Wasm.h
index a0a2c4b..e130ea3 100644
--- a/linux-x64/clang/include/llvm/Object/Wasm.h
+++ b/linux-x64/clang/include/llvm/Object/Wasm.h
@@ -130,6 +130,9 @@
const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
+ ArrayRef<wasm::WasmFeatureEntry> getTargetFeatures() const {
+ return TargetFeatures;
+ }
ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
ArrayRef<wasm::WasmImport> imports() const { return Imports; }
@@ -168,13 +171,12 @@
// Overrides from SectionRef.
void moveSectionNext(DataRefImpl &Sec) const override;
- std::error_code getSectionName(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
uint64_t getSectionAddress(DataRefImpl Sec) const override;
uint64_t getSectionIndex(DataRefImpl Sec) const override;
uint64_t getSectionSize(DataRefImpl Sec) const override;
- std::error_code getSectionContents(DataRefImpl Sec,
- StringRef &Res) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
uint64_t getSectionAlignment(DataRefImpl Sec) const override;
bool isSectionCompressed(DataRefImpl Sec) const override;
bool isSectionText(DataRefImpl Sec) const override;
@@ -244,6 +246,7 @@
Error parseElemSection(ReadContext &Ctx);
Error parseCodeSection(ReadContext &Ctx);
Error parseDataSection(ReadContext &Ctx);
+ Error parseDataCountSection(ReadContext &Ctx);
// Custom section types
Error parseDylinkSection(ReadContext &Ctx);
@@ -252,12 +255,14 @@
Error parseLinkingSectionSymtab(ReadContext &Ctx);
Error parseLinkingSectionComdat(ReadContext &Ctx);
Error parseProducersSection(ReadContext &Ctx);
+ Error parseTargetFeaturesSection(ReadContext &Ctx);
Error parseRelocSection(StringRef Name, ReadContext &Ctx);
wasm::WasmObjectHeader Header;
std::vector<WasmSection> Sections;
wasm::WasmDylinkInfo DylinkInfo;
wasm::WasmProducerInfo ProducerInfo;
+ std::vector<wasm::WasmFeatureEntry> TargetFeatures;
std::vector<wasm::WasmSignature> Signatures;
std::vector<uint32_t> FunctionTypes;
std::vector<wasm::WasmTable> Tables;
@@ -268,6 +273,7 @@
std::vector<wasm::WasmExport> Exports;
std::vector<wasm::WasmElemSegment> ElemSegments;
std::vector<WasmSegment> DataSegments;
+ llvm::Optional<size_t> DataCount;
std::vector<wasm::WasmFunction> Functions;
std::vector<WasmSymbol> Symbols;
std::vector<wasm::WasmFunctionName> DebugNames;
@@ -288,40 +294,51 @@
public:
// We define orders for all core wasm sections and known custom sections.
enum : int {
+ // Sentinel, must be zero
+ WASM_SEC_ORDER_NONE = 0,
+
// Core sections
- // The order of standard sections is precisely given by the spec.
- WASM_SEC_ORDER_TYPE = 1,
- WASM_SEC_ORDER_IMPORT = 2,
- WASM_SEC_ORDER_FUNCTION = 3,
- WASM_SEC_ORDER_TABLE = 4,
- WASM_SEC_ORDER_MEMORY = 5,
- WASM_SEC_ORDER_GLOBAL = 6,
- WASM_SEC_ORDER_EVENT = 7,
- WASM_SEC_ORDER_EXPORT = 8,
- WASM_SEC_ORDER_START = 9,
- WASM_SEC_ORDER_ELEM = 10,
- WASM_SEC_ORDER_DATACOUNT = 11,
- WASM_SEC_ORDER_CODE = 12,
- WASM_SEC_ORDER_DATA = 13,
+ WASM_SEC_ORDER_TYPE,
+ WASM_SEC_ORDER_IMPORT,
+ WASM_SEC_ORDER_FUNCTION,
+ WASM_SEC_ORDER_TABLE,
+ WASM_SEC_ORDER_MEMORY,
+ WASM_SEC_ORDER_GLOBAL,
+ WASM_SEC_ORDER_EVENT,
+ WASM_SEC_ORDER_EXPORT,
+ WASM_SEC_ORDER_START,
+ WASM_SEC_ORDER_ELEM,
+ WASM_SEC_ORDER_DATACOUNT,
+ WASM_SEC_ORDER_CODE,
+ WASM_SEC_ORDER_DATA,
// Custom sections
// "dylink" should be the very first section in the module
- WASM_SEC_ORDER_DYLINK = 0,
+ WASM_SEC_ORDER_DYLINK,
// "linking" section requires DATA section in order to validate data symbols
- WASM_SEC_ORDER_LINKING = 100,
+ WASM_SEC_ORDER_LINKING,
// Must come after "linking" section in order to validate reloc indexes.
- WASM_SEC_ORDER_RELOC = 101,
+ WASM_SEC_ORDER_RELOC,
// "name" section must appear after DATA. Comes after "linking" to allow
// symbol table to set default function name.
- WASM_SEC_ORDER_NAME = 102,
+ WASM_SEC_ORDER_NAME,
// "producers" section must appear after "name" section.
- WASM_SEC_ORDER_PRODUCERS = 103
+ WASM_SEC_ORDER_PRODUCERS,
+ // "target_features" section must appear after producers section
+ WASM_SEC_ORDER_TARGET_FEATURES,
+
+ // Must be last
+ WASM_NUM_SEC_ORDERS
+
};
+ // Sections that may or may not be present, but cannot be predecessors
+ static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS];
+
bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName = "");
private:
- int LastOrder = -1; // Lastly seen known section's order
+ bool Seen[WASM_NUM_SEC_ORDERS] = {}; // Sections that have been seen already
// Returns -1 for unknown sections.
int getSectionOrder(unsigned ID, StringRef CustomSectionName = "");
diff --git a/linux-x64/clang/include/llvm/Object/WindowsMachineFlag.h b/linux-x64/clang/include/llvm/Object/WindowsMachineFlag.h
new file mode 100644
index 0000000..acc6afc
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/WindowsMachineFlag.h
@@ -0,0 +1,33 @@
+//===- WindowsMachineFlag.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Functions for implementing the /machine: flag.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLDRIVERS_MACHINEFLAG_MACHINEFLAG_H
+#define LLVM_TOOLDRIVERS_MACHINEFLAG_MACHINEFLAG_H
+
+namespace llvm {
+
+class StringRef;
+namespace COFF {
+enum MachineTypes : unsigned;
+}
+
+// Returns a user-readable string for ARMNT, ARM64, AMD64, I386.
+// Other MachineTypes values must not be passed in.
+StringRef machineToStr(COFF::MachineTypes MT);
+
+// Maps /machine: arguments to a MachineTypes value.
+// Only returns ARMNT, ARM64, AMD64, I386, or IMAGE_FILE_MACHINE_UNKNOWN.
+COFF::MachineTypes getMachineType(StringRef S);
+
+}
+
+#endif
diff --git a/linux-x64/clang/include/llvm/Object/WindowsResource.h b/linux-x64/clang/include/llvm/Object/WindowsResource.h
index fd04e60..356dcb0 100644
--- a/linux-x64/clang/include/llvm/Object/WindowsResource.h
+++ b/linux-x64/clang/include/llvm/Object/WindowsResource.h
@@ -37,11 +37,14 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/ScopedPrinter.h"
#include <map>
namespace llvm {
+
+class raw_ostream;
+class ScopedPrinter;
+
namespace object {
class WindowsResource;
@@ -117,6 +120,7 @@
const WindowsResource *Owner);
BinaryStreamReader Reader;
+ const WindowsResource *Owner;
bool IsStringType;
ArrayRef<UTF16> Type;
uint16_t TypeID;
@@ -148,7 +152,7 @@
public:
class TreeNode;
WindowsResourceParser();
- Error parse(WindowsResource *WR);
+ Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
void printTree(raw_ostream &OS) const;
const TreeNode &getTree() const { return Root; }
const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
@@ -184,21 +188,25 @@
static std::unique_ptr<TreeNode> createIDNode();
static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
uint16_t MinorVersion,
- uint32_t Characteristics);
+ uint32_t Characteristics,
+ uint32_t Origin);
explicit TreeNode(bool IsStringNode);
TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
- uint32_t Characteristics);
+ uint32_t Characteristics, uint32_t Origin);
- void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString,
- bool &IsNewNameString);
+ bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
+ bool &IsNewTypeString, bool &IsNewNameString,
+ TreeNode *&Result);
TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
- TreeNode &addLanguageNode(const ResourceEntryRef &Entry);
- TreeNode &addChild(uint32_t ID, bool IsDataNode = false,
- uint16_t MajorVersion = 0, uint16_t MinorVersion = 0,
- uint32_t Characteristics = 0);
- TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
+ bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
+ TreeNode *&Result);
+ bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
+ uint32_t Characteristics, uint32_t Origin,
+ TreeNode *&Result);
+ TreeNode &addIDChild(uint32_t ID);
+ TreeNode &addNameChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
bool IsDataNode = false;
uint32_t StringIndex;
@@ -208,18 +216,26 @@
uint16_t MajorVersion = 0;
uint16_t MinorVersion = 0;
uint32_t Characteristics = 0;
+
+ // The .res file that defined this TreeNode, for diagnostics.
+ // Index into InputFilenames.
+ uint32_t Origin;
};
private:
TreeNode Root;
std::vector<std::vector<uint8_t>> Data;
std::vector<std::vector<UTF16>> StringTable;
+
+ std::vector<std::string> InputFilenames;
};
Expected<std::unique_ptr<MemoryBuffer>>
writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
- const WindowsResourceParser &Parser);
+ const WindowsResourceParser &Parser,
+ uint32_t TimeDateStamp);
+void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
} // namespace object
} // namespace llvm
diff --git a/linux-x64/clang/include/llvm/Object/XCOFFObjectFile.h b/linux-x64/clang/include/llvm/Object/XCOFFObjectFile.h
new file mode 100644
index 0000000..cdee712
--- /dev/null
+++ b/linux-x64/clang/include/llvm/Object/XCOFFObjectFile.h
@@ -0,0 +1,268 @@
+//===- XCOFFObjectFile.h - XCOFF object file 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the XCOFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
+#define LLVM_OBJECT_XCOFFOBJECTFILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/BinaryFormat/XCOFF.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+struct XCOFFFileHeader32 {
+ support::ubig16_t Magic;
+ support::ubig16_t NumberOfSections;
+
+ // Unix time value, value of 0 indicates no timestamp.
+ // Negative values are reserved.
+ support::big32_t TimeStamp;
+
+ support::ubig32_t SymbolTableOffset; // File offset to symbol table.
+ support::big32_t NumberOfSymTableEntries;
+ support::ubig16_t AuxHeaderSize;
+ support::ubig16_t Flags;
+};
+
+struct XCOFFFileHeader64 {
+ support::ubig16_t Magic;
+ support::ubig16_t NumberOfSections;
+
+ // Unix time value, value of 0 indicates no timestamp.
+ // Negative values are reserved.
+ support::big32_t TimeStamp;
+
+ support::ubig64_t SymbolTableOffset; // File offset to symbol table.
+ support::ubig16_t AuxHeaderSize;
+ support::ubig16_t Flags;
+ support::ubig32_t NumberOfSymTableEntries;
+};
+
+struct XCOFFSectionHeader32 {
+ char Name[XCOFF::SectionNameSize];
+ support::ubig32_t PhysicalAddress;
+ support::ubig32_t VirtualAddress;
+ support::ubig32_t SectionSize;
+ support::ubig32_t FileOffsetToRawData;
+ support::ubig32_t FileOffsetToRelocationInfo;
+ support::ubig32_t FileOffsetToLineNumberInfo;
+ support::ubig16_t NumberOfRelocations;
+ support::ubig16_t NumberOfLineNumbers;
+ support::big32_t Flags;
+
+ StringRef getName() const;
+};
+
+struct XCOFFSectionHeader64 {
+ char Name[XCOFF::SectionNameSize];
+ support::ubig64_t PhysicalAddress;
+ support::ubig64_t VirtualAddress;
+ support::ubig64_t SectionSize;
+ support::big64_t FileOffsetToRawData;
+ support::big64_t FileOffsetToRelocationInfo;
+ support::big64_t FileOffsetToLineNumberInfo;
+ support::ubig32_t NumberOfRelocations;
+ support::ubig32_t NumberOfLineNumbers;
+ support::big32_t Flags;
+ char Padding[4];
+
+ StringRef getName() const;
+};
+
+struct XCOFFSymbolEntry {
+ enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
+ typedef struct {
+ support::big32_t Magic; // Zero indicates name in string table.
+ support::ubig32_t Offset;
+ } NameInStrTblType;
+
+ typedef struct {
+ uint8_t LanguageId;
+ uint8_t CpuTypeId;
+ } CFileLanguageIdAndTypeIdType;
+
+ union {
+ char SymbolName[XCOFF::SymbolNameSize];
+ NameInStrTblType NameInStrTbl;
+ };
+
+ support::ubig32_t Value; // Symbol value; storage class-dependent.
+ support::big16_t SectionNumber;
+
+ union {
+ support::ubig16_t SymbolType;
+ CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+ };
+
+ XCOFF::StorageClass StorageClass;
+ uint8_t NumberOfAuxEntries;
+};
+
+struct XCOFFStringTable {
+ uint32_t Size;
+ const char *Data;
+};
+
+class XCOFFObjectFile : public ObjectFile {
+private:
+ const void *FileHeader = nullptr;
+ const void *SectionHeaderTable = nullptr;
+
+ const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
+ XCOFFStringTable StringTable = {0, nullptr};
+
+ const XCOFFFileHeader32 *fileHeader32() const;
+ const XCOFFFileHeader64 *fileHeader64() const;
+
+ const XCOFFSectionHeader32 *sectionHeaderTable32() const;
+ const XCOFFSectionHeader64 *sectionHeaderTable64() const;
+
+ size_t getFileHeaderSize() const;
+ size_t getSectionHeaderSize() const;
+
+ const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
+ const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
+ void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
+ uintptr_t getSectionHeaderTableAddress() const;
+
+ // This returns a pointer to the start of the storage for the name field of
+ // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
+ // null-terminated.
+ const char *getSectionNameInternal(DataRefImpl Sec) const;
+
+ int32_t getSectionFlags(DataRefImpl Sec) const;
+
+ static bool isReservedSectionNumber(int16_t SectionNumber);
+ Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
+
+ // Constructor and "create" factory function. The constructor is only a thin
+ // wrapper around the base constructor. The "create" function fills out the
+ // XCOFF-specific information and performs the error checking along the way.
+ XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
+ static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
+ MemoryBufferRef MBR);
+
+ // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
+ // and an XCOFFStringTable if parsing succeeded.
+ static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
+ uint64_t Offset);
+
+ // Make a friend so it can call the private 'create' function.
+ friend Expected<std::unique_ptr<ObjectFile>>
+ ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
+
+public:
+ // Interface inherited from base classes.
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override;
+ Expected<uint64_t> getStartAddress() const override;
+ bool isRelocatableObject() const override;
+
+ // Below here is the non-inherited interface.
+ bool is64Bit() const;
+
+ const XCOFFSymbolEntry *getPointerToSymbolTable() const {
+ assert(!is64Bit() && "Symbol table handling not supported yet.");
+ return SymbolTblPtr;
+ }
+
+ Expected<StringRef>
+ getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
+
+ const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
+
+ // File header related interfaces.
+ uint16_t getMagic() const;
+ uint16_t getNumberOfSections() const;
+ int32_t getTimeStamp() const;
+
+ // Symbol table offset and entry count are handled differently between
+ // XCOFF32 and XCOFF64.
+ uint32_t getSymbolTableOffset32() const;
+ uint64_t getSymbolTableOffset64() const;
+
+ // Note that this value is signed and might return a negative value. Negative
+ // values are reserved for future use.
+ int32_t getRawNumberOfSymbolTableEntries32() const;
+
+ // The sanitized value appropriate to use as an index into the symbol table.
+ uint32_t getLogicalNumberOfSymbolTableEntries32() const;
+
+ uint32_t getNumberOfSymbolTableEntries64() const;
+
+ uint16_t getOptionalHeaderSize() const;
+ uint16_t getFlags() const;
+
+ // Section header table related interfaces.
+ ArrayRef<XCOFFSectionHeader32> sections32() const;
+ ArrayRef<XCOFFSectionHeader64> sections64() const;
+}; // XCOFFObjectFile
+
+} // namespace object
+} // namespace llvm
+
+#endif // LLVM_OBJECT_XCOFFOBJECTFILE_H