summaryrefslogtreecommitdiff
path: root/include/llvm/Object
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /include/llvm/Object
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
Diffstat (limited to 'include/llvm/Object')
-rw-r--r--include/llvm/Object/Archive.h58
-rw-r--r--include/llvm/Object/ArchiveWriter.h45
-rw-r--r--include/llvm/Object/Binary.h12
-rw-r--r--include/llvm/Object/COFF.h142
-rw-r--r--include/llvm/Object/COFFYAML.h223
-rw-r--r--include/llvm/Object/ELF.h78
-rw-r--r--include/llvm/Object/ELFObjectFile.h146
-rw-r--r--include/llvm/Object/ELFTypes.h89
-rw-r--r--include/llvm/Object/ELFYAML.h319
-rw-r--r--include/llvm/Object/Error.h47
-rw-r--r--include/llvm/Object/FunctionIndexObjectFile.h110
-rw-r--r--include/llvm/Object/IRObjectFile.h10
-rw-r--r--include/llvm/Object/MachO.h30
-rw-r--r--include/llvm/Object/MachOUniversal.h70
-rw-r--r--include/llvm/Object/ModuleSummaryIndexObjectFile.h103
-rw-r--r--include/llvm/Object/ObjectFile.h48
-rw-r--r--include/llvm/Object/RelocVisitor.h16
-rw-r--r--include/llvm/Object/StackMapParser.h3
-rw-r--r--include/llvm/Object/SymbolicFile.h9
19 files changed, 677 insertions, 881 deletions
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 8dd042a2533fe..cfba2567371ac 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -14,6 +14,7 @@
#ifndef LLVM_OBJECT_ARCHIVE_H
#define LLVM_OBJECT_ARCHIVE_H
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Object/Binary.h"
@@ -42,7 +43,7 @@ struct ArchiveMemberHeader {
sys::fs::perms getAccessMode() const;
sys::TimeValue getLastModified() const;
llvm::StringRef getRawLastModified() const {
- return StringRef(LastModified, sizeof(LastModified)).rtrim(" ");
+ return StringRef(LastModified, sizeof(LastModified)).rtrim(' ');
}
unsigned getUID() const;
unsigned getGID() const;
@@ -78,6 +79,7 @@ public:
ErrorOr<Child> getNext() const;
ErrorOr<StringRef> getName() const;
+ ErrorOr<std::string> getFullName() const;
StringRef getRawName() const { return getHeader()->getName(); }
sys::TimeValue getLastModified() const {
return getHeader()->getLastModified();
@@ -100,26 +102,25 @@ public:
ErrorOr<MemoryBufferRef> getMemoryBufferRef() const;
- ErrorOr<std::unique_ptr<Binary>>
+ Expected<std::unique_ptr<Binary>>
getAsBinary(LLVMContext *Context = nullptr) const;
};
class child_iterator {
- ErrorOr<Child> child;
+ Child C;
+ Error *E;
public:
- child_iterator() : child(Child(nullptr, nullptr, nullptr)) {}
- child_iterator(const Child &c) : child(c) {}
- child_iterator(std::error_code EC) : child(EC) {}
- const ErrorOr<Child> *operator->() const { return &child; }
- const ErrorOr<Child> &operator*() const { return child; }
+ child_iterator() : C(Child(nullptr, nullptr, nullptr)), E(nullptr) {}
+ child_iterator(const Child &C, Error *E) : C(C), E(E) {}
+ const Child *operator->() const { return &C; }
+ const Child &operator*() const { return C; }
bool operator==(const child_iterator &other) const {
- // We ignore error states so that comparisions with end() work, which
- // allows range loops.
- if (child.getError() || other.child.getError())
- return false;
- return *child == *other.child;
+ // Ignore errors here: If an error occurred during increment then getNext
+ // will have been set to child_end(), and the following comparison should
+ // do the right thing.
+ return C == other.C;
}
bool operator!=(const child_iterator &other) const {
@@ -129,8 +130,15 @@ public:
// Code in loops with child_iterators must check for errors on each loop
// iteration. And if there is an error break out of the loop.
child_iterator &operator++() { // Preincrement
- assert(child && "Can't increment iterator with error");
- child = child->getNext();
+ assert(E && "Can't increment iterator with no Error attached");
+ if (auto ChildOrErr = C.getNext())
+ C = *ChildOrErr;
+ else {
+ ErrorAsOutParameter ErrAsOutParam(*E);
+ C = C.getParent()->child_end().C;
+ *E = errorCodeToError(ChildOrErr.getError());
+ E = nullptr;
+ }
return *this;
}
};
@@ -175,23 +183,25 @@ public:
}
};
- Archive(MemoryBufferRef Source, std::error_code &EC);
- static ErrorOr<std::unique_ptr<Archive>> create(MemoryBufferRef Source);
+ Archive(MemoryBufferRef Source, Error &Err);
+ static Expected<std::unique_ptr<Archive>> create(MemoryBufferRef Source);
enum Kind {
K_GNU,
K_MIPS64,
K_BSD,
+ K_DARWIN64,
K_COFF
};
Kind kind() const { return (Kind)Format; }
bool isThin() const { return IsThin; }
- child_iterator child_begin(bool SkipInternal = true) const;
+ child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
child_iterator child_end() const;
- iterator_range<child_iterator> children(bool SkipInternal = true) const {
- return make_range(child_begin(SkipInternal), child_end());
+ iterator_range<child_iterator> children(Error &Err,
+ bool SkipInternal = true) const {
+ return make_range(child_begin(Err, SkipInternal), child_end());
}
symbol_iterator symbol_begin() const;
@@ -206,12 +216,16 @@ public:
}
// check if a symbol is in the archive
- child_iterator findSym(StringRef name) const;
+ Expected<Optional<Child>> findSym(StringRef name) const;
bool hasSymbolTable() const;
StringRef getSymbolTable() const { return SymbolTable; }
uint32_t getNumberOfSymbols() const;
+ std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
+ return std::move(ThinBuffers);
+ }
+
private:
StringRef SymbolTable;
StringRef StringTable;
@@ -220,7 +234,7 @@ private:
uint16_t FirstRegularStartOfFile = -1;
void setFirstRegular(const Child &C);
- unsigned Format : 2;
+ unsigned Format : 3;
unsigned IsThin : 1;
mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
};
diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h
index b5d2ba3580809..55b58fac4f66b 100644
--- a/include/llvm/Object/ArchiveWriter.h
+++ b/include/llvm/Object/ArchiveWriter.h
@@ -20,29 +20,36 @@
namespace llvm {
-class NewArchiveIterator {
- bool IsNewMember;
- StringRef Name;
-
- object::Archive::Child OldMember;
-
-public:
- NewArchiveIterator(const object::Archive::Child &OldMember, StringRef Name);
- NewArchiveIterator(StringRef FileName);
- bool isNewMember() const;
- StringRef getName() const;
-
- const object::Archive::Child &getOld() const;
-
- StringRef getNew() const;
- llvm::ErrorOr<int> getFD(sys::fs::file_status &NewStatus) const;
- const sys::fs::file_status &getStatus() const;
+struct NewArchiveMember {
+ std::unique_ptr<MemoryBuffer> Buf;
+ sys::TimeValue ModTime = sys::TimeValue::PosixZeroTime();
+ unsigned UID = 0, GID = 0, Perms = 0644;
+
+ NewArchiveMember() = default;
+ NewArchiveMember(NewArchiveMember &&Other)
+ : Buf(std::move(Other.Buf)), ModTime(Other.ModTime), UID(Other.UID),
+ GID(Other.GID), Perms(Other.Perms) {}
+ NewArchiveMember &operator=(NewArchiveMember &&Other) {
+ Buf = std::move(Other.Buf);
+ ModTime = Other.ModTime;
+ UID = Other.UID;
+ GID = Other.GID;
+ Perms = Other.Perms;
+ return *this;
+ }
+ NewArchiveMember(MemoryBufferRef BufRef);
+
+ static Expected<NewArchiveMember>
+ getOldMember(const object::Archive::Child &OldMember, bool Deterministic);
+
+ static Expected<NewArchiveMember> getFile(StringRef FileName,
+ bool Deterministic);
};
std::pair<StringRef, std::error_code>
-writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
+writeArchive(StringRef ArcName, std::vector<NewArchiveMember> &NewMembers,
bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic,
- bool Thin);
+ bool Thin, std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
}
#endif
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index a0d1127781f64..5dff5406fcddc 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -42,8 +42,8 @@ protected:
ID_Archive,
ID_MachOUniversalBinary,
ID_COFFImportFile,
- ID_IR, // LLVM IR
- ID_FunctionIndex, // Function summary index
+ ID_IR, // LLVM IR
+ ID_ModuleSummaryIndex, // Module summary index
// Object and children.
ID_StartObjects,
@@ -123,7 +123,7 @@ public:
return TypeID == ID_IR;
}
- bool isFunctionIndex() const { return TypeID == ID_FunctionIndex; }
+ bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; }
bool isLittleEndian() const {
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
@@ -134,8 +134,8 @@ public:
/// @brief Create a Binary from Source, autodetecting the file type.
///
/// @param Source The data to create the Binary from.
-ErrorOr<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
- LLVMContext *Context = nullptr);
+Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
+ LLVMContext *Context = nullptr);
template <typename T> class OwningBinary {
std::unique_ptr<T> Bin;
@@ -185,7 +185,7 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
return Bin.get();
}
-ErrorOr<OwningBinary<Binary>> createBinary(StringRef Path);
+Expected<OwningBinary<Binary>> createBinary(StringRef Path);
}
}
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index 3e69c3e6e5d4f..dcc58b06e228d 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -169,6 +169,26 @@ struct import_directory_table_entry {
support::ulittle32_t ImportAddressTableRVA;
};
+struct debug_directory {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t Type;
+ support::ulittle32_t SizeOfData;
+ support::ulittle32_t AddressOfRawData;
+ support::ulittle32_t PointerToRawData;
+};
+
+/// Information that is resent in debug_directory::AddressOfRawData if Type is
+/// IMAGE_DEBUG_TYPE_CODEVIEW.
+struct debug_pdb_info {
+ support::ulittle32_t Signature;
+ uint8_t Guid[16];
+ support::ulittle32_t Age;
+ // PDBFileName: The null-terminated PDB file name follows.
+};
+
template <typename IntTy>
struct import_lookup_table_entry {
IntTy Data;
@@ -414,6 +434,18 @@ struct coff_section {
return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
NumberOfRelocations == UINT16_MAX;
}
+ uint32_t getAlignment() const {
+ // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
+ // IMAGE_SCN_ALIGN_1BYTES.
+ if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
+ return 1;
+
+ // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1.
+ uint32_t Shift = (Characteristics >> 20) & 0xF;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 1;
+ }
};
struct coff_relocation {
@@ -427,20 +459,32 @@ struct coff_aux_function_definition {
support::ulittle32_t TotalSize;
support::ulittle32_t PointerToLinenumber;
support::ulittle32_t PointerToNextFunction;
+ char Unused1[2];
};
+static_assert(sizeof(coff_aux_function_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_bf_and_ef_symbol {
char Unused1[4];
support::ulittle16_t Linenumber;
char Unused2[6];
support::ulittle32_t PointerToNextFunction;
+ char Unused3[2];
};
+static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_weak_external {
support::ulittle32_t TagIndex;
support::ulittle32_t Characteristics;
+ char Unused1[10];
};
+static_assert(sizeof(coff_aux_weak_external) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_section_definition {
support::ulittle32_t Length;
support::ulittle16_t NumberOfRelocations;
@@ -458,12 +502,19 @@ struct coff_aux_section_definition {
}
};
+static_assert(sizeof(coff_aux_section_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_clr_token {
uint8_t AuxType;
uint8_t Reserved;
support::ulittle32_t SymbolTableIndex;
+ char MBZ[12];
};
+static_assert(sizeof(coff_aux_clr_token) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_import_header {
support::ulittle16_t Sig1;
support::ulittle16_t Sig2;
@@ -485,6 +536,26 @@ struct coff_import_directory_table_entry {
support::ulittle32_t ImportAddressTableRVA;
};
+template <typename IntTy>
+struct coff_tls_directory {
+ IntTy StartAddressOfRawData;
+ IntTy EndAddressOfRawData;
+ IntTy AddressOfIndex;
+ IntTy AddressOfCallBacks;
+ support::ulittle32_t SizeOfZeroFill;
+ support::ulittle32_t Characteristics;
+ uint32_t getAlignment() const {
+ // Bit [20:24] contains section alignment.
+ uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 0;
+ }
+};
+
+typedef coff_tls_directory<support::little32_t> coff_tls_directory32;
+typedef coff_tls_directory<support::little64_t> coff_tls_directory64;
+
struct coff_load_configuration32 {
support::ulittle32_t Characteristics;
support::ulittle32_t TimeDateStamp;
@@ -563,12 +634,13 @@ private:
const char *StringTable;
uint32_t StringTableSize;
const import_directory_table_entry *ImportDirectory;
- uint32_t NumberOfImportDirectory;
const delay_import_directory_table_entry *DelayImportDirectory;
uint32_t NumberOfDelayImportDirectory;
const export_directory_table_entry *ExportDirectory;
const coff_base_reloc_block_header *BaseRelocHeader;
const coff_base_reloc_block_header *BaseRelocEnd;
+ const debug_directory *DebugDirectoryBegin;
+ const debug_directory *DebugDirectoryEnd;
std::error_code getString(uint32_t offset, StringRef &Res) const;
@@ -582,6 +654,7 @@ private:
std::error_code initDelayImportTablePtr();
std::error_code initExportTablePtr();
std::error_code initBaseRelocPtr();
+ std::error_code initDebugDirectoryPtr();
public:
uintptr_t getSymbolTable() const {
@@ -647,13 +720,13 @@ public:
}
protected:
void moveSymbolNext(DataRefImpl &Symb) const override;
- ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
- ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) 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;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
- ErrorOr<section_iterator> getSymbolSection(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;
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
@@ -662,6 +735,7 @@ protected:
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) 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;
@@ -693,6 +767,7 @@ public:
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
unsigned getArch() const override;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
import_directory_iterator import_directory_begin() const;
import_directory_iterator import_directory_end() const;
@@ -702,12 +777,21 @@ public:
export_directory_iterator export_directory_end() const;
base_reloc_iterator base_reloc_begin() const;
base_reloc_iterator base_reloc_end() const;
+ const debug_directory *debug_directory_begin() const {
+ return DebugDirectoryBegin;
+ }
+ const debug_directory *debug_directory_end() const {
+ return DebugDirectoryEnd;
+ }
iterator_range<import_directory_iterator> import_directories() const;
iterator_range<delay_import_directory_iterator>
delay_import_directories() const;
iterator_range<export_directory_iterator> export_directories() const;
iterator_range<base_reloc_iterator> base_relocs() const;
+ iterator_range<const debug_directory *> debug_directories() const {
+ return make_range(debug_directory_begin(), debug_directory_end());
+ }
const dos_header *getDOSHeader() const {
if (!PE32Header && !PE32PlusHeader)
@@ -776,9 +860,28 @@ public:
uint64_t getImageBase() const;
std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+
+ /// Given an RVA base and size, returns a valid array of bytes or an error
+ /// code if the RVA and size is not contained completely within a valid
+ /// section.
+ std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const;
+
std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
StringRef &Name) const;
+ /// Get PDB information out of a codeview debug directory entry.
+ std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
+ const debug_pdb_info *&Info,
+ StringRef &PDBFileName) const;
+
+ /// Get PDB information from an executable. If the information is not present,
+ /// Info will be set to nullptr and PDBFileName will be empty. An error is
+ /// returned only on corrupt object files. Convenience accessor that can be
+ /// used if the debug directory is not already handy.
+ std::error_code getDebugPDBInfo(const debug_pdb_info *&Info,
+ StringRef &PDBFileName) const;
+
bool isRelocatableObject() const override;
bool is64() const { return PE32PlusHeader; }
@@ -807,9 +910,6 @@ public:
std::error_code
getImportTableEntry(const import_directory_table_entry *&Result) const;
- std::error_code
- getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
-
private:
const import_directory_table_entry *ImportTable;
uint32_t Index;
@@ -881,7 +981,9 @@ public:
void moveNext();
std::error_code getSymbolName(StringRef &Result) const;
+ std::error_code isOrdinal(bool &Result) const;
std::error_code getOrdinal(uint16_t &Result) const;
+ std::error_code getHintNameRVA(uint32_t &Result) const;
private:
const import_lookup_table_entry32 *Entry32;
@@ -909,6 +1011,30 @@ private:
const COFFObjectFile *OwningObject;
};
+// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
+struct FpoData {
+ support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
+ support::ulittle32_t Size; // cbProcSize: # bytes in function
+ support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
+ support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
+ support::ulittle16_t Attributes;
+
+ // cbProlog: # bytes in prolog
+ int getPrologSize() const { return Attributes & 0xF; }
+
+ // cbRegs: # regs saved
+ int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
+
+ // fHasSEH: true if seh is func
+ bool hasSEH() const { return (Attributes >> 9) & 1; }
+
+ // fUseBP: true if EBP has been allocated
+ bool useBP() const { return (Attributes >> 10) & 1; }
+
+ // cbFrame: frame pointer
+ int getFP() const { return Attributes >> 14; }
+};
+
} // end namespace object
} // end namespace llvm
diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h
deleted file mode 100644
index 12a25223bd37e..0000000000000
--- a/include/llvm/Object/COFFYAML.h
+++ /dev/null
@@ -1,223 +0,0 @@
-//===- COFFYAML.h - COFF YAMLIO implementation ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares classes for handling the YAML representation of COFF.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_COFFYAML_H
-#define LLVM_OBJECT_COFFYAML_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/MC/YAML.h"
-#include "llvm/Support/COFF.h"
-
-namespace llvm {
-
-namespace COFF {
-inline Characteristics operator|(Characteristics a, Characteristics b) {
- uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b);
- return static_cast<Characteristics>(Ret);
-}
-
-inline SectionCharacteristics operator|(SectionCharacteristics a,
- SectionCharacteristics b) {
- uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b);
- return static_cast<SectionCharacteristics>(Ret);
-}
-
-inline DLLCharacteristics operator|(DLLCharacteristics a,
- DLLCharacteristics b) {
- uint16_t Ret = static_cast<uint16_t>(a) | static_cast<uint16_t>(b);
- return static_cast<DLLCharacteristics>(Ret);
-}
-}
-
-// The structure of the yaml files is not an exact 1:1 match to COFF. In order
-// to use yaml::IO, we use these structures which are closer to the source.
-namespace COFFYAML {
- LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
- LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
- LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
-
- struct Relocation {
- uint32_t VirtualAddress;
- uint16_t Type;
- StringRef SymbolName;
- };
-
- struct Section {
- COFF::section Header;
- unsigned Alignment;
- yaml::BinaryRef SectionData;
- std::vector<Relocation> Relocations;
- StringRef Name;
- Section();
- };
-
- struct Symbol {
- COFF::symbol Header;
- COFF::SymbolBaseType SimpleType;
- COFF::SymbolComplexType ComplexType;
- Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition;
- Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol;
- Optional<COFF::AuxiliaryWeakExternal> WeakExternal;
- StringRef File;
- Optional<COFF::AuxiliarySectionDefinition> SectionDefinition;
- Optional<COFF::AuxiliaryCLRToken> CLRToken;
- StringRef Name;
- Symbol();
- };
-
- struct PEHeader {
- COFF::PE32Header Header;
- Optional<COFF::DataDirectory> DataDirectories[COFF::NUM_DATA_DIRECTORIES];
- };
-
- struct Object {
- Optional<PEHeader> OptionalHeader;
- COFF::header Header;
- std::vector<Section> Sections;
- std::vector<Symbol> Symbols;
- Object();
- };
-}
-}
-
-LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section)
-LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol)
-LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation)
-
-namespace llvm {
-namespace yaml {
-
-template <>
-struct ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics> {
- static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFFYAML::AuxSymbolType> {
- static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFFYAML::COMDATType> {
- static void enumeration(IO &IO, COFFYAML::COMDATType &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::MachineTypes> {
- static void enumeration(IO &IO, COFF::MachineTypes &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::SymbolBaseType> {
- static void enumeration(IO &IO, COFF::SymbolBaseType &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::SymbolStorageClass> {
- static void enumeration(IO &IO, COFF::SymbolStorageClass &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::SymbolComplexType> {
- static void enumeration(IO &IO, COFF::SymbolComplexType &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::RelocationTypeI386> {
- static void enumeration(IO &IO, COFF::RelocationTypeI386 &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::RelocationTypeAMD64> {
- static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<COFF::WindowsSubsystem> {
- static void enumeration(IO &IO, COFF::WindowsSubsystem &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<COFF::Characteristics> {
- static void bitset(IO &IO, COFF::Characteristics &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<COFF::SectionCharacteristics> {
- static void bitset(IO &IO, COFF::SectionCharacteristics &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<COFF::DLLCharacteristics> {
- static void bitset(IO &IO, COFF::DLLCharacteristics &Value);
-};
-
-template <>
-struct MappingTraits<COFFYAML::Relocation> {
- static void mapping(IO &IO, COFFYAML::Relocation &Rel);
-};
-
-template <>
-struct MappingTraits<COFFYAML::PEHeader> {
- static void mapping(IO &IO, COFFYAML::PEHeader &PH);
-};
-
-template <>
-struct MappingTraits<COFF::DataDirectory> {
- static void mapping(IO &IO, COFF::DataDirectory &DD);
-};
-
-template <>
-struct MappingTraits<COFF::header> {
- static void mapping(IO &IO, COFF::header &H);
-};
-
-template <> struct MappingTraits<COFF::AuxiliaryFunctionDefinition> {
- static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD);
-};
-
-template <> struct MappingTraits<COFF::AuxiliarybfAndefSymbol> {
- static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS);
-};
-
-template <> struct MappingTraits<COFF::AuxiliaryWeakExternal> {
- static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE);
-};
-
-template <> struct MappingTraits<COFF::AuxiliarySectionDefinition> {
- static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD);
-};
-
-template <> struct MappingTraits<COFF::AuxiliaryCLRToken> {
- static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT);
-};
-
-template <>
-struct MappingTraits<COFFYAML::Symbol> {
- static void mapping(IO &IO, COFFYAML::Symbol &S);
-};
-
-template <>
-struct MappingTraits<COFFYAML::Section> {
- static void mapping(IO &IO, COFFYAML::Section &Sec);
-};
-
-template <>
-struct MappingTraits<COFFYAML::Object> {
- static void mapping(IO &IO, COFFYAML::Object &Obj);
-};
-
-} // end namespace yaml
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index b0eaa3f5ed4d8..80b8be03810cc 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -54,14 +54,19 @@ public:
typedef Elf_Versym_Impl<ELFT> Elf_Versym;
typedef Elf_Hash_Impl<ELFT> Elf_Hash;
typedef Elf_GnuHash_Impl<ELFT> Elf_GnuHash;
- typedef iterator_range<const Elf_Dyn *> Elf_Dyn_Range;
- typedef iterator_range<const Elf_Shdr *> Elf_Shdr_Range;
- typedef iterator_range<const Elf_Sym *> Elf_Sym_Range;
+ typedef typename ELFT::DynRange Elf_Dyn_Range;
+ typedef typename ELFT::ShdrRange Elf_Shdr_Range;
+ typedef typename ELFT::SymRange Elf_Sym_Range;
+ typedef typename ELFT::RelRange Elf_Rel_Range;
+ typedef typename ELFT::RelaRange Elf_Rela_Range;
+ typedef typename ELFT::PhdrRange Elf_Phdr_Range;
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Buf.data());
}
+ size_t getBufSize() const { return Buf.size(); }
+
private:
StringRef Buf;
@@ -104,22 +109,10 @@ public:
Header->getDataEncoding() == ELF::ELFDATA2LSB;
}
- ErrorOr<const Elf_Dyn *> dynamic_table_begin(const Elf_Phdr *Phdr) const;
- ErrorOr<const Elf_Dyn *> dynamic_table_end(const Elf_Phdr *Phdr) const;
- ErrorOr<Elf_Dyn_Range> dynamic_table(const Elf_Phdr *Phdr) const {
- ErrorOr<const Elf_Dyn *> Begin = dynamic_table_begin(Phdr);
- if (std::error_code EC = Begin.getError())
- return EC;
- ErrorOr<const Elf_Dyn *> End = dynamic_table_end(Phdr);
- if (std::error_code EC = End.getError())
- return EC;
- return make_range(*Begin, *End);
- }
-
const Elf_Shdr *section_begin() const;
const Elf_Shdr *section_end() const;
Elf_Shdr_Range sections() const {
- return make_range(section_begin(), section_end());
+ return makeArrayRef(section_begin(), section_end());
}
const Elf_Sym *symbol_begin(const Elf_Shdr *Sec) const {
@@ -138,11 +131,9 @@ public:
return symbol_begin(Sec) + Size / sizeof(Elf_Sym);
}
Elf_Sym_Range symbols(const Elf_Shdr *Sec) const {
- return make_range(symbol_begin(Sec), symbol_end(Sec));
+ return makeArrayRef(symbol_begin(Sec), symbol_end(Sec));
}
- typedef iterator_range<const Elf_Rela *> Elf_Rela_Range;
-
const Elf_Rela *rela_begin(const Elf_Shdr *sec) const {
if (sec->sh_entsize != sizeof(Elf_Rela))
report_fatal_error("Invalid relocation entry size");
@@ -157,7 +148,7 @@ public:
}
Elf_Rela_Range relas(const Elf_Shdr *Sec) const {
- return make_range(rela_begin(Sec), rela_end(Sec));
+ return makeArrayRef(rela_begin(Sec), rela_end(Sec));
}
const Elf_Rel *rel_begin(const Elf_Shdr *sec) const {
@@ -173,9 +164,8 @@ public:
return rel_begin(sec) + Size / sizeof(Elf_Rel);
}
- typedef iterator_range<const Elf_Rel *> Elf_Rel_Range;
Elf_Rel_Range rels(const Elf_Shdr *Sec) const {
- return make_range(rel_begin(Sec), rel_end(Sec));
+ return makeArrayRef(rel_begin(Sec), rel_end(Sec));
}
/// \brief Iterate over program header table.
@@ -189,10 +179,8 @@ public:
return program_header_begin() + Header->e_phnum;
}
- typedef iterator_range<const Elf_Phdr *> Elf_Phdr_Range;
-
const Elf_Phdr_Range program_headers() const {
- return make_range(program_header_begin(), program_header_end());
+ return makeArrayRef(program_header_begin(), program_header_end());
}
uint64_t getNumSections() const;
@@ -200,6 +188,9 @@ public:
uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
const Elf_Shdr *SymTab,
ArrayRef<Elf_Word> ShndxTable) const;
+ uint32_t getExtendedSymbolTableIndex(const Elf_Sym *Sym,
+ const Elf_Sym *FirstSym,
+ ArrayRef<Elf_Word> ShndxTable) const;
const Elf_Ehdr *getHeader() const { return Header; }
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
const Elf_Shdr *SymTab,
@@ -225,8 +216,15 @@ template <class ELFT>
uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex(
const Elf_Sym *Sym, const Elf_Shdr *SymTab,
ArrayRef<Elf_Word> ShndxTable) const {
+ return getExtendedSymbolTableIndex(Sym, symbol_begin(SymTab), ShndxTable);
+}
+
+template <class ELFT>
+uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex(
+ const Elf_Sym *Sym, const Elf_Sym *FirstSym,
+ ArrayRef<Elf_Word> ShndxTable) const {
assert(Sym->st_shndx == ELF::SHN_XINDEX);
- unsigned Index = Sym - symbol_begin(SymTab);
+ unsigned Index = Sym - FirstSym;
// The size of the table was checked in getSHNDXTable.
return ShndxTable[Index];
@@ -404,34 +402,6 @@ const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const {
}
template <class ELFT>
-ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *>
-ELFFile<ELFT>::dynamic_table_begin(const Elf_Phdr *Phdr) const {
- if (!Phdr)
- return nullptr;
- assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
- uintX_t Offset = Phdr->p_offset;
- if (Offset > Buf.size())
- return object_error::parse_failed;
- return reinterpret_cast<const Elf_Dyn *>(base() + Offset);
-}
-
-template <class ELFT>
-ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *>
-ELFFile<ELFT>::dynamic_table_end(const Elf_Phdr *Phdr) const {
- if (!Phdr)
- return nullptr;
- assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
- uintX_t Size = Phdr->p_filesz;
- if (Size % sizeof(Elf_Dyn))
- return object_error::elf_invalid_dynamic_table_size;
- // FIKME: Check for overflow?
- uintX_t End = Phdr->p_offset + Size;
- if (End > Buf.size())
- return object_error::parse_failed;
- return reinterpret_cast<const Elf_Dyn *>(base() + End);
-}
-
-template <class ELFT>
template <typename T>
const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const {
ErrorOr<const Elf_Shdr *> Sec = getSection(Section);
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 5d826da4c2fc2..07c6364a68949 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -14,23 +14,28 @@
#ifndef LLVM_OBJECT_ELFOBJECTFILE_H
#define LLVM_OBJECT_ELFOBJECTFILE_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cctype>
-#include <limits>
-#include <utility>
+#include <cassert>
+#include <cstdint>
+#include <system_error>
namespace llvm {
namespace object {
@@ -47,6 +52,7 @@ class ELFObjectFileBase : public ObjectFile {
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
+ virtual uint16_t getEMachine() const = 0;
virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
@@ -55,14 +61,16 @@ protected:
virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
-public:
+public:
typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
elf_symbol_iterator_range symbols() const;
static inline bool classof(const Binary *v) { return v->isELF(); }
+
+ SubtargetFeatures getFeatures() const override;
};
class ELFSectionRef : public SectionRef {
@@ -175,6 +183,7 @@ ELFObjectFileBase::symbols() const {
}
template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
+ uint16_t getEMachine() const override;
uint64_t getSymbolSize(DataRefImpl Sym) const override;
public:
@@ -197,18 +206,18 @@ protected:
ArrayRef<Elf_Word> ShndxTable;
void moveSymbolNext(DataRefImpl &Symb) const override;
- ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
- ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
uint8_t getSymbolOther(DataRefImpl Symb) const override;
uint8_t getSymbolELFType(DataRefImpl Symb) const override;
- SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
- ErrorOr<section_iterator> getSymbolSection(const Elf_Sym *Symb,
- const Elf_Shdr *SymTab) const;
- ErrorOr<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
+ const Elf_Shdr *SymTab) const;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
std::error_code getSectionName(DataRefImpl Sec,
@@ -218,6 +227,7 @@ protected:
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) 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;
@@ -284,11 +294,9 @@ protected:
// A symbol is exported if its binding is either GLOBAL or WEAK, and its
// visibility is either DEFAULT or PROTECTED. All other symbols are not
// exported.
- if ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) &&
- (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED))
- return true;
-
- return false;
+ return ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) &&
+ (Visibility == ELF::STV_DEFAULT ||
+ Visibility == ELF::STV_PROTECTED));
}
// This flag is used for classof, to distinguish ELFObjectFile from
@@ -354,7 +362,7 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
}
template <class ELFT>
-ErrorOr<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
+Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
const Elf_Sym *ESym = getSymbol(Sym);
const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a);
const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link);
@@ -389,7 +397,7 @@ uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
}
template <class ELFT>
-ErrorOr<uint64_t>
+Expected<uint64_t>
ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
uint64_t Result = getSymbolValue(Symb);
const Elf_Sym *ESym = getSymbol(Symb);
@@ -407,7 +415,7 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
ErrorOr<const Elf_Shdr *> SectionOrErr =
EF.getSection(ESym, SymTab, ShndxTable);
if (std::error_code EC = SectionOrErr.getError())
- return EC;
+ return errorCodeToError(EC);
const Elf_Shdr *Section = *SectionOrErr;
if (Section)
Result += Section->sh_addr;
@@ -425,6 +433,11 @@ uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
}
template <class ELFT>
+uint16_t ELFObjectFile<ELFT>::getEMachine() const {
+ return EF.getHeader()->e_machine;
+}
+
+template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
return getSymbol(Sym)->st_size;
}
@@ -445,7 +458,8 @@ uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
}
template <class ELFT>
-SymbolRef::Type ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
+Expected<SymbolRef::Type>
+ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
const Elf_Sym *ESym = getSymbol(Symb);
switch (ESym->getType()) {
@@ -487,12 +501,17 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
Result |= SymbolRef::SF_FormatSpecific;
if (EF.getHeader()->e_machine == ELF::EM_ARM) {
- if (ErrorOr<StringRef> NameOrErr = getSymbolName(Sym)) {
+ if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$t") ||
Name.startswith("$a"))
Result |= SymbolRef::SF_FormatSpecific;
+ } else {
+ // TODO: Actually report errors helpfully.
+ consumeError(NameOrErr.takeError());
}
+ if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
+ Result |= SymbolRef::SF_Thumb;
}
if (ESym->st_shndx == ELF::SHN_UNDEF)
@@ -511,12 +530,12 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
}
template <class ELFT>
-ErrorOr<section_iterator>
+Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
const Elf_Shdr *SymTab) const {
ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
if (std::error_code EC = ESecOrErr.getError())
- return EC;
+ return errorCodeToError(EC);
const Elf_Shdr *ESec = *ESecOrErr;
if (!ESec)
@@ -528,7 +547,7 @@ ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
}
template <class ELFT>
-ErrorOr<section_iterator>
+Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
const Elf_Sym *Sym = getSymbol(Symb);
const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
@@ -576,6 +595,11 @@ uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
}
template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
+}
+
+template <class ELFT>
bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
}
@@ -606,22 +630,6 @@ ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
RelData.d.b = 0;
-
- const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
- return relocation_iterator(RelocationRef(RelData, this));
-
- const Elf_Shdr *RelSec = getRelSection(RelData);
- ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link);
- if (std::error_code EC = SymSecOrErr.getError())
- report_fatal_error(EC.message());
- const Elf_Shdr *SymSec = *SymSecOrErr;
- uint32_t SymSecType = SymSec->sh_type;
- if (SymSecType != ELF::SHT_SYMTAB && SymSecType != ELF::SHT_DYNSYM)
- report_fatal_error("Invalid symbol table section type!");
- if (SymSecType == ELF::SHT_DYNSYM)
- RelData.d.b = 1;
-
return relocation_iterator(RelocationRef(RelData, this));
}
@@ -633,7 +641,14 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
return Begin;
DataRefImpl RelData = Begin->getRawDataRefImpl();
- RelData.d.b += (S->sh_size / S->sh_entsize) << 1;
+ const Elf_Shdr *RelSec = getRelSection(RelData);
+
+ // Error check sh_link here so that getRelocationSymbol can just use it.
+ ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link);
+ if (std::error_code EC = SymSecOrErr.getError())
+ report_fatal_error(EC.message());
+
+ RelData.d.b += S->sh_size / S->sh_entsize;
return relocation_iterator(RelocationRef(RelData, this));
}
@@ -657,7 +672,7 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
// Relocations
template <class ELFT>
void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
- Rel.d.b += 2;
+ ++Rel.d.b;
}
template <class ELFT>
@@ -672,12 +687,10 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
if (!symbolIdx)
return symbol_end();
- bool IsDyn = Rel.d.b & 1;
+ // FIXME: error check symbolIdx
DataRefImpl SymbolData;
- if (IsDyn)
- SymbolData = toDRI(DotDynSymSec, symbolIdx);
- else
- SymbolData = toDRI(DotSymtabSec, symbolIdx);
+ SymbolData.d.a = sec->sh_link;
+ SymbolData.d.b = symbolIdx;
return symbol_iterator(SymbolRef(SymbolData, this));
}
@@ -725,14 +738,14 @@ template <class ELFT>
const typename ELFObjectFile<ELFT>::Elf_Rel *
ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
- return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b >> 1);
+ return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
}
template <class ELFT>
const typename ELFObjectFile<ELFT>::Elf_Rela *
ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
- return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b >> 1);
+ return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
}
template <class ELFT>
@@ -835,6 +848,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF32-avr";
case ELF::EM_HEXAGON:
return "ELF32-hexagon";
+ case ELF::EM_LANAI:
+ return "ELF32-lanai";
case ELF::EM_MIPS:
return "ELF32-mips";
case ELF::EM_PPC:
@@ -844,6 +859,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF32-sparc";
case ELF::EM_WEBASSEMBLY:
return "ELF32-wasm";
+ case ELF::EM_AMDGPU:
+ return "ELF32-amdgpu";
default:
return "ELF32-unknown";
}
@@ -865,6 +882,12 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF64-mips";
case ELF::EM_WEBASSEMBLY:
return "ELF64-wasm";
+ case ELF::EM_AMDGPU:
+ return (EF.getHeader()->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA
+ && IsLittleEndian) ?
+ "ELF64-amdgpu-hsacobj" : "ELF64-amdgpu";
+ case ELF::EM_BPF:
+ return "ELF64-BPF";
default:
return "ELF64-unknown";
}
@@ -891,6 +914,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
return Triple::avr;
case ELF::EM_HEXAGON:
return Triple::hexagon;
+ case ELF::EM_LANAI:
+ return Triple::lanai;
case ELF::EM_MIPS:
switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
@@ -919,6 +944,15 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
default: return Triple::UnknownArch;
}
+ case ELF::EM_AMDGPU:
+ return (EF.getHeader()->e_ident[ELF::EI_CLASS] == ELF::ELFCLASS64
+ && EF.getHeader()->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA
+ && IsLittleEndian) ?
+ Triple::amdgcn : Triple::UnknownArch;
+
+ case ELF::EM_BPF:
+ return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
+
default:
return Triple::UnknownArch;
}
@@ -934,7 +968,7 @@ template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
return EF.getHeader()->e_type == ELF::ET_REL;
}
-}
-}
+} // end namespace object
+} // end namespace llvm
-#endif
+#endif // LLVM_OBJECT_ELFOBJECTFILE_H
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index 07b312a7d77c1..55028f360dbf3 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -21,9 +21,60 @@ namespace object {
using support::endianness;
-template <endianness target_endianness, bool is64Bits> struct ELFType {
- static const endianness TargetEndianness = target_endianness;
- static const bool Is64Bits = is64Bits;
+template <class ELFT> struct Elf_Ehdr_Impl;
+template <class ELFT> struct Elf_Shdr_Impl;
+template <class ELFT> struct Elf_Sym_Impl;
+template <class ELFT> struct Elf_Dyn_Impl;
+template <class ELFT> struct Elf_Phdr_Impl;
+template <class ELFT, bool isRela> struct Elf_Rel_Impl;
+template <class ELFT> struct Elf_Verdef_Impl;
+template <class ELFT> struct Elf_Verdaux_Impl;
+template <class ELFT> struct Elf_Verneed_Impl;
+template <class ELFT> struct Elf_Vernaux_Impl;
+template <class ELFT> struct Elf_Versym_Impl;
+template <class ELFT> struct Elf_Hash_Impl;
+template <class ELFT> struct Elf_GnuHash_Impl;
+template <class ELFT> struct Elf_Chdr_Impl;
+
+template <endianness E, bool Is64> struct ELFType {
+private:
+ template <typename Ty>
+ using packed = support::detail::packed_endian_specific_integral<Ty, E, 2>;
+
+public:
+ static const endianness TargetEndianness = E;
+ static const bool Is64Bits = Is64;
+
+ typedef typename std::conditional<Is64, uint64_t, uint32_t>::type uint;
+ typedef Elf_Ehdr_Impl<ELFType<E, Is64>> Ehdr;
+ typedef Elf_Shdr_Impl<ELFType<E, Is64>> Shdr;
+ typedef Elf_Sym_Impl<ELFType<E, Is64>> Sym;
+ typedef Elf_Dyn_Impl<ELFType<E, Is64>> Dyn;
+ typedef Elf_Phdr_Impl<ELFType<E, Is64>> Phdr;
+ typedef Elf_Rel_Impl<ELFType<E, Is64>, false> Rel;
+ typedef Elf_Rel_Impl<ELFType<E, Is64>, true> Rela;
+ typedef Elf_Verdef_Impl<ELFType<E, Is64>> Verdef;
+ typedef Elf_Verdaux_Impl<ELFType<E, Is64>> Verdaux;
+ typedef Elf_Verneed_Impl<ELFType<E, Is64>> Verneed;
+ typedef Elf_Vernaux_Impl<ELFType<E, Is64>> Vernaux;
+ typedef Elf_Versym_Impl<ELFType<E, Is64>> Versym;
+ typedef Elf_Hash_Impl<ELFType<E, Is64>> Hash;
+ typedef Elf_GnuHash_Impl<ELFType<E, Is64>> GnuHash;
+ typedef Elf_Chdr_Impl<ELFType<E, Is64>> Chdr;
+ typedef ArrayRef<Dyn> DynRange;
+ typedef ArrayRef<Shdr> ShdrRange;
+ typedef ArrayRef<Sym> SymRange;
+ typedef ArrayRef<Rel> RelRange;
+ typedef ArrayRef<Rela> RelaRange;
+ typedef ArrayRef<Phdr> PhdrRange;
+
+ typedef packed<uint16_t> Half;
+ typedef packed<uint32_t> Word;
+ typedef packed<int32_t> Sword;
+ typedef packed<uint64_t> Xword;
+ typedef packed<int64_t> Sxword;
+ typedef packed<uint> Addr;
+ typedef packed<uint> Off;
};
typedef ELFType<support::little, false> ELF32LE;
@@ -208,14 +259,14 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
return getBinding() != ELF::STB_LOCAL;
}
- ErrorOr<StringRef> getName(StringRef StrTab) const;
+ Expected<StringRef> getName(StringRef StrTab) const;
};
template <class ELFT>
-ErrorOr<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
+Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
uint32_t Offset = this->st_name;
if (Offset >= StrTab.size())
- return object_error::parse_failed;
+ return errorCodeToError(object_error::parse_failed);
return StringRef(StrTab.data() + Offset);
}
@@ -320,12 +371,10 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
uintX_t getPtr() const { return d_un.d_ptr; }
};
-// Elf_Rel: Elf Relocation
-template <class ELFT, bool isRela> struct Elf_Rel_Impl;
-
template <endianness TargetEndianness>
struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ static const bool IsRela = false;
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
@@ -361,12 +410,14 @@ template <endianness TargetEndianness>
struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
: public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ static const bool IsRela = true;
Elf_Sword r_addend; // Compute value for relocatable field by adding this
};
template <endianness TargetEndianness>
struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ static const bool IsRela = false;
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
@@ -411,6 +462,7 @@ template <endianness TargetEndianness>
struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
: public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ static const bool IsRela = true;
Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
};
@@ -508,6 +560,25 @@ struct Elf_GnuHash_Impl {
}
};
+// Compressed section headers.
+// http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
+template <endianness TargetEndianness>
+struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word ch_type;
+ Elf_Word ch_size;
+ Elf_Word ch_addralign;
+};
+
+template <endianness TargetEndianness>
+struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word ch_type;
+ Elf_Word ch_reserved;
+ Elf_Xword ch_size;
+ Elf_Xword ch_addralign;
+};
+
// MIPS .reginfo section
template <class ELFT>
struct Elf_Mips_RegInfo;
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
deleted file mode 100644
index df0aa500c8a29..0000000000000
--- a/include/llvm/Object/ELFYAML.h
+++ /dev/null
@@ -1,319 +0,0 @@
-//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file declares classes for handling the YAML representation
-/// of ELF.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_ELFYAML_H
-#define LLVM_OBJECT_ELFYAML_H
-
-#include "llvm/MC/YAML.h"
-#include "llvm/Support/ELF.h"
-
-namespace llvm {
-namespace ELFYAML {
-
-// 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,
-// and are appropriately converted to the necessary endianness when
-// reading/generating binary object files.
-// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
-// the common prefix of the respective constants. E.g. ELF_EM corresponds
-// to the `e_machine` constants, like `EM_X86_64`.
-// In the future, these would probably be better suited by C++11 enum
-// class's with appropriate fixed underlying type.
-LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
-// Just use 64, since it can hold 32-bit values too.
-LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
-// Just use 64, since it can hold 32-bit values too.
-LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
-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)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
-
-// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
-// since 64-bit can hold 32-bit values too.
-struct FileHeader {
- ELF_ELFCLASS Class;
- ELF_ELFDATA Data;
- ELF_ELFOSABI OSABI;
- ELF_ET Type;
- ELF_EM Machine;
- ELF_EF Flags;
- llvm::yaml::Hex64 Entry;
-};
-struct Symbol {
- StringRef Name;
- ELF_STT Type;
- StringRef Section;
- llvm::yaml::Hex64 Value;
- llvm::yaml::Hex64 Size;
- uint8_t Other;
-};
-struct LocalGlobalWeakSymbols {
- std::vector<Symbol> Local;
- std::vector<Symbol> Global;
- std::vector<Symbol> Weak;
-};
-
-struct SectionOrType {
- StringRef sectionNameOrType;
-};
-
-struct Section {
- enum class SectionKind {
- Group,
- RawContent,
- Relocation,
- NoBits,
- MipsABIFlags
- };
- SectionKind Kind;
- StringRef Name;
- ELF_SHT Type;
- ELF_SHF Flags;
- llvm::yaml::Hex64 Address;
- StringRef Link;
- StringRef Info;
- llvm::yaml::Hex64 AddressAlign;
- Section(SectionKind Kind) : Kind(Kind) {}
- virtual ~Section();
-};
-struct RawContentSection : Section {
- yaml::BinaryRef Content;
- llvm::yaml::Hex64 Size;
- RawContentSection() : Section(SectionKind::RawContent) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::RawContent;
- }
-};
-
-struct NoBitsSection : Section {
- llvm::yaml::Hex64 Size;
- NoBitsSection() : Section(SectionKind::NoBits) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::NoBits;
- }
-};
-
-struct Group : Section {
- // Members of a group contain a flag and a list of section indices
- // that are part of the group.
- std::vector<SectionOrType> Members;
- Group() : Section(SectionKind::Group) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::Group;
- }
-};
-
-struct Relocation {
- llvm::yaml::Hex64 Offset;
- int64_t Addend;
- ELF_REL Type;
- StringRef Symbol;
-};
-struct RelocationSection : Section {
- std::vector<Relocation> Relocations;
- RelocationSection() : Section(SectionKind::Relocation) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::Relocation;
- }
-};
-
-// Represents .MIPS.abiflags section
-struct MipsABIFlags : Section {
- llvm::yaml::Hex16 Version;
- MIPS_ISA ISALevel;
- llvm::yaml::Hex8 ISARevision;
- MIPS_AFL_REG GPRSize;
- MIPS_AFL_REG CPR1Size;
- MIPS_AFL_REG CPR2Size;
- MIPS_ABI_FP FpABI;
- MIPS_AFL_EXT ISAExtension;
- MIPS_AFL_ASE ASEs;
- MIPS_AFL_FLAGS1 Flags1;
- llvm::yaml::Hex32 Flags2;
- MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
- static bool classof(const Section *S) {
- return S->Kind == SectionKind::MipsABIFlags;
- }
-};
-
-struct Object {
- FileHeader Header;
- std::vector<std::unique_ptr<Section>> Sections;
- // 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.
- LocalGlobalWeakSymbols Symbols;
-};
-
-} // end namespace ELFYAML
-} // end namespace llvm
-
-LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
-
-namespace llvm {
-namespace yaml {
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
- static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
- static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
- static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
- static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
- static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
- static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
- static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
- static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
- static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
-};
-
-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);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
- static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
- static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
- static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
- static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
-};
-
-template <>
-struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
- static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
- static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
-};
-
-template <>
-struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
- static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
-};
-
-template <>
-struct MappingTraits<ELFYAML::FileHeader> {
- static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
-};
-
-template <>
-struct MappingTraits<ELFYAML::Symbol> {
- static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
-};
-
-template <>
-struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
- static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
-};
-
-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::Object> {
- static void mapping(IO &IO, ELFYAML::Object &Object);
-};
-
-template <> struct MappingTraits<ELFYAML::SectionOrType> {
- static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
-};
-
-} // end namespace yaml
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
index 0f79a6ed0dd81..cd55e5dc26d7b 100644
--- a/include/llvm/Object/Error.h
+++ b/include/llvm/Object/Error.h
@@ -14,11 +14,15 @@
#ifndef LLVM_OBJECT_ERROR_H
#define LLVM_OBJECT_ERROR_H
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Error.h"
#include <system_error>
namespace llvm {
namespace object {
+class Binary;
+
const std::error_category &object_category();
enum class object_error {
@@ -30,16 +34,51 @@ enum class object_error {
string_table_non_null_end,
invalid_section_index,
bitcode_section_not_found,
- elf_invalid_dynamic_table_size,
- macho_small_load_command,
- macho_load_segment_too_many_sections,
- macho_load_segment_too_small,
};
inline std::error_code make_error_code(object_error e) {
return std::error_code(static_cast<int>(e), object_category());
}
+/// Base class for all errors indicating malformed binary files.
+///
+/// Having a subclass for all malformed binary files allows archive-walking
+/// code to skip malformed files without having to understand every possible
+/// way that a binary file might be malformed.
+///
+/// Currently inherits from ECError for easy interoperability with
+/// std::error_code, but this will be removed in the future.
+class BinaryError : public ErrorInfo<BinaryError, ECError> {
+public:
+ static char ID;
+ BinaryError() {
+ // Default to parse_failed, can be overridden with setErrorCode.
+ setErrorCode(make_error_code(object_error::parse_failed));
+ }
+};
+
+/// Generic binary error.
+///
+/// For errors that don't require their own specific sub-error (most errors)
+/// this class can be used to describe the error via a string message.
+class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
+public:
+ static char ID;
+ GenericBinaryError(Twine Msg);
+ GenericBinaryError(Twine Msg, object_error ECOverride);
+ const std::string &getMessage() const { return Msg; }
+ void log(raw_ostream &OS) const override;
+private:
+ std::string Msg;
+};
+
+/// isNotObjectErrorInvalidFileType() is used when looping through the children
+/// of an archive after calling getAsBinary() on the child and it returns an
+/// llvm::Error. In the cases we want to loop through the children and ignore the
+/// non-objects in the archive this is used to test the error to see if an
+/// error() function needs to called on the llvm::Error.
+Error isNotObjectErrorInvalidFileType(llvm::Error Err);
+
} // end namespace object.
} // end namespace llvm.
diff --git a/include/llvm/Object/FunctionIndexObjectFile.h b/include/llvm/Object/FunctionIndexObjectFile.h
deleted file mode 100644
index 74b461dc7cc72..0000000000000
--- a/include/llvm/Object/FunctionIndexObjectFile.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===- FunctionIndexObjectFile.h - Function index file implementation -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the FunctionIndexObjectFile template class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_FUNCTIONINDEXOBJECTFILE_H
-#define LLVM_OBJECT_FUNCTIONINDEXOBJECTFILE_H
-
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/Object/SymbolicFile.h"
-
-namespace llvm {
-class FunctionInfoIndex;
-class Module;
-
-namespace object {
-class ObjectFile;
-
-/// This class is used to read just the function summary index related
-/// sections out of the given object (which may contain a single module's
-/// bitcode or be a combined index bitcode file). It builds a FunctionInfoIndex
-/// object.
-class FunctionIndexObjectFile : public SymbolicFile {
- std::unique_ptr<FunctionInfoIndex> Index;
-
-public:
- FunctionIndexObjectFile(MemoryBufferRef Object,
- std::unique_ptr<FunctionInfoIndex> I);
- ~FunctionIndexObjectFile() override;
-
- // TODO: Walk through FunctionMap entries for function symbols.
- // However, currently these interfaces are not used by any consumers.
- void moveSymbolNext(DataRefImpl &Symb) const override {
- llvm_unreachable("not implemented");
- }
- std::error_code printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const override {
- llvm_unreachable("not implemented");
- return std::error_code();
- }
- uint32_t getSymbolFlags(DataRefImpl Symb) const override {
- llvm_unreachable("not implemented");
- return 0;
- }
- basic_symbol_iterator symbol_begin_impl() const override {
- llvm_unreachable("not implemented");
- return basic_symbol_iterator(BasicSymbolRef());
- }
- basic_symbol_iterator symbol_end_impl() const override {
- llvm_unreachable("not implemented");
- return basic_symbol_iterator(BasicSymbolRef());
- }
-
- const FunctionInfoIndex &getIndex() const {
- return const_cast<FunctionIndexObjectFile *>(this)->getIndex();
- }
- FunctionInfoIndex &getIndex() { return *Index; }
- std::unique_ptr<FunctionInfoIndex> takeIndex();
-
- static inline bool classof(const Binary *v) { return v->isFunctionIndex(); }
-
- /// \brief Finds and returns bitcode embedded in the given object file, or an
- /// error code if not found.
- static ErrorOr<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
-
- /// \brief Finds and returns bitcode in the given memory buffer (which may
- /// be either a bitcode file or a native object file with embedded bitcode),
- /// or an error code if not found.
- static ErrorOr<MemoryBufferRef>
- findBitcodeInMemBuffer(MemoryBufferRef Object);
-
- /// \brief Looks for function summary in the given memory buffer,
- /// returns true if found, else false.
- static bool
- hasFunctionSummaryInMemBuffer(MemoryBufferRef Object,
- DiagnosticHandlerFunction DiagnosticHandler);
-
- /// \brief Parse function index in the given memory buffer.
- /// Return new FunctionIndexObjectFile instance containing parsed function
- /// summary/index.
- static ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
- create(MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
- bool IsLazy = false);
-
- /// \brief Parse the function summary information for function with the
- /// given name out of the given buffer. Parsed information is
- /// stored on the index object saved in this object.
- std::error_code
- findFunctionSummaryInMemBuffer(MemoryBufferRef Object,
- DiagnosticHandlerFunction DiagnosticHandler,
- StringRef FunctionName);
-};
-}
-
-/// Parse the function index out of an IR file and return the function
-/// index object if found, or nullptr if not.
-ErrorOr<std::unique_ptr<FunctionInfoIndex>>
-getFunctionIndexForFile(StringRef Path,
- DiagnosticHandlerFunction DiagnosticHandler);
-}
-
-#endif
diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h
index ef655287c34c6..9fe011e17d627 100644
--- a/include/llvm/Object/IRObjectFile.h
+++ b/include/llvm/Object/IRObjectFile.h
@@ -20,6 +20,7 @@ namespace llvm {
class Mangler;
class Module;
class GlobalValue;
+class Triple;
namespace object {
class ObjectFile;
@@ -59,6 +60,15 @@ public:
/// error code if not found.
static ErrorOr<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
+ /// Parse inline ASM and collect the symbols that are not defined in
+ /// the current module.
+ ///
+ /// For each found symbol, call \p AsmUndefinedRefs with the name of the
+ /// symbol found and the associated flags.
+ static void CollectAsmUndefinedRefs(
+ const Triple &TheTriple, StringRef InlineAsm,
+ function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs);
+
/// \brief Finds and returns bitcode in the given memory buffer (which may
/// be either a bitcode file or a native object file with embedded bitcode),
/// or an error code if not found.
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index e02ce3b214168..7906db1e8a77d 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -193,24 +193,24 @@ public:
typedef SmallVector<LoadCommandInfo, 4> LoadCommandList;
typedef LoadCommandList::const_iterator load_command_iterator;
- MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
- std::error_code &EC);
+ static Expected<std::unique_ptr<MachOObjectFile>>
+ create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits);
void moveSymbolNext(DataRefImpl &Symb) const override;
uint64_t getNValue(DataRefImpl Sym) const;
- ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
// MachO specific.
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
unsigned getSectionType(SectionRef Sec) const;
- ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- ErrorOr<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
unsigned getSymbolSectionID(SymbolRef Symb) const;
unsigned getSectionID(SectionRef Sec) const;
@@ -222,10 +222,12 @@ public:
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) 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;
+ bool isSectionBitcode(DataRefImpl Sec) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
@@ -251,6 +253,7 @@ public:
// MachO specific.
basic_symbol_iterator getSymbolByIndex(unsigned Index) const;
+ uint64_t getSymbolIndex(DataRefImpl Symb) const;
section_iterator section_begin() const override;
section_iterator section_end() const override;
@@ -259,7 +262,8 @@ public:
StringRef getFileFormatName() const override;
unsigned getArch() const override;
- Triple getArch(const char **McpuDefault, Triple *ThumbTriple) const;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
+ Triple getArchTriple(const char **McpuDefault = nullptr) const;
relocation_iterator section_rel_begin(unsigned Index) const;
relocation_iterator section_rel_end(unsigned Index) const;
@@ -405,12 +409,8 @@ public:
StringRef &Suffix);
static Triple::ArchType getArch(uint32_t CPUType);
- static Triple getArch(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault = nullptr);
- static Triple getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault = nullptr);
- static Triple getArch(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault, Triple *ThumbTriple);
+ static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
+ const char **McpuDefault = nullptr);
static bool isValidArch(StringRef ArchFlag);
static Triple getHostArch();
@@ -441,6 +441,10 @@ public:
}
private:
+
+ MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
+ Error &Err);
+
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
union {
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
index a11d381a700a2..7eb2af944f3dc 100644
--- a/include/llvm/Object/MachOUniversal.h
+++ b/include/llvm/Object/MachOUniversal.h
@@ -14,21 +14,22 @@
#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
#define LLVM_OBJECT_MACHOUNIVERSAL_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachO.h"
-#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
namespace llvm {
+class StringRef;
+
namespace object {
class MachOUniversalBinary : public Binary {
virtual void anchor();
+ uint32_t Magic;
uint32_t NumberOfObjects;
public:
class ObjectForArch {
@@ -37,6 +38,7 @@ public:
uint32_t Index;
/// \brief Descriptor of the object.
MachO::fat_arch Header;
+ MachO::fat_arch_64 Header64;
public:
ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
@@ -51,19 +53,58 @@ public:
}
ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
- uint32_t getCPUType() const { return Header.cputype; }
- uint32_t getCPUSubType() const { return Header.cpusubtype; }
- uint32_t getOffset() const { return Header.offset; }
- uint32_t getSize() const { return Header.size; }
- uint32_t getAlign() const { return Header.align; }
+ uint32_t getCPUType() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.cputype;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.cputype;
+ }
+ uint32_t getCPUSubType() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.cpusubtype;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.cpusubtype;
+ }
+ uint32_t getOffset() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.offset;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.offset;
+ }
+ uint32_t getSize() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.size;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.size;
+ }
+ uint32_t getAlign() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.align;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.align;
+ }
+ uint32_t getReserved() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return 0;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.reserved;
+ }
std::string getArchTypeName() const {
- Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype);
- return T.getArchName();
+ if (Parent->getMagic() == MachO::FAT_MAGIC) {
+ Triple T =
+ MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype);
+ return T.getArchName();
+ } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
+ Triple T =
+ MachOObjectFile::getArchTriple(Header64.cputype,
+ Header64.cpusubtype);
+ return T.getArchName();
+ }
}
- ErrorOr<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
+ Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
- ErrorOr<std::unique_ptr<Archive>> getAsArchive() const;
+ Expected<std::unique_ptr<Archive>> getAsArchive() const;
};
class object_iterator {
@@ -86,8 +127,8 @@ public:
}
};
- MachOUniversalBinary(MemoryBufferRef Souce, std::error_code &EC);
- static ErrorOr<std::unique_ptr<MachOUniversalBinary>>
+ MachOUniversalBinary(MemoryBufferRef Souce, Error &Err);
+ static Expected<std::unique_ptr<MachOUniversalBinary>>
create(MemoryBufferRef Source);
object_iterator begin_objects() const {
@@ -101,6 +142,7 @@ public:
return make_range(begin_objects(), end_objects());
}
+ uint32_t getMagic() const { return Magic; }
uint32_t getNumberOfObjects() const { return NumberOfObjects; }
// Cast methods.
@@ -108,7 +150,7 @@ public:
return V->isMachOUniversalBinary();
}
- ErrorOr<std::unique_ptr<MachOObjectFile>>
+ Expected<std::unique_ptr<MachOObjectFile>>
getObjectForArch(StringRef ArchName) const;
};
diff --git a/include/llvm/Object/ModuleSummaryIndexObjectFile.h b/include/llvm/Object/ModuleSummaryIndexObjectFile.h
new file mode 100644
index 0000000000000..d021fb29427f0
--- /dev/null
+++ b/include/llvm/Object/ModuleSummaryIndexObjectFile.h
@@ -0,0 +1,103 @@
+//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ModuleSummaryIndexObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
+#define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
+
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/Object/SymbolicFile.h"
+
+namespace llvm {
+class ModuleSummaryIndex;
+class Module;
+
+namespace object {
+class ObjectFile;
+
+/// This class is used to read just the module summary index related
+/// sections out of the given object (which may contain a single module's
+/// bitcode or be a combined index bitcode file). It builds a ModuleSummaryIndex
+/// object.
+class ModuleSummaryIndexObjectFile : public SymbolicFile {
+ std::unique_ptr<ModuleSummaryIndex> Index;
+
+public:
+ ModuleSummaryIndexObjectFile(MemoryBufferRef Object,
+ std::unique_ptr<ModuleSummaryIndex> I);
+ ~ModuleSummaryIndexObjectFile() override;
+
+ // TODO: Walk through GlobalValueMap entries for symbols.
+ // However, currently these interfaces are not used by any consumers.
+ void moveSymbolNext(DataRefImpl &Symb) const override {
+ llvm_unreachable("not implemented");
+ }
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override {
+ llvm_unreachable("not implemented");
+ return std::error_code();
+ }
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override {
+ llvm_unreachable("not implemented");
+ return 0;
+ }
+ basic_symbol_iterator symbol_begin_impl() const override {
+ llvm_unreachable("not implemented");
+ return basic_symbol_iterator(BasicSymbolRef());
+ }
+ basic_symbol_iterator symbol_end_impl() const override {
+ llvm_unreachable("not implemented");
+ return basic_symbol_iterator(BasicSymbolRef());
+ }
+
+ const ModuleSummaryIndex &getIndex() const {
+ return const_cast<ModuleSummaryIndexObjectFile *>(this)->getIndex();
+ }
+ ModuleSummaryIndex &getIndex() { return *Index; }
+ std::unique_ptr<ModuleSummaryIndex> takeIndex();
+
+ static inline bool classof(const Binary *v) {
+ return v->isModuleSummaryIndex();
+ }
+
+ /// \brief Finds and returns bitcode embedded in the given object file, or an
+ /// error code if not found.
+ static ErrorOr<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
+
+ /// \brief Finds and returns bitcode in the given memory buffer (which may
+ /// be either a bitcode file or a native object file with embedded bitcode),
+ /// or an error code if not found.
+ static ErrorOr<MemoryBufferRef>
+ findBitcodeInMemBuffer(MemoryBufferRef Object);
+
+ /// \brief Looks for summary sections in the given memory buffer,
+ /// returns true if found, else false.
+ static bool hasGlobalValueSummaryInMemBuffer(
+ MemoryBufferRef Object,
+ const DiagnosticHandlerFunction &DiagnosticHandler);
+
+ /// \brief Parse module summary index in the given memory buffer.
+ /// Return new ModuleSummaryIndexObjectFile instance containing parsed module
+ /// summary/index.
+ static ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
+ create(MemoryBufferRef Object,
+ const DiagnosticHandlerFunction &DiagnosticHandler);
+};
+}
+
+/// Parse the module summary index out of an IR file and return the module
+/// summary index object if found, or nullptr if not.
+ErrorOr<std::unique_ptr<ModuleSummaryIndex>> getModuleSummaryIndexForFile(
+ StringRef Path, const DiagnosticHandlerFunction &DiagnosticHandler);
+}
+
+#endif
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index ce0c891ee0c22..6272a5f056eb8 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -15,13 +15,13 @@
#define LLVM_OBJECT_OBJECTFILE_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cstring>
-#include <vector>
namespace llvm {
namespace object {
@@ -90,10 +90,12 @@ public:
/// @brief Get the alignment of this section as the actual value (not log 2).
uint64_t getAlignment() const;
+ bool isCompressed() const;
bool isText() const;
bool isData() const;
bool isBSS() const;
bool isVirtual() const;
+ bool isBitcode() const;
bool containsSymbol(SymbolRef S) const;
@@ -130,10 +132,10 @@ public:
assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
}
- ErrorOr<StringRef> getName() const;
+ Expected<StringRef> getName() const;
/// Returns the symbol virtual address (i.e. address at which it will be
/// mapped).
- ErrorOr<uint64_t> getAddress() const;
+ Expected<uint64_t> getAddress() const;
/// Return the value of the symbol depending on the object this can be an
/// offset or a virtual address.
@@ -142,11 +144,11 @@ public:
/// @brief Get the alignment of this symbol as the actual value (not log 2).
uint32_t getAlignment() const;
uint64_t getCommonSize() const;
- SymbolRef::Type getType() const;
+ Expected<SymbolRef::Type> getType() const;
/// @brief Get section this symbol is defined in reference to. Result is
/// end_sections() if it is undefined or is an absolute symbol.
- ErrorOr<section_iterator> getSection() const;
+ Expected<section_iterator> getSection() const;
const ObjectFile *getObject() const;
};
@@ -193,15 +195,15 @@ protected:
// Implementations assume that the DataRefImpl is valid and has not been
// modified externally. It's UB otherwise.
friend class SymbolRef;
- virtual ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
+ virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
- virtual ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
+ virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
- virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0;
- virtual ErrorOr<section_iterator>
+ virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
+ virtual Expected<section_iterator>
getSymbolSection(DataRefImpl Symb) const = 0;
// Same as above for SectionRef.
@@ -214,11 +216,13 @@ protected:
virtual std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const = 0;
virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
+ virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
virtual bool isSectionText(DataRefImpl Sec) const = 0;
virtual bool isSectionData(DataRefImpl Sec) const = 0;
virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
// A section is 'virtual' if its contents aren't present in the object image.
virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
+ virtual bool isSectionBitcode(DataRefImpl Sec) const;
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
@@ -259,6 +263,7 @@ public:
virtual StringRef getFileFormatName() const = 0;
virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+ virtual SubtargetFeatures getFeatures() const = 0;
/// Returns platform-specific object flags, if any.
virtual std::error_code getPlatformFlags(unsigned &Result) const {
@@ -273,12 +278,12 @@ public:
/// @param ObjectPath The path to the object file. ObjectPath.isObject must
/// return true.
/// @brief Create ObjectFile from path.
- static ErrorOr<OwningBinary<ObjectFile>>
+ static Expected<OwningBinary<ObjectFile>>
createObjectFile(StringRef ObjectPath);
- static ErrorOr<std::unique_ptr<ObjectFile>>
+ static Expected<std::unique_ptr<ObjectFile>>
createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type);
- static ErrorOr<std::unique_ptr<ObjectFile>>
+ static Expected<std::unique_ptr<ObjectFile>>
createObjectFile(MemoryBufferRef Object) {
return createObjectFile(Object, sys::fs::file_magic::unknown);
}
@@ -294,19 +299,20 @@ public:
static ErrorOr<std::unique_ptr<ObjectFile>>
createELFObjectFile(MemoryBufferRef Object);
- static ErrorOr<std::unique_ptr<MachOObjectFile>>
+ static Expected<std::unique_ptr<MachOObjectFile>>
createMachOObjectFile(MemoryBufferRef Object);
+
};
// Inline function definitions.
inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
: BasicSymbolRef(SymbolP, Owner) {}
-inline ErrorOr<StringRef> SymbolRef::getName() const {
+inline Expected<StringRef> SymbolRef::getName() const {
return getObject()->getSymbolName(getRawDataRefImpl());
}
-inline ErrorOr<uint64_t> SymbolRef::getAddress() const {
+inline Expected<uint64_t> SymbolRef::getAddress() const {
return getObject()->getSymbolAddress(getRawDataRefImpl());
}
@@ -322,11 +328,11 @@ inline uint64_t SymbolRef::getCommonSize() const {
return getObject()->getCommonSymbolSize(getRawDataRefImpl());
}
-inline ErrorOr<section_iterator> SymbolRef::getSection() const {
+inline Expected<section_iterator> SymbolRef::getSection() const {
return getObject()->getSymbolSection(getRawDataRefImpl());
}
-inline SymbolRef::Type SymbolRef::getType() const {
+inline Expected<SymbolRef::Type> SymbolRef::getType() const {
return getObject()->getSymbolType(getRawDataRefImpl());
}
@@ -378,6 +384,10 @@ inline uint64_t SectionRef::getAlignment() const {
return OwningObject->getSectionAlignment(SectionPimpl);
}
+inline bool SectionRef::isCompressed() const {
+ return OwningObject->isSectionCompressed(SectionPimpl);
+}
+
inline bool SectionRef::isText() const {
return OwningObject->isSectionText(SectionPimpl);
}
@@ -394,6 +404,10 @@ inline bool SectionRef::isVirtual() const {
return OwningObject->isSectionVirtual(SectionPimpl);
}
+inline bool SectionRef::isBitcode() const {
+ return OwningObject->isSectionBitcode(SectionPimpl);
+}
+
inline relocation_iterator SectionRef::relocation_begin() const {
return OwningObject->section_rel_begin(SectionPimpl);
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index d5e4258cb0a76..5e0df98d86279 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -16,7 +16,6 @@
#ifndef LLVM_OBJECT_RELOCVISITOR_H
#define LLVM_OBJECT_RELOCVISITOR_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
@@ -175,6 +174,14 @@ private:
case llvm::ELF::R_ARM_ABS32:
return visitELF_ARM_ABS32(R, Value);
}
+ case Triple::lanai:
+ switch (RelocType) {
+ case llvm::ELF::R_LANAI_32:
+ return visitELF_Lanai_32(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
case Triple::mipsel:
case Triple::mips:
switch (RelocType) {
@@ -311,6 +318,13 @@ private:
return RelocToApply(Res, 4);
}
+ /// Lanai ELF
+ RelocToApply visitELF_Lanai_32(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getELFAddend(R);
+ uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+ return RelocToApply(Res, 4);
+ }
+
/// MIPS ELF
RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
uint32_t Res = Value & 0xFFFFFFFF;
diff --git a/include/llvm/Object/StackMapParser.h b/include/llvm/Object/StackMapParser.h
index 276eab6c294e5..e58162de1501e 100644
--- a/include/llvm/Object/StackMapParser.h
+++ b/include/llvm/Object/StackMapParser.h
@@ -10,9 +10,8 @@
#ifndef LLVM_CODEGEN_STACKMAPPARSER_H
#define LLVM_CODEGEN_STACKMAPPARSER_H
-#include "llvm/Support/Debug.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Endian.h"
-#include <map>
#include <vector>
namespace llvm {
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
index 0c5b38111a9c0..894c2670f265c 100644
--- a/include/llvm/Object/SymbolicFile.h
+++ b/include/llvm/Object/SymbolicFile.h
@@ -16,6 +16,7 @@
#include "llvm/Object/Binary.h"
#include "llvm/Support/Format.h"
+#include <utility>
namespace llvm {
namespace object {
@@ -58,7 +59,7 @@ class content_iterator
content_type Current;
public:
- content_iterator(content_type symb) : Current(symb) {}
+ content_iterator(content_type symb) : Current(std::move(symb)) {}
const content_type *operator->() const { return &Current; }
@@ -153,15 +154,15 @@ public:
}
// construction aux.
- static ErrorOr<std::unique_ptr<SymbolicFile>>
+ static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type,
LLVMContext *Context);
- static ErrorOr<std::unique_ptr<SymbolicFile>>
+ static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object) {
return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
}
- static ErrorOr<OwningBinary<SymbolicFile>>
+ static Expected<OwningBinary<SymbolicFile>>
createSymbolicFile(StringRef ObjectPath);
static inline bool classof(const Binary *v) {