aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Object
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Object')
-rw-r--r--include/llvm/Object/Archive.h27
-rw-r--r--include/llvm/Object/Binary.h30
-rw-r--r--include/llvm/Object/COFF.h392
-rw-r--r--include/llvm/Object/COFFYAML.h60
-rw-r--r--include/llvm/Object/ELF.h160
-rw-r--r--include/llvm/Object/ELFObjectFile.h494
-rw-r--r--include/llvm/Object/ELFYAML.h64
-rw-r--r--include/llvm/Object/Error.h36
-rw-r--r--include/llvm/Object/IRObjectFile.h59
-rw-r--r--include/llvm/Object/MachO.h181
-rw-r--r--include/llvm/Object/MachOUniversal.h25
-rw-r--r--include/llvm/Object/ObjectFile.h470
-rw-r--r--include/llvm/Object/RelocVisitor.h76
-rw-r--r--include/llvm/Object/SymbolicFile.h195
-rw-r--r--include/llvm/Object/YAML.h116
15 files changed, 1441 insertions, 944 deletions
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 1cba51954eca..af6c995c1d05 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Binary.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -71,7 +72,7 @@ public:
Child getNext() const;
- error_code getName(StringRef &Result) const;
+ ErrorOr<StringRef> getName() const;
StringRef getRawName() const { return getHeader()->getName(); }
sys::TimeValue getLastModified() const {
return getHeader()->getLastModified();
@@ -88,16 +89,17 @@ public:
return StringRef(Data.data() + StartOfFile, getSize());
}
- error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
- bool FullPath = false) const;
+ ErrorOr<std::unique_ptr<MemoryBuffer>>
+ getMemoryBuffer(bool FullPath = false) const;
- error_code getAsBinary(OwningPtr<Binary> &Result) const;
+ ErrorOr<std::unique_ptr<Binary>>
+ getAsBinary(LLVMContext *Context = nullptr) const;
};
class child_iterator {
Child child;
public:
- child_iterator() : child(Child(0, 0)) {}
+ child_iterator() : child(Child(nullptr, nullptr)) {}
child_iterator(const Child &c) : child(c) {}
const Child* operator->() const {
return &child;
@@ -135,8 +137,8 @@ public:
: Parent(p)
, SymbolIndex(symi)
, StringIndex(stri) {}
- error_code getName(StringRef &Result) const;
- error_code getMember(child_iterator &Result) const;
+ StringRef getName() const;
+ ErrorOr<child_iterator> getMember() const;
Symbol getNext() const;
};
@@ -162,7 +164,8 @@ public:
}
};
- Archive(MemoryBuffer *source, error_code &ec);
+ Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &EC);
+ static ErrorOr<Archive *> create(std::unique_ptr<MemoryBuffer> Source);
enum Kind {
K_GNU,
@@ -174,11 +177,11 @@ public:
return Format;
}
- child_iterator begin_children(bool SkipInternal = true) const;
- child_iterator end_children() const;
+ child_iterator child_begin(bool SkipInternal = true) const;
+ child_iterator child_end() const;
- symbol_iterator begin_symbols() const;
- symbol_iterator end_symbols() const;
+ symbol_iterator symbol_begin() const;
+ symbol_iterator symbol_end() const;
// Cast methods.
static inline bool classof(Binary const *v) {
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index a3f5625cc9b7..91984cb52715 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -14,11 +14,13 @@
#ifndef LLVM_OBJECT_BINARY_H
#define LLVM_OBJECT_BINARY_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Object/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
namespace llvm {
+class LLVMContext;
class MemoryBuffer;
class StringRef;
@@ -32,13 +34,15 @@ private:
unsigned int TypeID;
protected:
- MemoryBuffer *Data;
+ std::unique_ptr<MemoryBuffer> Data;
- Binary(unsigned int Type, MemoryBuffer *Source);
+ Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
enum {
ID_Archive,
ID_MachOUniversalBinary,
+ ID_IR, // LLVM IR
+
// Object and children.
ID_StartObjects,
ID_COFF,
@@ -74,6 +78,7 @@ public:
virtual ~Binary();
StringRef getData() const;
+ MemoryBuffer *releaseBuffer() { return Data.release(); }
StringRef getFileName() const;
// Cast methods.
@@ -84,6 +89,10 @@ public:
return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
}
+ bool isSymbolic() const {
+ return isIR() || isObject();
+ }
+
bool isArchive() const {
return TypeID == ID_Archive;
}
@@ -104,6 +113,10 @@ public:
return TypeID == ID_COFF;
}
+ bool isIR() const {
+ return TypeID == ID_IR;
+ }
+
bool isLittleEndian() const {
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
@@ -112,14 +125,11 @@ public:
/// @brief Create a Binary from Source, autodetecting the file type.
///
-/// @param Source The data to create the Binary from. Ownership is transferred
-/// to Result if successful. If an error is returned, Source is destroyed
-/// by createBinary before returning.
-/// @param Result A pointer to the resulting Binary if no error occured.
-error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result);
-
-error_code createBinary(StringRef Path, OwningPtr<Binary> &Result);
+/// @param Source The data to create the Binary from.
+ErrorOr<Binary *> createBinary(std::unique_ptr<MemoryBuffer> Source,
+ LLVMContext *Context = nullptr);
+ErrorOr<Binary *> createBinary(StringRef Path);
}
}
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index e05ae6c654c7..e2da070d47bd 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -19,12 +19,13 @@
#include "llvm/Support/Endian.h"
namespace llvm {
- template <typename T>
- class ArrayRef;
+template <typename T> class ArrayRef;
namespace object {
class ImportDirectoryEntryRef;
+class ExportDirectoryEntryRef;
typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator;
+typedef content_iterator<ExportDirectoryEntryRef> export_directory_iterator;
/// The DOS compatible header at the front of all PE/COFF executables.
struct dos_header {
@@ -64,8 +65,8 @@ struct coff_file_header {
/// The 32-bit PE header that follows the COFF header.
struct pe32_header {
support::ulittle16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
support::ulittle32_t SizeOfCode;
support::ulittle32_t SizeOfInitializedData;
support::ulittle32_t SizeOfUninitializedData;
@@ -98,8 +99,8 @@ struct pe32_header {
/// The 64-bit PE header that follows the COFF header.
struct pe32plus_header {
support::ulittle16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
support::ulittle32_t SizeOfCode;
support::ulittle32_t SizeOfInitializedData;
support::ulittle32_t SizeOfUninitializedData;
@@ -157,6 +158,28 @@ struct import_lookup_table_entry32 {
}
};
+struct export_directory_table_entry {
+ support::ulittle32_t ExportFlags;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t OrdinalBase;
+ support::ulittle32_t AddressTableEntries;
+ support::ulittle32_t NumberOfNamePointers;
+ support::ulittle32_t ExportAddressTableRVA;
+ support::ulittle32_t NamePointerRVA;
+ support::ulittle32_t OrdinalTableRVA;
+};
+
+union export_address_table_entry {
+ support::ulittle32_t ExportRVA;
+ support::ulittle32_t ForwarderRVA;
+};
+
+typedef support::ulittle32_t export_name_pointer_table_entry;
+typedef support::ulittle16_t export_ordinal_table_entry;
+
struct coff_symbol {
struct StringTableOffset {
support::ulittle32_t Zeroes;
@@ -169,19 +192,50 @@ struct coff_symbol {
} Name;
support::ulittle32_t Value;
- support::little16_t SectionNumber;
+ support::ulittle16_t SectionNumber;
support::ulittle16_t Type;
- support::ulittle8_t StorageClass;
- support::ulittle8_t NumberOfAuxSymbols;
+ support::ulittle8_t StorageClass;
+ support::ulittle8_t NumberOfAuxSymbols;
+
+ uint8_t getBaseType() const { return Type & 0x0F; }
+
+ uint8_t getComplexType() const { return (Type & 0xF0) >> 4; }
+
+ bool isFunctionDefinition() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+ getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
+ !COFF::isReservedSectionNumber(SectionNumber);
+ }
+
+ bool isFunctionLineInfo() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION;
+ }
+
+ bool isWeakExternal() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
+ (StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ SectionNumber == COFF::IMAGE_SYM_UNDEFINED && Value == 0);
+ }
+
+ bool isFileRecord() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_FILE;
+ }
- uint8_t getBaseType() const {
- return Type & 0x0F;
+ bool isSectionDefinition() const {
+ // C++/CLI creates external ABS symbols for non-const appdomain globals.
+ // These are also followed by an auxiliary section definition.
+ bool isAppdomainGlobal = StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ SectionNumber == COFF::IMAGE_SYM_ABSOLUTE;
+ bool isOrdinarySection =
+ StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Value == 0;
+ return isAppdomainGlobal || isOrdinarySection;
}
- uint8_t getComplexType() const {
- return (Type & 0xF0) >> 4;
+ bool isCLRToken() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
}
};
@@ -196,6 +250,13 @@ struct coff_section {
support::ulittle16_t NumberOfRelocations;
support::ulittle16_t NumberOfLinenumbers;
support::ulittle32_t Characteristics;
+
+ // Returns true if the actual number of relocations is stored in
+ // VirtualAddress field of the first relocation table entry.
+ bool hasExtendedRelocations() const {
+ return Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL &&
+ NumberOfRelocations == UINT16_MAX;
+ };
};
struct coff_relocation {
@@ -204,12 +265,32 @@ struct coff_relocation {
support::ulittle16_t Type;
};
+struct coff_aux_function_definition {
+ support::ulittle32_t TagIndex;
+ support::ulittle32_t TotalSize;
+ support::ulittle32_t PointerToLinenumber;
+ support::ulittle32_t PointerToNextFunction;
+ char Unused[2];
+};
+
+struct coff_aux_bf_and_ef_symbol {
+ char Unused1[4];
+ support::ulittle16_t Linenumber;
+ char Unused2[6];
+ support::ulittle32_t PointerToNextFunction;
+ char Unused3[2];
+};
+
struct coff_aux_weak_external {
support::ulittle32_t TagIndex;
support::ulittle32_t Characteristics;
char Unused[10];
};
+struct coff_aux_file {
+ char FileName[18];
+};
+
struct coff_aux_section_definition {
support::ulittle32_t Length;
support::ulittle16_t NumberOfRelocations;
@@ -220,149 +301,222 @@ struct coff_aux_section_definition {
char Unused[3];
};
+struct coff_aux_clr_token {
+ support::ulittle8_t AuxType;
+ support::ulittle8_t Reserved;
+ support::ulittle32_t SymbolTableIndex;
+ char Unused[12];
+};
+
+struct coff_load_configuration32 {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t GlobalFlagsClear;
+ support::ulittle32_t GlobalFlagsSet;
+ support::ulittle32_t CriticalSectionDefaultTimeout;
+ support::ulittle32_t DeCommitFreeBlockThreshold;
+ support::ulittle32_t DeCommitTotalFreeThreshold;
+ support::ulittle32_t LockPrefixTable;
+ support::ulittle32_t MaximumAllocationSize;
+ support::ulittle32_t VirtualMemoryThreshold;
+ support::ulittle32_t ProcessAffinityMask;
+ support::ulittle32_t ProcessHeapFlags;
+ support::ulittle16_t CSDVersion;
+ uint16_t Reserved;
+ support::ulittle32_t EditList;
+ support::ulittle32_t SecurityCookie;
+ support::ulittle32_t SEHandlerTable;
+ support::ulittle32_t SEHandlerCount;
+};
+
+struct coff_runtime_function_x64 {
+ support::ulittle32_t BeginAddress;
+ support::ulittle32_t EndAddress;
+ support::ulittle32_t UnwindInformation;
+};
+
class COFFObjectFile : public ObjectFile {
private:
friend class ImportDirectoryEntryRef;
+ friend class ExportDirectoryEntryRef;
const coff_file_header *COFFHeader;
- const pe32_header *PE32Header;
- const data_directory *DataDirectory;
- const coff_section *SectionTable;
- const coff_symbol *SymbolTable;
- const char *StringTable;
- uint32_t StringTableSize;
+ const pe32_header *PE32Header;
+ const pe32plus_header *PE32PlusHeader;
+ const data_directory *DataDirectory;
+ const coff_section *SectionTable;
+ const coff_symbol *SymbolTable;
+ const char *StringTable;
+ uint32_t StringTableSize;
const import_directory_table_entry *ImportDirectory;
- uint32_t NumberOfImportDirectory;
+ uint32_t NumberOfImportDirectory;
+ const export_directory_table_entry *ExportDirectory;
- error_code getString(uint32_t offset, StringRef &Res) const;
+ std::error_code getString(uint32_t offset, StringRef &Res) const;
- const coff_symbol *toSymb(DataRefImpl Symb) const;
- const coff_section *toSec(DataRefImpl Sec) const;
- const coff_relocation *toRel(DataRefImpl Rel) const;
+ const coff_symbol *toSymb(DataRefImpl Symb) const;
+ const coff_section *toSec(DataRefImpl Sec) const;
+ const coff_relocation *toRel(DataRefImpl Rel) const;
- error_code initSymbolTablePtr();
- error_code initImportTablePtr();
+ std::error_code initSymbolTablePtr();
+ std::error_code initImportTablePtr();
+ std::error_code initExportTablePtr();
protected:
- virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
- virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
- virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
- virtual error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const;
- virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
-
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
- virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
- virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const;
- virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const;
- virtual relocation_iterator section_rel_end(DataRefImpl Sec) const;
-
- virtual error_code getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const;
- virtual error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const;
- virtual error_code getRelocationOffset(DataRefImpl Rel,
- uint64_t &Res) const;
- virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
- virtual error_code getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
- virtual error_code getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
-
- virtual error_code getLibraryNext(DataRefImpl LibData,
- LibraryRef &Result) const;
- virtual error_code getLibraryPath(DataRefImpl LibData,
- StringRef &Result) const;
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const override;
+ std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const override;
+ std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) 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;
+ std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ std::error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Result) const override;
+ std::error_code getLibraryPath(DataRefImpl LibData,
+ StringRef &Result) const override;
public:
- COFFObjectFile(MemoryBuffer *Object, error_code &ec);
- virtual symbol_iterator begin_symbols() const;
- virtual symbol_iterator end_symbols() const;
- virtual symbol_iterator begin_dynamic_symbols() const;
- virtual symbol_iterator end_dynamic_symbols() const;
- virtual library_iterator begin_libraries_needed() const;
- virtual library_iterator end_libraries_needed() const;
- virtual section_iterator begin_sections() const;
- virtual section_iterator end_sections() const;
-
- const coff_section *getCOFFSection(section_iterator &It) const;
- const coff_symbol *getCOFFSymbol(symbol_iterator &It) const;
- const coff_relocation *getCOFFRelocation(relocation_iterator &It) const;
-
- virtual uint8_t getBytesInAddress() const;
- virtual StringRef getFileFormatName() const;
- virtual unsigned getArch() const;
- virtual StringRef getLoadName() const;
+ COFFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
+ library_iterator needed_library_begin() const override;
+ library_iterator needed_library_end() const override;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ const coff_section *getCOFFSection(const SectionRef &Section) const;
+ const coff_symbol *getCOFFSymbol(const SymbolRef &Symbol) const;
+ const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ unsigned getArch() const override;
+ StringRef getLoadName() const override;
import_directory_iterator import_directory_begin() const;
import_directory_iterator import_directory_end() const;
-
- error_code getHeader(const coff_file_header *&Res) const;
- error_code getCOFFHeader(const coff_file_header *&Res) const;
- error_code getPE32Header(const pe32_header *&Res) const;
- error_code getDataDirectory(uint32_t index, const data_directory *&Res) const;
- error_code getSection(int32_t index, const coff_section *&Res) const;
- error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
+ export_directory_iterator export_directory_begin() const;
+ export_directory_iterator export_directory_end() const;
+
+ std::error_code getHeader(const coff_file_header *&Res) const;
+ std::error_code getCOFFHeader(const coff_file_header *&Res) const;
+ std::error_code getPE32Header(const pe32_header *&Res) const;
+ std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
+ std::error_code getDataDirectory(uint32_t index,
+ const data_directory *&Res) const;
+ std::error_code getSection(int32_t index, const coff_section *&Res) const;
+ std::error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
template <typename T>
- error_code getAuxSymbol(uint32_t index, const T *&Res) const {
+ std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
const coff_symbol *s;
- error_code ec = getSymbol(index, s);
- Res = reinterpret_cast<const T*>(s);
+ std::error_code ec = getSymbol(index, s);
+ Res = reinterpret_cast<const T *>(s);
return ec;
}
- error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
+ std::error_code getSymbolName(const coff_symbol *symbol,
+ StringRef &Res) const;
ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
- error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
- error_code getSectionContents(const coff_section *Sec,
- ArrayRef<uint8_t> &Res) const;
+ std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
+ std::error_code getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const;
- error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
- error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const;
+ std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
+ std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+ std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
+ StringRef &Name) const;
- static inline bool classof(const Binary *v) {
- return v->isCOFF();
- }
+ static inline bool classof(const Binary *v) { return v->isCOFF(); }
};
// The iterator for the import directory table.
class ImportDirectoryEntryRef {
public:
- ImportDirectoryEntryRef() : OwningObject(0) {}
- ImportDirectoryEntryRef(DataRefImpl ImportDirectory,
+ ImportDirectoryEntryRef() : OwningObject(nullptr) {}
+ ImportDirectoryEntryRef(const import_directory_table_entry *Table, uint32_t I,
const COFFObjectFile *Owner)
- : ImportDirectoryPimpl(ImportDirectory), OwningObject(Owner) {}
+ : ImportTable(Table), Index(I), OwningObject(Owner) {}
bool operator==(const ImportDirectoryEntryRef &Other) const;
- error_code getNext(ImportDirectoryEntryRef &Result) const;
- error_code getName(StringRef &Result) const;
+ void moveNext();
+ std::error_code getName(StringRef &Result) const;
- error_code
+ std::error_code
getImportTableEntry(const import_directory_table_entry *&Result) const;
- error_code
+ std::error_code
getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
private:
- DataRefImpl ImportDirectoryPimpl;
+ const import_directory_table_entry *ImportTable;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject;
+};
+
+// The iterator for the export directory table entry.
+class ExportDirectoryEntryRef {
+public:
+ ExportDirectoryEntryRef() : OwningObject(nullptr) {}
+ ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
+ const COFFObjectFile *Owner)
+ : ExportTable(Table), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ExportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ std::error_code getDllName(StringRef &Result) const;
+ std::error_code getOrdinalBase(uint32_t &Result) const;
+ std::error_code getOrdinal(uint32_t &Result) const;
+ std::error_code getExportRVA(uint32_t &Result) const;
+ std::error_code getSymbolName(StringRef &Result) const;
+
+private:
+ const export_directory_table_entry *ExportTable;
+ uint32_t Index;
const COFFObjectFile *OwningObject;
};
} // end namespace object
diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h
index 3fa3ec6c124b..4aba08f75ddc 100644
--- a/include/llvm/Object/COFFYAML.h
+++ b/include/llvm/Object/COFFYAML.h
@@ -14,7 +14,8 @@
#ifndef LLVM_OBJECT_COFFYAML_H
#define LLVM_OBJECT_COFFYAML_H
-#include "llvm/Object/YAML.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/MC/YAML.h"
#include "llvm/Support/COFF.h"
namespace llvm {
@@ -35,6 +36,10 @@ inline SectionCharacteristics operator|(SectionCharacteristics a,
// 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;
@@ -44,7 +49,7 @@ namespace COFFYAML {
struct Section {
COFF::section Header;
unsigned Alignment;
- object::yaml::BinaryRef SectionData;
+ yaml::BinaryRef SectionData;
std::vector<Relocation> Relocations;
StringRef Name;
Section();
@@ -54,7 +59,12 @@ namespace COFFYAML {
COFF::symbol Header;
COFF::SymbolBaseType SimpleType;
COFF::SymbolComplexType ComplexType;
- object::yaml::BinaryRef AuxiliaryData;
+ 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();
};
@@ -76,6 +86,21 @@ 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);
};
@@ -96,8 +121,13 @@ struct ScalarEnumerationTraits<COFF::SymbolComplexType> {
};
template <>
-struct ScalarEnumerationTraits<COFF::RelocationTypeX86> {
- static void enumeration(IO &IO, COFF::RelocationTypeX86 &Value);
+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 <>
@@ -120,6 +150,26 @@ 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);
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index a6774c115030..fbc48e6d7218 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -40,19 +40,20 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
// Subclasses of ELFFile may need this for template instantiation
inline std::pair<unsigned char, unsigned char>
-getElfArchType(MemoryBuffer *Object) {
- if (Object->getBufferSize() < ELF::EI_NIDENT)
- return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
- return std::make_pair((uint8_t) Object->getBufferStart()[ELF::EI_CLASS],
- (uint8_t) Object->getBufferStart()[ELF::EI_DATA]);
+getElfArchType(StringRef Object) {
+ if (Object.size() < ELF::EI_NIDENT)
+ return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
+ (uint8_t)ELF::ELFDATANONE);
+ return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
+ (uint8_t)Object[ELF::EI_DATA]);
}
template <class ELFT>
class ELFFile {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef typename conditional<ELFT::Is64Bits,
- uint64_t, uint32_t>::type uintX_t;
+ typedef typename std::conditional<ELFT::Is64Bits,
+ uint64_t, uint32_t>::type uintX_t;
/// \brief Iterate over constant sized entities.
template <class EntT>
@@ -60,12 +61,12 @@ public:
public:
typedef ptrdiff_t difference_type;
typedef EntT value_type;
- typedef std::random_access_iterator_tag iterator_category;
+ typedef std::forward_iterator_tag iterator_category;
typedef value_type &reference;
typedef value_type *pointer;
/// \brief Default construct iterator.
- ELFEntityIterator() : EntitySize(0), Current(0) {}
+ ELFEntityIterator() : EntitySize(0), Current(nullptr) {}
ELFEntityIterator(uintX_t EntSize, const char *Start)
: EntitySize(EntSize), Current(Start) {}
@@ -133,9 +134,11 @@ public:
typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
typedef Elf_Versym_Impl<ELFT> Elf_Versym;
typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
+ typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter;
+ typedef iterator_range<Elf_Shdr_Iter> Elf_Shdr_Range;
/// \brief Archive files are 2 byte aligned, so we need this for
/// PointerIntPair to work.
@@ -228,10 +231,10 @@ private:
typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
typedef DenseMap<unsigned, unsigned> IndexMap_t;
- MemoryBuffer *Buf;
+ StringRef Buf;
const uint8_t *base() const {
- return reinterpret_cast<const uint8_t *>(Buf->getBufferStart());
+ return reinterpret_cast<const uint8_t *>(Buf.data());
}
const Elf_Ehdr *Header;
@@ -249,7 +252,7 @@ private:
/// \brief Represents a region described by entries in the .dynamic table.
struct DynRegionInfo {
- DynRegionInfo() : Addr(0), Size(0), EntSize(0) {}
+ DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
/// \brief Address in current address space.
const void *Addr;
/// \brief Size in bytes of the region.
@@ -273,19 +276,19 @@ private:
public:
// If the integer is 0, this is an Elf_Verdef*.
// If the integer is 1, this is an Elf_Vernaux*.
- VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { }
+ VersionMapEntry() : PointerIntPair<const void*, 1>(nullptr, 0) { }
VersionMapEntry(const Elf_Verdef *verdef)
: PointerIntPair<const void*, 1>(verdef, 0) { }
VersionMapEntry(const Elf_Vernaux *vernaux)
: PointerIntPair<const void*, 1>(vernaux, 1) { }
- bool isNull() const { return getPointer() == NULL; }
+ bool isNull() const { return getPointer() == nullptr; }
bool isVerdef() const { return !isNull() && getInt() == 0; }
bool isVernaux() const { return !isNull() && getInt() == 1; }
const Elf_Verdef *getVerdef() const {
- return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL;
+ return isVerdef() ? (const Elf_Verdef*)getPointer() : nullptr;
}
const Elf_Vernaux *getVernaux() const {
- return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL;
+ return isVernaux() ? (const Elf_Vernaux*)getPointer() : nullptr;
}
};
mutable SmallVector<VersionMapEntry, 16> VersionMap;
@@ -315,7 +318,12 @@ public:
std::pair<const Elf_Shdr *, const Elf_Sym *>
getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const;
- ELFFile(MemoryBuffer *Object, error_code &ec);
+ ELFFile(StringRef Object, std::error_code &ec);
+
+ bool isMipsELF64() const {
+ return Header->e_machine == ELF::EM_MIPS &&
+ Header->getFileClass() == ELF::ELFCLASS64;
+ }
bool isMips64EL() const {
return Header->e_machine == ELF::EM_MIPS &&
@@ -325,6 +333,9 @@ public:
Elf_Shdr_Iter begin_sections() const;
Elf_Shdr_Iter end_sections() const;
+ Elf_Shdr_Range sections() const {
+ return make_range(begin_sections(), end_sections());
+ }
Elf_Sym_Iter begin_symbols() const;
Elf_Sym_Iter end_symbols() const;
@@ -333,12 +344,15 @@ public:
/// \param NULLEnd use one past the first DT_NULL entry as the end instead of
/// the section size.
Elf_Dyn_Iter end_dynamic_table(bool NULLEnd = false) const;
+ Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const {
+ return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd));
+ }
Elf_Sym_Iter begin_dynamic_symbols() const {
if (DynSymRegion.Addr)
return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr,
true);
- return Elf_Sym_Iter(0, 0, true);
+ return Elf_Sym_Iter(0, nullptr, true);
}
Elf_Sym_Iter end_dynamic_symbols() const {
@@ -346,7 +360,7 @@ public:
return Elf_Sym_Iter(DynSymRegion.EntSize,
(const char *)DynSymRegion.Addr + DynSymRegion.Size,
true);
- return Elf_Sym_Iter(0, 0, true);
+ return Elf_Sym_Iter(0, nullptr, true);
}
Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const {
@@ -478,7 +492,7 @@ void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
template <class ELFT>
void ELFFile<ELFT>::LoadVersionMap() const {
// If there is no dynamic symtab or version table, there is nothing to do.
- if (DynSymRegion.Addr == NULL || dot_gnu_version_sec == NULL)
+ if (!DynSymRegion.Addr || !dot_gnu_version_sec)
return;
// Has the VersionMap already been loaded?
@@ -510,7 +524,7 @@ ELFFile<ELFT>::getSection(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return getSection(ExtendedSymbolTable.lookup(symb));
if (symb->st_shndx >= ELF::SHN_LORESERVE)
- return 0;
+ return nullptr;
return getSection(symb->st_shndx);
}
@@ -523,7 +537,7 @@ ELFFile<ELFT>::getSymbol(uint32_t Index) const {
template <class ELFT>
ErrorOr<ArrayRef<uint8_t> >
ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
- if (Sec->sh_offset + Sec->sh_size > Buf->getBufferSize())
+ if (Sec->sh_offset + Sec->sh_size > Buf.size())
return object_error::parse_failed;
const uint8_t *Start = base() + Sec->sh_offset;
return ArrayRef<uint8_t>(Start, Sec->sh_size);
@@ -537,10 +551,16 @@ StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
template <class ELFT>
void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
SmallVectorImpl<char> &Result) const {
- if (!isMips64EL()) {
+ if (!isMipsELF64()) {
StringRef Name = getRelocationTypeName(Type);
Result.append(Name.begin(), Name.end());
} else {
+ // The Mips N64 ABI allows up to three operations to be specified per
+ // relocation record. Unfortunately there's no easy way to test for the
+ // presence of N64 ELFs as they have no special flag that identifies them
+ // as being N64. We can safely assume at the moment that all Mips
+ // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
+ // information to disambiguate between old vs new ABIs.
uint8_t Type1 = (Type >> 0) & 0xFF;
uint8_t Type2 = (Type >> 8) & 0xFF;
uint8_t Type3 = (Type >> 16) & 0xFF;
@@ -565,7 +585,7 @@ std::pair<const typename ELFFile<ELFT>::Elf_Shdr *,
const typename ELFFile<ELFT>::Elf_Sym *>
ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const {
if (!Sec->sh_link)
- return std::make_pair((const Elf_Shdr *)0, (const Elf_Sym *)0);
+ return std::make_pair(nullptr, nullptr);
const Elf_Shdr *SymTable = getSection(Sec->sh_link);
return std::make_pair(
SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL())));
@@ -583,7 +603,7 @@ void ELFFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const {
template <class ELFT>
uint64_t ELFFile<ELFT>::getNumSections() const {
assert(Header && "Header not initialized!");
- if (Header->e_shnum == ELF::SHN_UNDEF) {
+ if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) {
assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
return SectionHeaderTable->sh_size;
}
@@ -602,18 +622,13 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const {
}
template <class ELFT>
-ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec)
- : Buf(Object),
- SectionHeaderTable(0),
- dot_shstrtab_sec(0),
- dot_strtab_sec(0),
- dot_symtab_sec(0),
- SymbolTableSectionHeaderIndex(0),
- dot_gnu_version_sec(0),
- dot_gnu_version_r_sec(0),
- dot_gnu_version_d_sec(0),
- dt_soname(0) {
- const uint64_t FileSize = Buf->getBufferSize();
+ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
+ : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr),
+ dot_strtab_sec(nullptr), dot_symtab_sec(nullptr),
+ SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr),
+ dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr),
+ dt_soname(nullptr) {
+ const uint64_t FileSize = Buf.size();
if (sizeof(Elf_Ehdr) > FileSize)
// FIXME: Proper error handling.
@@ -641,30 +656,29 @@ ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec)
// Scan sections for special sections.
- for (Elf_Shdr_Iter SecI = begin_sections(), SecE = end_sections();
- SecI != SecE; ++SecI) {
- switch (SecI->sh_type) {
+ for (const Elf_Shdr &Sec : sections()) {
+ switch (Sec.sh_type) {
case ELF::SHT_SYMTAB_SHNDX:
if (SymbolTableSectionHeaderIndex)
// FIXME: Proper error handling.
report_fatal_error("More than one .symtab_shndx!");
- SymbolTableSectionHeaderIndex = &*SecI;
+ SymbolTableSectionHeaderIndex = &Sec;
break;
case ELF::SHT_SYMTAB:
if (dot_symtab_sec)
// FIXME: Proper error handling.
report_fatal_error("More than one .symtab!");
- dot_symtab_sec = &*SecI;
- dot_strtab_sec = getSection(SecI->sh_link);
+ dot_symtab_sec = &Sec;
+ dot_strtab_sec = getSection(Sec.sh_link);
break;
case ELF::SHT_DYNSYM: {
if (DynSymRegion.Addr)
// FIXME: Proper error handling.
report_fatal_error("More than one .dynsym!");
- DynSymRegion.Addr = base() + SecI->sh_offset;
- DynSymRegion.Size = SecI->sh_size;
- DynSymRegion.EntSize = SecI->sh_entsize;
- const Elf_Shdr *DynStr = getSection(SecI->sh_link);
+ DynSymRegion.Addr = base() + Sec.sh_offset;
+ DynSymRegion.Size = Sec.sh_size;
+ DynSymRegion.EntSize = Sec.sh_entsize;
+ const Elf_Shdr *DynStr = getSection(Sec.sh_link);
DynStrRegion.Addr = base() + DynStr->sh_offset;
DynStrRegion.Size = DynStr->sh_size;
DynStrRegion.EntSize = DynStr->sh_entsize;
@@ -674,27 +688,27 @@ ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec)
if (DynamicRegion.Addr)
// FIXME: Proper error handling.
report_fatal_error("More than one .dynamic!");
- DynamicRegion.Addr = base() + SecI->sh_offset;
- DynamicRegion.Size = SecI->sh_size;
- DynamicRegion.EntSize = SecI->sh_entsize;
+ DynamicRegion.Addr = base() + Sec.sh_offset;
+ DynamicRegion.Size = Sec.sh_size;
+ DynamicRegion.EntSize = Sec.sh_entsize;
break;
case ELF::SHT_GNU_versym:
- if (dot_gnu_version_sec != NULL)
+ if (dot_gnu_version_sec != nullptr)
// FIXME: Proper error handling.
report_fatal_error("More than one .gnu.version section!");
- dot_gnu_version_sec = &*SecI;
+ dot_gnu_version_sec = &Sec;
break;
case ELF::SHT_GNU_verdef:
- if (dot_gnu_version_d_sec != NULL)
+ if (dot_gnu_version_d_sec != nullptr)
// FIXME: Proper error handling.
report_fatal_error("More than one .gnu.version_d section!");
- dot_gnu_version_d_sec = &*SecI;
+ dot_gnu_version_d_sec = &Sec;
break;
case ELF::SHT_GNU_verneed:
- if (dot_gnu_version_r_sec != NULL)
+ if (dot_gnu_version_r_sec != nullptr)
// FIXME: Proper error handling.
report_fatal_error("More than one .gnu.version_r section!");
- dot_gnu_version_r_sec = &*SecI;
+ dot_gnu_version_r_sec = &Sec;
break;
}
}
@@ -730,7 +744,7 @@ ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec)
}
}
- ec = error_code::success();
+ ec = std::error_code();
}
// Get the symbol table index in the symtab section given a symbol
@@ -761,7 +775,7 @@ typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const {
template <class ELFT>
typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const {
if (!dot_symtab_sec)
- return Elf_Sym_Iter(0, 0, false);
+ return Elf_Sym_Iter(0, nullptr, false);
return Elf_Sym_Iter(dot_symtab_sec->sh_entsize,
(const char *)base() + dot_symtab_sec->sh_offset, false);
}
@@ -769,7 +783,7 @@ typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const {
template <class ELFT>
typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const {
if (!dot_symtab_sec)
- return Elf_Sym_Iter(0, 0, false);
+ return Elf_Sym_Iter(0, nullptr, false);
return Elf_Sym_Iter(dot_symtab_sec->sh_entsize,
(const char *)base() + dot_symtab_sec->sh_offset +
dot_symtab_sec->sh_size,
@@ -782,14 +796,14 @@ ELFFile<ELFT>::begin_dynamic_table() const {
if (DynamicRegion.Addr)
return Elf_Dyn_Iter(DynamicRegion.EntSize,
(const char *)DynamicRegion.Addr);
- return Elf_Dyn_Iter(0, 0);
+ return Elf_Dyn_Iter(0, nullptr);
}
template <class ELFT>
typename ELFFile<ELFT>::Elf_Dyn_Iter
ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
if (!DynamicRegion.Addr)
- return Elf_Dyn_Iter(0, 0);
+ return Elf_Dyn_Iter(0, nullptr);
Elf_Dyn_Iter Ret(DynamicRegion.EntSize,
(const char *)DynamicRegion.Addr + DynamicRegion.Size);
@@ -809,17 +823,13 @@ ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
template <class ELFT>
StringRef ELFFile<ELFT>::getLoadName() const {
if (!dt_soname) {
+ dt_soname = "";
// Find the DT_SONAME entry
- Elf_Dyn_Iter it = begin_dynamic_table();
- Elf_Dyn_Iter ie = end_dynamic_table();
- while (it != ie && it->getTag() != ELF::DT_SONAME)
- ++it;
-
- if (it != ie) {
- dt_soname = getDynamicString(it->getVal());
- } else {
- dt_soname = "";
- }
+ for (const auto &Entry : dynamic_table())
+ if (Entry.getTag() == ELF::DT_SONAME) {
+ dt_soname = getDynamicString(Entry.getVal());
+ break;
+ }
}
return dt_soname;
}
@@ -842,7 +852,7 @@ template <class ELFT>
const typename ELFFile<ELFT>::Elf_Shdr *
ELFFile<ELFT>::getSection(uint32_t index) const {
if (index == 0)
- return 0;
+ return nullptr;
if (!SectionHeaderTable || index >= getNumSections())
// FIXME: Proper error handling.
report_fatal_error("Invalid section index!");
@@ -871,7 +881,7 @@ const char *ELFFile<ELFT>::getString(const Elf_Shdr *section,
template <class ELFT>
const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const {
if (!DynStrRegion.Addr || Offset >= DynStrRegion.Size)
- return 0;
+ return nullptr;
return (const char *)DynStrRegion.Addr + Offset;
}
@@ -913,7 +923,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
const Elf_Sym *symb,
bool &IsDefault) const {
// Handle non-dynamic symbols.
- if (section != DynSymRegion.Addr && section != 0) {
+ if (section != DynSymRegion.Addr && section != nullptr) {
// Non-dynamic symbols can have versions in their names
// A name of the form 'foo@V1' indicates version 'V1', non-default.
// A name of the form 'foo@@V2' indicates version 'V2', default version.
@@ -937,7 +947,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
}
// This is a dynamic symbol. Look in the GNU symbol version table.
- if (dot_gnu_version_sec == NULL) {
+ if (!dot_gnu_version_sec) {
// No version table.
IsDefault = false;
return StringRef("");
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 962a3e2a8655..069f38112def 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -44,6 +44,7 @@ public:
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+ typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
@@ -55,53 +56,65 @@ public:
protected:
ELFFile<ELFT> EF;
- virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
- virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
- virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const;
- virtual error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const;
- virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
-
- virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
- virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const;
-
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
- virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
- virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const;
- virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const;
- virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const;
- virtual relocation_iterator section_rel_end(DataRefImpl Sec) const;
- virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
-
- virtual error_code getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const;
- virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
- virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
- virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
- virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
- virtual error_code
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const override;
+ std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const override;
+ std::error_code getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const override;
+ std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override;
+ std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
+
+ std::error_code getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const override;
+ std::error_code getLibraryPath(DataRefImpl Data,
+ StringRef &Res) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ section_iterator getRelocatedSection(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code
getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
+ SmallVectorImpl<char> &Result) const override;
uint64_t getROffset(DataRefImpl Rel) const;
StringRef getRelocationTypeName(uint32_t Type) const;
@@ -165,31 +178,35 @@ protected:
bool isDyldELFObject;
public:
- ELFObjectFile(MemoryBuffer *Object, error_code &ec);
+ ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
const Elf_Sym *getSymbol(DataRefImpl Symb) const;
- virtual symbol_iterator begin_symbols() const;
- virtual symbol_iterator end_symbols() const;
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
- virtual symbol_iterator begin_dynamic_symbols() const;
- virtual symbol_iterator end_dynamic_symbols() const;
+ symbol_iterator dynamic_symbol_begin() const;
+ symbol_iterator dynamic_symbol_end() const;
- virtual section_iterator begin_sections() const;
- virtual section_iterator end_sections() const;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
- virtual library_iterator begin_libraries_needed() const;
- virtual library_iterator end_libraries_needed() const;
+ library_iterator needed_library_begin() const override;
+ library_iterator needed_library_end() const override;
- error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
- error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
- bool &IsDefault) const;
+ std::error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
+ std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
+ bool &IsDefault) const;
- virtual uint8_t getBytesInAddress() const;
- virtual StringRef getFileFormatName() const;
- virtual StringRef getObjectType() const { return "ELF"; }
- virtual unsigned getArch() const;
- virtual StringRef getLoadName() const;
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ unsigned getArch() const override;
+ StringRef getLoadName() const override;
+
+ std::error_code getPlatformFlags(unsigned &Result) const override {
+ Result = EF.getHeader()->e_flags;
+ return object_error::success;
+ }
const ELFFile<ELFT> *getELFFile() const { return &EF; }
@@ -208,44 +225,40 @@ typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile;
typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile;
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb,
- SymbolRef &Result) const {
- Result = SymbolRef(toDRI(++toELFSymIter(Symb)), this);
- return object_error::success;
+void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
+ Symb = toDRI(++toELFSymIter(Symb));
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
- StringRef &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
+ StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
if (!Name)
- return Name;
+ return Name.getError();
Result = *Name;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
- StringRef &Version,
- bool &IsDefault) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
+ StringRef &Version,
+ bool &IsDefault) const {
DataRefImpl Symb = SymRef.getRawDataRefImpl();
const Elf_Sym *symb = getSymbol(Symb);
ErrorOr<StringRef> Ver =
EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault);
if (!Ver)
- return Ver;
+ return Ver.getError();
Version = *Ver;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Result) const {
const Elf_Sym *ESym = getSymbol(Symb);
- const Elf_Shdr *ESec;
switch (EF.getSymbolTableIndex(ESym)) {
case ELF::SHN_COMMON:
- // Unintialized symbols have no offset in the object file
case ELF::SHN_UNDEF:
Result = UnknownAddressOrSize;
return object_error::success;
@@ -253,75 +266,25 @@ error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb,
Result = ESym->st_value;
return object_error::success;
default:
- ESec = EF.getSection(ESym);
- }
-
- switch (ESym->getType()) {
- case ELF::STT_SECTION:
- Result = ESec ? ESec->sh_offset : UnknownAddressOrSize;
- return object_error::success;
- case ELF::STT_FUNC:
- case ELF::STT_OBJECT:
- case ELF::STT_NOTYPE:
- Result = ESym->st_value + (ESec ? ESec->sh_offset : 0);
- return object_error::success;
- default:
- Result = UnknownAddressOrSize;
- return object_error::success;
+ break;
}
-}
-template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Result) const {
- const Elf_Sym *ESym = getSymbol(Symb);
- const Elf_Shdr *ESec;
- switch (EF.getSymbolTableIndex(ESym)) {
- case ELF::SHN_COMMON:
- case ELF::SHN_UNDEF:
- Result = UnknownAddressOrSize;
- return object_error::success;
- case ELF::SHN_ABS:
- Result = ESym->st_value;
- return object_error::success;
- default:
- ESec = EF.getSection(ESym);
- }
+ const Elf_Ehdr *Header = EF.getHeader();
+ Result = ESym->st_value;
- switch (ESym->getType()) {
- case ELF::STT_SECTION:
- Result = ESec ? ESec->sh_addr : UnknownAddressOrSize;
- return object_error::success;
- case ELF::STT_FUNC:
- case ELF::STT_OBJECT:
- case ELF::STT_NOTYPE:
- bool IsRelocatable;
- switch (EF.getHeader()->e_type) {
- case ELF::ET_EXEC:
- case ELF::ET_DYN:
- IsRelocatable = false;
- break;
- default:
- IsRelocatable = true;
- }
- Result = ESym->st_value;
+ // Clear the ARM/Thumb indicator flag.
+ if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC)
+ Result &= ~1;
- // Clear the ARM/Thumb indicator flag.
- if (EF.getHeader()->e_machine == ELF::EM_ARM)
- Result &= ~1;
+ if (Header->e_type == ELF::ET_REL)
+ Result += EF.getSection(ESym)->sh_addr;
- if (IsRelocatable && ESec != 0)
- Result += ESec->sh_addr;
- return object_error::success;
- default:
- Result = UnknownAddressOrSize;
- return object_error::success;
- }
+ return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
- uint32_t &Res) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const {
Elf_Sym_Iter Sym = toELFSymIter(Symb);
if (Sym->st_shndx == ELF::SHN_COMMON)
Res = Sym->st_value;
@@ -331,15 +294,23 @@ error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
+ uint64_t &Result) const {
Result = toELFSymIter(Symb)->st_size;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb,
+ uint8_t &Result) const {
+ Result = toELFSymIter(Symb)->st_other;
+ return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Result) const {
const Elf_Sym *ESym = getSymbol(Symb);
switch (ESym->getType()) {
@@ -368,11 +339,11 @@ error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
- uint32_t &Result) const {
- const Elf_Sym *ESym = getSymbol(Symb);
+uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
+ Elf_Sym_Iter EIter = toELFSymIter(Symb);
+ const Elf_Sym *ESym = &*EIter;
- Result = SymbolRef::SF_None;
+ uint32_t Result = SymbolRef::SF_None;
if (ESym->getBinding() != ELF::STB_LOCAL)
Result |= SymbolRef::SF_Global;
@@ -384,7 +355,7 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
Result |= SymbolRef::SF_Absolute;
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
- ESym == &*EF.begin_symbols())
+ EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols())
Result |= SymbolRef::SF_FormatSpecific;
if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
@@ -394,19 +365,17 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON)
Result |= SymbolRef::SF_Common;
- if (ESym->getType() == ELF::STT_TLS)
- Result |= SymbolRef::SF_ThreadLocal;
-
- return object_error::success;
+ return Result;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const {
+std::error_code
+ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const {
const Elf_Sym *ESym = getSymbol(Symb);
const Elf_Shdr *ESec = EF.getSection(ESym);
if (!ESec)
- Res = end_sections();
+ Res = section_end();
else {
DataRefImpl Sec;
Sec.p = reinterpret_cast<intptr_t>(ESec);
@@ -416,69 +385,61 @@ error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb,
- uint64_t &Val) const {
- const Elf_Sym *ESym = getSymbol(Symb);
- Val = ESym->st_value;
- return object_error::success;
-}
-
-template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec,
- SectionRef &Result) const {
- Result = SectionRef(toDRI(++toELFShdrIter(Sec)), this);
- return object_error::success;
+void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
+ Sec = toDRI(++toELFShdrIter(Sec));
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
- StringRef &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
+ StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec));
if (!Name)
- return Name;
+ return Name.getError();
Result = *Name;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
+ uint64_t &Result) const {
Result = toELFShdrIter(Sec)->sh_addr;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
+ uint64_t &Result) const {
Result = toELFShdrIter(Sec)->sh_size;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
- StringRef &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
+ StringRef &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
- uint64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Result) const {
Result = toELFShdrIter(Sec)->sh_addralign;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
+ bool &Result) const {
Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
+ bool &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
EShdr->sh_type == ELF::SHT_PROGBITS;
@@ -486,8 +447,8 @@ error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
+ bool &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
EShdr->sh_type == ELF::SHT_NOBITS;
@@ -495,7 +456,7 @@ error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
}
template <class ELFT>
-error_code
+std::error_code
ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
bool &Result) const {
Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC;
@@ -503,31 +464,31 @@ ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
+ bool &Result) const {
Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
+ bool &Result) const {
Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Result) const {
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
- DataRefImpl Symb,
- bool &Result) const {
+std::error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const {
Elf_Sym_Iter ESym = toELFSymIter(Symb);
uintX_t Index = ESym->st_shndx;
@@ -566,12 +527,12 @@ template <class ELFT>
section_iterator
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
if (EF.getHeader()->e_type != ELF::ET_REL)
- return end_sections();
+ return section_end();
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
uintX_t Type = EShdr->sh_type;
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
- return end_sections();
+ return section_end();
const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
return section_iterator(SectionRef(toDRI(R), this));
@@ -579,11 +540,8 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
// Relocations
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
- RelocationRef &Result) const {
+void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
++Rel.d.b;
- Result = RelocationRef(Rel, this);
- return object_error::success;
}
template <class ELFT>
@@ -604,7 +562,7 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
}
}
if (!symbolIdx)
- return end_symbols();
+ return symbol_end();
const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
@@ -624,15 +582,29 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
- uint64_t &Result) const {
- Result = getROffset(Rel);
+std::error_code
+ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Result) const {
+ uint64_t ROffset = getROffset(Rel);
+ const Elf_Ehdr *Header = EF.getHeader();
+
+ if (Header->e_type == ELF::ET_REL) {
+ const Elf_Shdr *RelocationSec = getRelSection(Rel);
+ const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
+ Result = ROffset + RelocatedSec->sh_addr;
+ } else {
+ Result = ROffset;
+ }
+
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
- uint64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Result) const {
+ assert(EF.getHeader()->e_type == ELF::ET_REL &&
+ "Only relocatable object files have relocation offsets");
Result = getROffset(Rel);
return object_error::success;
}
@@ -651,8 +623,8 @@ uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
- uint64_t &Result) const {
+std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
+ uint64_t &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default:
@@ -675,7 +647,7 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationTypeName(
+std::error_code ELFObjectFile<ELFT>::getRelocationTypeName(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
uint32_t type;
@@ -697,8 +669,9 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
- int64_t &Result) const {
+std::error_code
+ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
+ int64_t &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default:
@@ -715,7 +688,7 @@ error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationValueString(
+std::error_code ELFObjectFile<ELFT>::getRelocationValueString(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getRelSection(Rel);
uint8_t type;
@@ -743,7 +716,7 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString(
ErrorOr<StringRef> SymName =
EF.getSymbolName(EF.getSection(sec->sh_link), symb);
if (!SymName)
- return SymName;
+ return SymName.getError();
switch (EF.getHeader()->e_machine) {
case ELF::EM_X86_64:
switch (type) {
@@ -783,6 +756,7 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString(
}
case ELF::EM_ARM:
case ELF::EM_HEXAGON:
+ case ELF::EM_MIPS:
res = *SymName;
break;
default:
@@ -812,40 +786,41 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
}
template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
+ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ std::error_code &EC)
: ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
support::little,
ELFT::Is64Bits),
- Object),
- EF(Object, ec) {}
+ std::move(Object)),
+ EF(Data->getBuffer(), EC) {}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const {
- return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
+ return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::end_symbols() const {
- return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
+ return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const {
+symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const {
+symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
}
template <class ELFT>
-section_iterator ELFObjectFile<ELFT>::begin_sections() const {
+section_iterator ELFObjectFile<ELFT>::section_begin() const {
return section_iterator(SectionRef(toDRI(EF.begin_sections()), this));
}
template <class ELFT>
-section_iterator ELFObjectFile<ELFT>::end_sections() const {
+section_iterator ELFObjectFile<ELFT>::section_end() const {
return section_iterator(SectionRef(toDRI(EF.end_sections()), this));
}
@@ -863,7 +838,7 @@ StringRef ELFObjectFile<ELFT>::getLoadName() const {
}
template <class ELFT>
-library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const {
+library_iterator ELFObjectFile<ELFT>::needed_library_begin() const {
Elf_Dyn_Iter DI = EF.begin_dynamic_table();
Elf_Dyn_Iter DE = EF.end_dynamic_table();
@@ -874,8 +849,8 @@ library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const {
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
- LibraryRef &Result) const {
+std::error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const {
Elf_Dyn_Iter DI = toELFDynIter(Data);
Elf_Dyn_Iter DE = EF.end_dynamic_table();
@@ -889,14 +864,14 @@ error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
- StringRef &Res) const {
+std::error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
+ StringRef &Res) const {
Res = EF.getDynamicString(toELFDynIter(Data)->getVal());
return object_error::success;
}
template <class ELFT>
-library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const {
+library_iterator ELFObjectFile<ELFT>::needed_library_end() const {
return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this));
}
@@ -922,6 +897,9 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF32-mips";
case ELF::EM_PPC:
return "ELF32-ppc";
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return "ELF32-sparc";
default:
return "ELF32-unknown";
}
@@ -937,6 +915,10 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF64-ppc64";
case ELF::EM_S390:
return "ELF64-s390";
+ case ELF::EM_SPARCV9:
+ return "ELF64-sparc";
+ case ELF::EM_MIPS:
+ return "ELF64-mips";
default:
return "ELF64-unknown";
}
@@ -948,6 +930,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
template <class ELFT>
unsigned ELFObjectFile<ELFT>::getArch() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
switch (EF.getHeader()->e_machine) {
case ELF::EM_386:
return Triple::x86;
@@ -960,13 +943,25 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_HEXAGON:
return Triple::hexagon;
case ELF::EM_MIPS:
- return (ELFT::TargetEndianness == support::little) ? Triple::mipsel
- : Triple::mips;
+ switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32:
+ return IsLittleEndian ? Triple::mipsel : Triple::mips;
+ case ELF::ELFCLASS64:
+ return IsLittleEndian ? Triple::mips64el : Triple::mips64;
+ default:
+ report_fatal_error("Invalid ELFCLASS!");
+ }
case ELF::EM_PPC64:
- return (ELFT::TargetEndianness == support::little) ? Triple::ppc64le
- : Triple::ppc64;
+ return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
case ELF::EM_S390:
return Triple::systemz;
+
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return Triple::sparc;
+ case ELF::EM_SPARCV9:
+ return Triple::sparcv9;
+
default:
return Triple::UnknownArch;
}
@@ -974,8 +969,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
/// FIXME: Maybe we should have a base ElfObjectFile that is not a template
/// and make these member functions?
-static inline error_code getELFRelocationAddend(const RelocationRef R,
- int64_t &Addend) {
+inline std::error_code getELFRelocationAddend(const RelocationRef R,
+ int64_t &Addend) {
const ObjectFile *Obj = R.getObjectFile();
DataRefImpl DRI = R.getRawDataRefImpl();
// Little-endian 32-bit
@@ -997,12 +992,31 @@ static inline error_code getELFRelocationAddend(const RelocationRef R,
llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF");
}
+inline std::pair<symbol_iterator, symbol_iterator>
+getELFDynamicSymbolIterators(SymbolicFile *Obj) {
+ if (const ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+ if (const ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+ if (const ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+ if (const ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+
+ llvm_unreachable(
+ "Object passed to getELFDynamicSymbolIterators() is not ELF");
+}
+
/// This is a generic interface for retrieving GNU symbol version
/// information from an ELFObjectFile.
-static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
- const SymbolRef &Sym,
- StringRef &Version,
- bool &IsDefault) {
+inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj,
+ const SymbolRef &Sym,
+ StringRef &Version,
+ bool &IsDefault) {
// Little-endian 32-bit
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index fca965f3dbf2..fc8cc9581655 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -16,7 +16,7 @@
#ifndef LLVM_OBJECT_ELFYAML_H
#define LLVM_OBJECT_ELFYAML_H
-#include "llvm/Object/YAML.h"
+#include "llvm/MC/YAML.h"
#include "llvm/Support/ELF.h"
namespace llvm {
@@ -37,10 +37,14 @@ 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(uint8_t, ELF_REL)
// 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)
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
// since 64-bit can hold 32-bit values too.
@@ -50,6 +54,7 @@ struct FileHeader {
ELF_ELFOSABI OSABI;
ELF_ET Type;
ELF_EM Machine;
+ ELF_EF Flags;
llvm::yaml::Hex64 Entry;
};
struct Symbol {
@@ -58,6 +63,7 @@ struct Symbol {
StringRef Section;
llvm::yaml::Hex64 Value;
llvm::yaml::Hex64 Size;
+ ELF_STV Visibility;
};
struct LocalGlobalWeakSymbols {
std::vector<Symbol> Local;
@@ -65,17 +71,42 @@ struct LocalGlobalWeakSymbols {
std::vector<Symbol> Weak;
};
struct Section {
+ enum class SectionKind { RawContent, Relocation };
+ SectionKind Kind;
StringRef Name;
ELF_SHT Type;
ELF_SHF Flags;
llvm::yaml::Hex64 Address;
- object::yaml::BinaryRef Content;
StringRef Link;
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 Relocation {
+ llvm::yaml::Hex64 Offset;
+ int64_t Addend;
+ ELF_REL Type;
+ StringRef Symbol;
+};
+struct RelocationSection : Section {
+ StringRef Info;
+ std::vector<Relocation> Relocations;
+ RelocationSection() : Section(SectionKind::Relocation) {}
+ static bool classof(const Section *S) {
+ return S->Kind == SectionKind::Relocation;
+ }
};
struct Object {
FileHeader Header;
- std::vector<Section> Sections;
+ 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
@@ -86,8 +117,9 @@ struct Object {
} // end namespace ELFYAML
} // end namespace llvm
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section)
+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)
namespace llvm {
namespace yaml {
@@ -118,6 +150,11 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
};
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);
};
@@ -133,6 +170,16 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
};
template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
+ static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
+ static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
+};
+
+template <>
struct MappingTraits<ELFYAML::FileHeader> {
static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
};
@@ -147,9 +194,14 @@ 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<ELFYAML::Section> {
- static void mapping(IO &IO, ELFYAML::Section &Section);
+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 <>
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
index 8b0570b02f8b..701da1272cd5 100644
--- a/include/llvm/Object/Error.h
+++ b/include/llvm/Object/Error.h
@@ -14,38 +14,32 @@
#ifndef LLVM_OBJECT_ERROR_H
#define LLVM_OBJECT_ERROR_H
-#include "llvm/Support/system_error.h"
+#include <system_error>
namespace llvm {
namespace object {
-const error_category &object_category();
+const std::error_category &object_category();
-struct object_error {
- enum Impl {
- success = 0,
- arch_not_found,
- invalid_file_type,
- parse_failed,
- unexpected_eof
- };
- Impl V;
-
- object_error(Impl V) : V(V) {}
- operator Impl() const { return V; }
+enum class object_error {
+ success = 0,
+ arch_not_found,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof
};
-inline error_code make_error_code(object_error e) {
- return error_code(static_cast<int>(e), object_category());
+inline std::error_code make_error_code(object_error e) {
+ return std::error_code(static_cast<int>(e), object_category());
}
} // end namespace object.
-template <> struct is_error_code_enum<object::object_error> : true_type { };
-
-template <> struct is_error_code_enum<object::object_error::Impl> : true_type {
-};
-
} // end namespace llvm.
+namespace std {
+template <>
+struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
+}
+
#endif
diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h
new file mode 100644
index 000000000000..b33cc263b9bd
--- /dev/null
+++ b/include/llvm/Object/IRObjectFile.h
@@ -0,0 +1,59 @@
+//===- IRObjectFile.h - LLVM IR object file 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 the IRObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IR_OBJECT_FILE_H
+#define LLVM_OBJECT_IR_OBJECT_FILE_H
+
+#include "llvm/Object/SymbolicFile.h"
+
+namespace llvm {
+class Mangler;
+class Module;
+class GlobalValue;
+
+namespace object {
+class IRObjectFile : public SymbolicFile {
+ std::unique_ptr<Module> M;
+ std::unique_ptr<Mangler> Mang;
+ std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
+
+public:
+ IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::unique_ptr<Module> M);
+ ~IRObjectFile();
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ const GlobalValue *getSymbolGV(DataRefImpl Symb) const;
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
+
+ const Module &getModule() const {
+ return const_cast<IRObjectFile*>(this)->getModule();
+ }
+ Module &getModule() {
+ return *M;
+ }
+
+ static inline bool classof(const Binary *v) {
+ return v->isIR();
+ }
+
+ static ErrorOr<IRObjectFile *>
+ createIRObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ LLVMContext &Context);
+};
+}
+}
+
+#endif
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 100613ac8ccb..4835eb80bd65 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -31,18 +31,18 @@ class DiceRef {
const ObjectFile *OwningObject;
public:
- DiceRef() : OwningObject(NULL) { }
+ DiceRef() : OwningObject(nullptr) { }
DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
bool operator==(const DiceRef &Other) const;
bool operator<(const DiceRef &Other) const;
- error_code getNext(DiceRef &Result) const;
+ void moveNext();
- error_code getOffset(uint32_t &Result) const;
- error_code getLength(uint16_t &Result) const;
- error_code getKind(uint16_t &Result) const;
+ std::error_code getOffset(uint32_t &Result) const;
+ std::error_code getLength(uint16_t &Result) const;
+ std::error_code getKind(uint16_t &Result) const;
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
@@ -56,77 +56,97 @@ public:
MachO::load_command C; // The command itself.
};
- MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
- error_code &ec);
-
- virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
- virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const;
- virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const;
- virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
-
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
- virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
- virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
- virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const;
- virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
- virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const;
- virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const;
- virtual relocation_iterator section_rel_end(DataRefImpl Sec) const;
-
- virtual error_code getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const;
- virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
- virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
- virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
- virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
- virtual error_code getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
- virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
-
- virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
- virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
+ MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, bool IsLittleEndian,
+ bool Is64Bits, std::error_code &EC);
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const override;
+
+ // MachO specific.
+ std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
+
+ std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const override;
+ std::error_code getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const override;
+ std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const override;
+ std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const override;
+ std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const override;
+ std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) 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;
+ std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ std::error_code getRelocationHidden(DataRefImpl Rel,
+ bool &Result) const override;
+
+ std::error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Res) const override;
+ std::error_code getLibraryPath(DataRefImpl LibData,
+ StringRef &Res) const override;
+
+ // MachO specific.
+ std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &Res);
// TODO: Would be useful to have an iterator based version
// of the load command interface too.
- virtual symbol_iterator begin_symbols() const;
- virtual symbol_iterator end_symbols() const;
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
- virtual symbol_iterator begin_dynamic_symbols() const;
- virtual symbol_iterator end_dynamic_symbols() const;
+ // MachO specific.
+ basic_symbol_iterator getSymbolByIndex(unsigned Index) const;
- virtual section_iterator begin_sections() const;
- virtual section_iterator end_sections() const;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
- virtual library_iterator begin_libraries_needed() const;
- virtual library_iterator end_libraries_needed() const;
+ library_iterator needed_library_begin() const override;
+ library_iterator needed_library_end() const override;
- virtual uint8_t getBytesInAddress() const;
+ uint8_t getBytesInAddress() const override;
- virtual StringRef getFileFormatName() const;
- virtual unsigned getArch() const;
+ StringRef getFileFormatName() const override;
+ unsigned getArch() const override;
- virtual StringRef getLoadName() const;
+ StringRef getLoadName() const override;
relocation_iterator section_rel_begin(unsigned Index) const;
relocation_iterator section_rel_end(unsigned Index) const;
@@ -179,6 +199,10 @@ public:
getSegment64LoadCommand(const LoadCommandInfo &L) const;
MachO::linker_options_command
getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
+ MachO::version_min_command
+ getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+ MachO::dylib_command
+ getDylibIDLoadCommand(const LoadCommandInfo &L) const;
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
@@ -197,7 +221,13 @@ public:
bool is64Bit() const;
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+ static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
+ StringRef &Suffix);
+
static Triple::ArchType getArch(uint32_t CPUType);
+ static Triple getArch(uint32_t CPUType, uint32_t CPUSubType);
+ static Triple getArch(StringRef ArchFlag);
+ static Triple getHostArch();
static bool classof(const Binary *v) {
return v->isMachO();
@@ -206,6 +236,10 @@ public:
private:
typedef SmallVector<const char*, 1> SectionList;
SectionList Sections;
+ typedef SmallVector<const char*, 1> LibraryList;
+ LibraryList Libraries;
+ typedef SmallVector<StringRef, 1> LibraryShortName;
+ LibraryShortName LibrariesShortNames;
const char *SymtabLoadCmd;
const char *DysymtabLoadCmd;
const char *DataInCodeLoadCmd;
@@ -223,20 +257,17 @@ inline bool DiceRef::operator<(const DiceRef &Other) const {
return DicePimpl < Other.DicePimpl;
}
-inline error_code DiceRef::getNext(DiceRef &Result) const {
- DataRefImpl Rel = DicePimpl;
+inline void DiceRef::moveNext() {
const MachO::data_in_code_entry *P =
- reinterpret_cast<const MachO::data_in_code_entry *>(Rel.p);
- Rel.p = reinterpret_cast<uintptr_t>(P + 1);
- Result = DiceRef(Rel, OwningObject);
- return object_error::success;
+ reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
+ DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
}
// Since a Mach-O data in code reference, a DiceRef, can only be created when
// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
// the methods that get the values of the fields of the reference.
-inline error_code DiceRef::getOffset(uint32_t &Result) const {
+inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
const MachOObjectFile *MachOOF =
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
@@ -244,7 +275,7 @@ inline error_code DiceRef::getOffset(uint32_t &Result) const {
return object_error::success;
}
-inline error_code DiceRef::getLength(uint16_t &Result) const {
+inline std::error_code DiceRef::getLength(uint16_t &Result) const {
const MachOObjectFile *MachOOF =
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
@@ -252,7 +283,7 @@ inline error_code DiceRef::getLength(uint16_t &Result) const {
return object_error::success;
}
-inline error_code DiceRef::getKind(uint16_t &Result) const {
+inline std::error_code DiceRef::getKind(uint16_t &Result) const {
const MachOObjectFile *MachOOF =
static_cast<const MachOObjectFile *>(OwningObject);
MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
index c5d1359256b0..e6677f5bf28b 100644
--- a/include/llvm/Object/MachOUniversal.h
+++ b/include/llvm/Object/MachOUniversal.h
@@ -14,10 +14,12 @@
#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
#define LLVM_OBJECT_MACHOUNIVERSAL_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/Binary.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
namespace llvm {
@@ -41,7 +43,7 @@ public:
ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
void clear() {
- Parent = 0;
+ Parent = nullptr;
Index = 0;
}
@@ -51,8 +53,14 @@ public:
ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
uint32_t getCPUType() const { return Header.cputype; }
+ std::string getArchTypeName() const {
+ Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype);
+ return T.getArchName();
+ }
+
+ ErrorOr<std::unique_ptr<ObjectFile>> getAsObjectFile() const;
- error_code getAsObjectFile(OwningPtr<ObjectFile> &Result) const;
+ std::error_code getAsArchive(std::unique_ptr<Archive> &Result) const;
};
class object_iterator {
@@ -76,13 +84,16 @@ public:
}
};
- MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
+ MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source,
+ std::error_code &ec);
+ static ErrorOr<MachOUniversalBinary *>
+ create(std::unique_ptr<MemoryBuffer> Source);
object_iterator begin_objects() const {
return ObjectForArch(this, 0);
}
object_iterator end_objects() const {
- return ObjectForArch(0, 0);
+ return ObjectForArch(nullptr, 0);
}
uint32_t getNumberOfObjects() const { return NumberOfObjects; }
@@ -92,8 +103,8 @@ public:
return V->isMachOUniversalBinary();
}
- error_code getObjectForArch(Triple::ArchType Arch,
- OwningPtr<ObjectFile> &Result) const;
+ ErrorOr<std::unique_ptr<ObjectFile>>
+ getObjectForArch(Triple::ArchType Arch) const;
};
}
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 9aea639ef058..a4370a3f30d0 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -15,9 +15,10 @@
#define LLVM_OBJECT_OBJECTFILE_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/Binary.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>
@@ -27,65 +28,8 @@ namespace object {
class ObjectFile;
-union DataRefImpl {
- // This entire union should probably be a
- // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
- struct {
- uint32_t a, b;
- } d;
- uintptr_t p;
- DataRefImpl() {
- std::memset(this, 0, sizeof(DataRefImpl));
- }
-};
-
-template<class content_type>
-class content_iterator {
- content_type Current;
-public:
- content_iterator(content_type symb)
- : Current(symb) {}
-
- const content_type* operator->() const {
- return &Current;
- }
-
- const content_type &operator*() const {
- return Current;
- }
-
- bool operator==(const content_iterator &other) const {
- return Current == other.Current;
- }
-
- bool operator!=(const content_iterator &other) const {
- return !(*this == other);
- }
-
- content_iterator& increment(error_code &err) {
- content_type next;
- if (error_code ec = Current.getNext(next))
- err = ec;
- else
- Current = next;
- return *this;
- }
-};
-
-inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
- // Check bitwise identical. This is the only legal way to compare a union w/o
- // knowing which member is in use.
- return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
-}
-
-inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
- // Check bitwise identical. This is the only legal way to compare a union w/o
- // knowing which member is in use.
- return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
-}
-
class SymbolRef;
-typedef content_iterator<SymbolRef> symbol_iterator;
+class symbol_iterator;
/// RelocationRef - This is a value type class that represents a single
/// relocation in the list of relocations in the object file.
@@ -94,34 +38,34 @@ class RelocationRef {
const ObjectFile *OwningObject;
public:
- RelocationRef() : OwningObject(NULL) { }
+ RelocationRef() : OwningObject(nullptr) { }
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
bool operator==(const RelocationRef &Other) const;
- error_code getNext(RelocationRef &Result) const;
+ void moveNext();
- error_code getAddress(uint64_t &Result) const;
- error_code getOffset(uint64_t &Result) const;
+ std::error_code getAddress(uint64_t &Result) const;
+ std::error_code getOffset(uint64_t &Result) const;
symbol_iterator getSymbol() const;
- error_code getType(uint64_t &Result) const;
+ std::error_code getType(uint64_t &Result) const;
/// @brief Indicates whether this relocation should hidden when listing
/// relocations, usually because it is the trailing part of a multipart
/// relocation that will be printed as part of the leading relocation.
- error_code getHidden(bool &Result) const;
+ std::error_code getHidden(bool &Result) const;
/// @brief Get a string that represents the type of this relocation.
///
/// This is for display purposes only.
- error_code getTypeName(SmallVectorImpl<char> &Result) const;
+ std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
/// @brief Get a string that represents the calculation of the value of this
/// relocation.
///
/// This is for display purposes only.
- error_code getValueString(SmallVectorImpl<char> &Result) const;
+ std::error_code getValueString(SmallVectorImpl<char> &Result) const;
DataRefImpl getRawDataRefImpl() const;
const ObjectFile *getObjectFile() const;
@@ -138,36 +82,41 @@ class SectionRef {
const ObjectFile *OwningObject;
public:
- SectionRef() : OwningObject(NULL) { }
+ SectionRef() : OwningObject(nullptr) { }
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
bool operator==(const SectionRef &Other) const;
+ bool operator!=(const SectionRef &Other) const;
bool operator<(const SectionRef &Other) const;
- error_code getNext(SectionRef &Result) const;
+ void moveNext();
- error_code getName(StringRef &Result) const;
- error_code getAddress(uint64_t &Result) const;
- error_code getSize(uint64_t &Result) const;
- error_code getContents(StringRef &Result) const;
+ std::error_code getName(StringRef &Result) const;
+ std::error_code getAddress(uint64_t &Result) const;
+ std::error_code getSize(uint64_t &Result) const;
+ std::error_code getContents(StringRef &Result) const;
/// @brief Get the alignment of this section as the actual value (not log 2).
- error_code getAlignment(uint64_t &Result) const;
+ std::error_code getAlignment(uint64_t &Result) const;
// FIXME: Move to the normalization layer when it's created.
- error_code isText(bool &Result) const;
- error_code isData(bool &Result) const;
- error_code isBSS(bool &Result) const;
- error_code isRequiredForExecution(bool &Result) const;
- error_code isVirtual(bool &Result) const;
- error_code isZeroInit(bool &Result) const;
- error_code isReadOnlyData(bool &Result) const;
-
- error_code containsSymbol(SymbolRef S, bool &Result) const;
-
- relocation_iterator begin_relocations() const;
- relocation_iterator end_relocations() const;
+ std::error_code isText(bool &Result) const;
+ std::error_code isData(bool &Result) const;
+ std::error_code isBSS(bool &Result) const;
+ std::error_code isRequiredForExecution(bool &Result) const;
+ std::error_code isVirtual(bool &Result) const;
+ std::error_code isZeroInit(bool &Result) const;
+ std::error_code isReadOnlyData(bool &Result) const;
+
+ std::error_code containsSymbol(SymbolRef S, bool &Result) const;
+
+ relocation_iterator relocation_begin() const;
+ relocation_iterator relocation_end() const;
+ iterator_range<relocation_iterator> relocations() const {
+ return iterator_range<relocation_iterator>(relocation_begin(),
+ relocation_end());
+ }
section_iterator getRelocatedSection() const;
DataRefImpl getRawDataRefImpl() const;
@@ -175,13 +124,11 @@ public:
/// SymbolRef - This is a value type class that represents a single symbol in
/// the list of symbols in the object file.
-class SymbolRef {
+class SymbolRef : public BasicSymbolRef {
friend class SectionRef;
- DataRefImpl SymbolPimpl;
- const ObjectFile *OwningObject;
public:
- SymbolRef() : OwningObject(NULL) { }
+ SymbolRef() : BasicSymbolRef() {}
enum Type {
ST_Unknown, // Type not specified
@@ -192,46 +139,41 @@ public:
ST_Other
};
- enum Flags LLVM_ENUM_INT_TYPE(unsigned) {
- SF_None = 0,
- SF_Undefined = 1U << 0, // Symbol is defined in another object file
- SF_Global = 1U << 1, // Global symbol
- SF_Weak = 1U << 2, // Weak symbol
- SF_Absolute = 1U << 3, // Absolute symbol
- SF_ThreadLocal = 1U << 4, // Thread local symbol
- SF_Common = 1U << 5, // Symbol has common linkage
- SF_FormatSpecific = 1U << 31 // Specific to the object file format
- // (e.g. section symbols)
- };
-
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
- bool operator==(const SymbolRef &Other) const;
- bool operator<(const SymbolRef &Other) const;
-
- error_code getNext(SymbolRef &Result) const;
-
- error_code getName(StringRef &Result) const;
+ std::error_code getName(StringRef &Result) const;
/// Returns the symbol virtual address (i.e. address at which it will be
/// mapped).
- error_code getAddress(uint64_t &Result) const;
- error_code getFileOffset(uint64_t &Result) const;
+ std::error_code getAddress(uint64_t &Result) const;
/// @brief Get the alignment of this symbol as the actual value (not log 2).
- error_code getAlignment(uint32_t &Result) const;
- error_code getSize(uint64_t &Result) const;
- error_code getType(SymbolRef::Type &Result) const;
-
- /// Get symbol flags (bitwise OR of SymbolRef::Flags)
- error_code getFlags(uint32_t &Result) const;
+ std::error_code getAlignment(uint32_t &Result) const;
+ std::error_code getSize(uint64_t &Result) const;
+ std::error_code getType(SymbolRef::Type &Result) const;
+ std::error_code getOther(uint8_t &Result) const;
/// @brief Get section this symbol is defined in reference to. Result is
/// end_sections() if it is undefined or is an absolute symbol.
- error_code getSection(section_iterator &Result) const;
+ std::error_code getSection(section_iterator &Result) const;
- /// @brief Get value of the symbol in the symbol table.
- error_code getValue(uint64_t &Val) const;
+ const ObjectFile *getObject() const;
+};
- DataRefImpl getRawDataRefImpl() const;
+class symbol_iterator : public basic_symbol_iterator {
+public:
+ symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
+ symbol_iterator(const basic_symbol_iterator &B)
+ : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+ cast<ObjectFile>(B->getObject()))) {}
+
+ const SymbolRef *operator->() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef*>(&P);
+ }
+
+ const SymbolRef &operator*() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef&>(P);
+ }
};
/// LibraryRef - This is a value type class that represents a single library in
@@ -242,34 +184,32 @@ class LibraryRef {
const ObjectFile *OwningObject;
public:
- LibraryRef() : OwningObject(NULL) { }
+ LibraryRef() : OwningObject(nullptr) { }
LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
bool operator==(const LibraryRef &Other) const;
bool operator<(const LibraryRef &Other) const;
- error_code getNext(LibraryRef &Result) const;
+ std::error_code getNext(LibraryRef &Result) const;
// Get the path to this library, as stored in the object file.
- error_code getPath(StringRef &Result) const;
+ std::error_code getPath(StringRef &Result) const;
DataRefImpl getRawDataRefImpl() const;
};
typedef content_iterator<LibraryRef> library_iterator;
-const uint64_t UnknownAddressOrSize = ~0ULL;
-
/// ObjectFile - This class is the base class for all object file types.
/// Concrete instances of this object are created by createObjectFile, which
/// figures out which type to create.
-class ObjectFile : public Binary {
+class ObjectFile : public SymbolicFile {
virtual void anchor();
ObjectFile() LLVM_DELETED_FUNCTION;
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected:
- ObjectFile(unsigned int Type, MemoryBuffer *source);
+ ObjectFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
@@ -284,81 +224,102 @@ protected:
// Implementations assume that the DataRefImpl is valid and has not been
// modified externally. It's UB otherwise.
friend class SymbolRef;
- virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
- virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
- virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0;
- virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
- virtual error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const = 0;
- virtual error_code getSymbolFlags(DataRefImpl Symb,
- uint32_t &Res) const = 0;
- virtual error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const = 0;
- virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0;
+ virtual std::error_code getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const = 0;
+ std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
+ virtual std::error_code getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSymbolAlignment(DataRefImpl Symb,
+ uint32_t &Res) const;
+ virtual std::error_code getSymbolSize(DataRefImpl Symb,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const = 0;
+ virtual std::error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const = 0;
+ virtual std::error_code getSymbolOther(DataRefImpl Symb,
+ uint8_t &Res) const {
+ return object_error::invalid_file_type;
+ }
// Same as above for SectionRef.
friend class SectionRef;
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
- virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
- virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
- virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
- virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0;
- virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Res) const = 0;
+ virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
+ virtual std::error_code getSectionName(DataRefImpl Sec,
+ StringRef &Res) const = 0;
+ virtual std::error_code getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSectionSize(DataRefImpl Sec,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const = 0;
+ virtual std::error_code getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const = 0;
+ virtual std::error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
+ virtual std::error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
+ virtual std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
+ virtual std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const = 0;
// A section is 'virtual' if its contents aren't present in the object image.
- virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0;
- virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const = 0;
+ virtual std::error_code isSectionVirtual(DataRefImpl Sec,
+ bool &Res) const = 0;
+ virtual std::error_code isSectionZeroInit(DataRefImpl Sec,
+ bool &Res) const = 0;
+ virtual std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Res) const = 0;
+ virtual std::error_code sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const = 0;
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;
// Same as above for RelocationRef.
friend class RelocationRef;
- virtual error_code getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const = 0;
- virtual error_code getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const =0;
- virtual error_code getRelocationOffset(DataRefImpl Rel,
- uint64_t &Res) const =0;
+ virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
+ virtual std::error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
+ virtual std::error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
- virtual error_code getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const = 0;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const = 0;
- virtual error_code getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const = 0;
- virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const {
+ virtual std::error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
+ virtual std::error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+ virtual std::error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+ virtual std::error_code getRelocationHidden(DataRefImpl Rel,
+ bool &Result) const {
Result = false;
return object_error::success;
}
// Same for LibraryRef
friend class LibraryRef;
- virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
- virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
+ virtual std::error_code getLibraryNext(DataRefImpl Lib,
+ LibraryRef &Res) const = 0;
+ virtual std::error_code getLibraryPath(DataRefImpl Lib,
+ StringRef &Res) const = 0;
public:
+ typedef iterator_range<symbol_iterator> symbol_iterator_range;
+ symbol_iterator_range symbols() const {
+ return symbol_iterator_range(symbol_begin(), symbol_end());
+ }
- virtual symbol_iterator begin_symbols() const = 0;
- virtual symbol_iterator end_symbols() const = 0;
-
- virtual symbol_iterator begin_dynamic_symbols() const = 0;
- virtual symbol_iterator end_dynamic_symbols() const = 0;
+ virtual section_iterator section_begin() const = 0;
+ virtual section_iterator section_end() const = 0;
- virtual section_iterator begin_sections() const = 0;
- virtual section_iterator end_sections() const = 0;
+ typedef iterator_range<section_iterator> section_iterator_range;
+ section_iterator_range sections() const {
+ return section_iterator_range(section_begin(), section_end());
+ }
- virtual library_iterator begin_libraries_needed() const = 0;
- virtual library_iterator end_libraries_needed() const = 0;
+ virtual library_iterator needed_library_begin() const = 0;
+ virtual library_iterator needed_library_end() const = 0;
/// @brief The number of bytes used to represent an address in this object
/// file format.
@@ -372,78 +333,74 @@ public:
/// LC_ID_DYLIB (install name) on MachO.
virtual StringRef getLoadName() const = 0;
+ /// Returns platform-specific object flags, if any.
+ virtual std::error_code getPlatformFlags(unsigned &Result) const {
+ Result = 0;
+ return object_error::invalid_file_type;
+ }
+
/// @returns Pointer to ObjectFile subclass to handle this type of object.
/// @param ObjectPath The path to the object file. ObjectPath.isObject must
/// return true.
/// @brief Create ObjectFile from path.
- static ObjectFile *createObjectFile(StringRef ObjectPath);
- static ObjectFile *createObjectFile(MemoryBuffer *Object);
+ static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
+ static ErrorOr<ObjectFile *>
+ createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
+ sys::fs::file_magic Type);
+ static ErrorOr<ObjectFile *>
+ createObjectFile(std::unique_ptr<MemoryBuffer> &Object) {
+ return createObjectFile(Object, sys::fs::file_magic::unknown);
+ }
+
static inline bool classof(const Binary *v) {
return v->isObject();
}
public:
- static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
- static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
- static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
+ static ErrorOr<ObjectFile *>
+ createCOFFObjectFile(std::unique_ptr<MemoryBuffer> Object);
+ static ErrorOr<ObjectFile *>
+ createELFObjectFile(std::unique_ptr<MemoryBuffer> &Object);
+ static ErrorOr<ObjectFile *>
+ createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Object);
};
// Inline function definitions.
inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
- : SymbolPimpl(SymbolP)
- , OwningObject(Owner) {}
-
-inline bool SymbolRef::operator==(const SymbolRef &Other) const {
- return SymbolPimpl == Other.SymbolPimpl;
-}
+ : BasicSymbolRef(SymbolP, Owner) {}
-inline bool SymbolRef::operator<(const SymbolRef &Other) const {
- return SymbolPimpl < Other.SymbolPimpl;
+inline std::error_code SymbolRef::getName(StringRef &Result) const {
+ return getObject()->getSymbolName(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getNext(SymbolRef &Result) const {
- return OwningObject->getSymbolNext(SymbolPimpl, Result);
+inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
+ return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getName(StringRef &Result) const {
- return OwningObject->getSymbolName(SymbolPimpl, Result);
+inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const {
+ return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getAddress(uint64_t &Result) const {
- return OwningObject->getSymbolAddress(SymbolPimpl, Result);
+inline std::error_code SymbolRef::getSize(uint64_t &Result) const {
+ return getObject()->getSymbolSize(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
- return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
+inline std::error_code SymbolRef::getSection(section_iterator &Result) const {
+ return getObject()->getSymbolSection(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getAlignment(uint32_t &Result) const {
- return OwningObject->getSymbolAlignment(SymbolPimpl, Result);
+inline std::error_code SymbolRef::getType(SymbolRef::Type &Result) const {
+ return getObject()->getSymbolType(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getSize(uint64_t &Result) const {
- return OwningObject->getSymbolSize(SymbolPimpl, Result);
+inline std::error_code SymbolRef::getOther(uint8_t &Result) const {
+ return getObject()->getSymbolOther(getRawDataRefImpl(), Result);
}
-inline error_code SymbolRef::getFlags(uint32_t &Result) const {
- return OwningObject->getSymbolFlags(SymbolPimpl, Result);
-}
-
-inline error_code SymbolRef::getSection(section_iterator &Result) const {
- return OwningObject->getSymbolSection(SymbolPimpl, Result);
-}
-
-inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
- return OwningObject->getSymbolType(SymbolPimpl, Result);
-}
-
-inline error_code SymbolRef::getValue(uint64_t &Val) const {
- return OwningObject->getSymbolValue(SymbolPimpl, Val);
-}
-
-inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
- return SymbolPimpl;
+inline const ObjectFile *SymbolRef::getObject() const {
+ const SymbolicFile *O = BasicSymbolRef::getObject();
+ return cast<ObjectFile>(O);
}
@@ -457,72 +414,77 @@ inline bool SectionRef::operator==(const SectionRef &Other) const {
return SectionPimpl == Other.SectionPimpl;
}
+inline bool SectionRef::operator!=(const SectionRef &Other) const {
+ return SectionPimpl != Other.SectionPimpl;
+}
+
inline bool SectionRef::operator<(const SectionRef &Other) const {
return SectionPimpl < Other.SectionPimpl;
}
-inline error_code SectionRef::getNext(SectionRef &Result) const {
- return OwningObject->getSectionNext(SectionPimpl, Result);
+inline void SectionRef::moveNext() {
+ return OwningObject->moveSectionNext(SectionPimpl);
}
-inline error_code SectionRef::getName(StringRef &Result) const {
+inline std::error_code SectionRef::getName(StringRef &Result) const {
return OwningObject->getSectionName(SectionPimpl, Result);
}
-inline error_code SectionRef::getAddress(uint64_t &Result) const {
+inline std::error_code SectionRef::getAddress(uint64_t &Result) const {
return OwningObject->getSectionAddress(SectionPimpl, Result);
}
-inline error_code SectionRef::getSize(uint64_t &Result) const {
+inline std::error_code SectionRef::getSize(uint64_t &Result) const {
return OwningObject->getSectionSize(SectionPimpl, Result);
}
-inline error_code SectionRef::getContents(StringRef &Result) const {
+inline std::error_code SectionRef::getContents(StringRef &Result) const {
return OwningObject->getSectionContents(SectionPimpl, Result);
}
-inline error_code SectionRef::getAlignment(uint64_t &Result) const {
+inline std::error_code SectionRef::getAlignment(uint64_t &Result) const {
return OwningObject->getSectionAlignment(SectionPimpl, Result);
}
-inline error_code SectionRef::isText(bool &Result) const {
+inline std::error_code SectionRef::isText(bool &Result) const {
return OwningObject->isSectionText(SectionPimpl, Result);
}
-inline error_code SectionRef::isData(bool &Result) const {
+inline std::error_code SectionRef::isData(bool &Result) const {
return OwningObject->isSectionData(SectionPimpl, Result);
}
-inline error_code SectionRef::isBSS(bool &Result) const {
+inline std::error_code SectionRef::isBSS(bool &Result) const {
return OwningObject->isSectionBSS(SectionPimpl, Result);
}
-inline error_code SectionRef::isRequiredForExecution(bool &Result) const {
+inline std::error_code SectionRef::isRequiredForExecution(bool &Result) const {
return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result);
}
-inline error_code SectionRef::isVirtual(bool &Result) const {
+inline std::error_code SectionRef::isVirtual(bool &Result) const {
return OwningObject->isSectionVirtual(SectionPimpl, Result);
}
-inline error_code SectionRef::isZeroInit(bool &Result) const {
+inline std::error_code SectionRef::isZeroInit(bool &Result) const {
return OwningObject->isSectionZeroInit(SectionPimpl, Result);
}
-inline error_code SectionRef::isReadOnlyData(bool &Result) const {
+inline std::error_code SectionRef::isReadOnlyData(bool &Result) const {
return OwningObject->isSectionReadOnlyData(SectionPimpl, Result);
}
-inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
- return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
- Result);
+inline std::error_code SectionRef::containsSymbol(SymbolRef S,
+ bool &Result) const {
+ return OwningObject->sectionContainsSymbol(SectionPimpl,
+ S.getRawDataRefImpl(), Result);
}
-inline relocation_iterator SectionRef::begin_relocations() const {
+inline relocation_iterator SectionRef::relocation_begin() const {
return OwningObject->section_rel_begin(SectionPimpl);
}
-inline relocation_iterator SectionRef::end_relocations() const {
+inline relocation_iterator SectionRef::relocation_end() const {
return OwningObject->section_rel_end(SectionPimpl);
}
@@ -544,15 +506,15 @@ inline bool RelocationRef::operator==(const RelocationRef &Other) const {
return RelocationPimpl == Other.RelocationPimpl;
}
-inline error_code RelocationRef::getNext(RelocationRef &Result) const {
- return OwningObject->getRelocationNext(RelocationPimpl, Result);
+inline void RelocationRef::moveNext() {
+ return OwningObject->moveRelocationNext(RelocationPimpl);
}
-inline error_code RelocationRef::getAddress(uint64_t &Result) const {
+inline std::error_code RelocationRef::getAddress(uint64_t &Result) const {
return OwningObject->getRelocationAddress(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getOffset(uint64_t &Result) const {
+inline std::error_code RelocationRef::getOffset(uint64_t &Result) const {
return OwningObject->getRelocationOffset(RelocationPimpl, Result);
}
@@ -560,21 +522,21 @@ inline symbol_iterator RelocationRef::getSymbol() const {
return OwningObject->getRelocationSymbol(RelocationPimpl);
}
-inline error_code RelocationRef::getType(uint64_t &Result) const {
+inline std::error_code RelocationRef::getType(uint64_t &Result) const {
return OwningObject->getRelocationType(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result)
- const {
+inline std::error_code
+RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
- const {
+inline std::error_code
+RelocationRef::getValueString(SmallVectorImpl<char> &Result) const {
return OwningObject->getRelocationValueString(RelocationPimpl, Result);
}
-inline error_code RelocationRef::getHidden(bool &Result) const {
+inline std::error_code RelocationRef::getHidden(bool &Result) const {
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
}
@@ -599,11 +561,11 @@ inline bool LibraryRef::operator<(const LibraryRef &Other) const {
return LibraryPimpl < Other.LibraryPimpl;
}
-inline error_code LibraryRef::getNext(LibraryRef &Result) const {
+inline std::error_code LibraryRef::getNext(LibraryRef &Result) const {
return OwningObject->getLibraryNext(LibraryPimpl, Result);
}
-inline error_code LibraryRef::getPath(StringRef &Result) const {
+inline std::error_code LibraryRef::getPath(StringRef &Result) const {
return OwningObject->getLibraryPath(LibraryPimpl, Result);
}
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 97912fe52d81..5ca245057a55 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -17,8 +17,8 @@
#define LLVM_OBJECT_RELOCVISITOR_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
@@ -33,7 +33,6 @@ struct RelocToApply {
// The width of the value; how many bytes to touch when applying the
// relocation.
char Width;
- RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) {}
RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
RelocToApply() : Value(0), Width(0) {}
};
@@ -103,6 +102,16 @@ public:
HasError = true;
return RelocToApply();
}
+ } else if (FileFormat == "ELF64-mips") {
+ switch (RelocType) {
+ case llvm::ELF::R_MIPS_32:
+ return visitELF_MIPS_32(R, Value);
+ case llvm::ELF::R_MIPS_64:
+ return visitELF_MIPS_64(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
} else if (FileFormat == "ELF64-aarch64") {
switch (RelocType) {
case llvm::ELF::R_AARCH64_ABS32:
@@ -123,6 +132,35 @@ public:
HasError = true;
return RelocToApply();
}
+ } else if (FileFormat == "ELF32-sparc") {
+ switch (RelocType) {
+ case llvm::ELF::R_SPARC_32:
+ case llvm::ELF::R_SPARC_UA32:
+ return visitELF_SPARC_32(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF64-sparc") {
+ switch (RelocType) {
+ case llvm::ELF::R_SPARC_32:
+ case llvm::ELF::R_SPARC_UA32:
+ return visitELF_SPARCV9_32(R, Value);
+ case llvm::ELF::R_SPARC_64:
+ case llvm::ELF::R_SPARC_UA64:
+ return visitELF_SPARCV9_64(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF32-arm") {
+ switch (RelocType) {
+ default:
+ HasError = true;
+ return RelocToApply();
+ case llvm::ELF::R_ARM_ABS32:
+ return visitELF_ARM_ABS32(R, Value);
+ }
}
HasError = true;
return RelocToApply();
@@ -215,12 +253,14 @@ private:
/// PPC64 ELF
RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) {
- int64_t Addend = getAddend64BE(R);
+ int64_t Addend;
+ getELFRelocationAddend(R, Addend);
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
return RelocToApply(Res, 4);
}
RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) {
- int64_t Addend = getAddend64BE(R);
+ int64_t Addend;
+ getELFRelocationAddend(R, Addend);
return RelocToApply(Value + Addend, 8);
}
@@ -239,6 +279,13 @@ private:
return RelocToApply(Res, 4);
}
+ RelocToApply visitELF_MIPS_64(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ getELFRelocationAddend(R, Addend);
+ uint64_t Res = (Value + Addend);
+ return RelocToApply(Res, 8);
+ }
+
// AArch64 ELF
RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) {
int64_t Addend = getAddend64LE(R);
@@ -272,6 +319,27 @@ private:
int64_t Addend = getAddend64BE(R);
return RelocToApply(Value + Addend, 8);
}
+
+ RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
+ int32_t Addend = getAddend32BE(R);
+ return RelocToApply(Value + Addend, 4);
+ }
+
+ RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
+ int32_t Addend = getAddend64BE(R);
+ return RelocToApply(Value + Addend, 4);
+ }
+
+ RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getAddend64BE(R);
+ return RelocToApply(Value + Addend, 8);
+ }
+
+ RelocToApply visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getAddend32LE(R);
+ return RelocToApply(Value + Addend, 4);
+ }
+
};
}
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
new file mode 100644
index 000000000000..77eef4a546aa
--- /dev/null
+++ b/include/llvm/Object/SymbolicFile.h
@@ -0,0 +1,195 @@
+//===- SymbolicFile.h - Interface that only provides symbols ----*- 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 the SymbolicFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLIC_FILE_H
+#define LLVM_OBJECT_SYMBOLIC_FILE_H
+
+#include "llvm/Object/Binary.h"
+
+namespace llvm {
+namespace object {
+
+union DataRefImpl {
+ // This entire union should probably be a
+ // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
+ struct {
+ uint32_t a, b;
+ } d;
+ uintptr_t p;
+ DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
+};
+
+inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
+}
+
+inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
+ return !operator==(a, b);
+}
+
+inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
+}
+
+template <class content_type> class content_iterator {
+ content_type Current;
+
+public:
+ content_iterator(content_type symb) : Current(symb) {}
+
+ const content_type *operator->() const { return &Current; }
+
+ const content_type &operator*() const { return Current; }
+
+ bool operator==(const content_iterator &other) const {
+ return Current == other.Current;
+ }
+
+ bool operator!=(const content_iterator &other) const {
+ return !(*this == other);
+ }
+
+ content_iterator &operator++() { // preincrement
+ Current.moveNext();
+ return *this;
+ }
+};
+
+class SymbolicFile;
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class BasicSymbolRef {
+ DataRefImpl SymbolPimpl;
+ const SymbolicFile *OwningObject;
+
+public:
+ // FIXME: should we add a SF_Text?
+ enum Flags : unsigned {
+ SF_None = 0,
+ SF_Undefined = 1U << 0, // Symbol is defined in another object file
+ SF_Global = 1U << 1, // Global symbol
+ SF_Weak = 1U << 2, // Weak symbol
+ SF_Absolute = 1U << 3, // Absolute symbol
+ SF_Common = 1U << 4, // Symbol has common linkage
+ SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
+ SF_FormatSpecific = 1U << 6 // Specific to the object file format
+ // (e.g. section symbols)
+ };
+
+ BasicSymbolRef() : OwningObject(nullptr) { }
+ BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
+
+ bool operator==(const BasicSymbolRef &Other) const;
+ bool operator<(const BasicSymbolRef &Other) const;
+
+ void moveNext();
+
+ std::error_code printName(raw_ostream &OS) const;
+
+ /// Get symbol flags (bitwise OR of SymbolRef::Flags)
+ uint32_t getFlags() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const SymbolicFile *getObject() const;
+};
+
+typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
+
+const uint64_t UnknownAddressOrSize = ~0ULL;
+
+class SymbolicFile : public Binary {
+public:
+ virtual ~SymbolicFile();
+ SymbolicFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
+
+ // virtual interface.
+ virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
+
+ virtual std::error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const = 0;
+
+ virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
+
+ virtual basic_symbol_iterator symbol_begin_impl() const = 0;
+
+ virtual basic_symbol_iterator symbol_end_impl() const = 0;
+
+ // convenience wrappers.
+ basic_symbol_iterator symbol_begin() const {
+ return symbol_begin_impl();
+ }
+ basic_symbol_iterator symbol_end() const {
+ return symbol_end_impl();
+ }
+ typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range;
+ basic_symbol_iterator_range symbols() const {
+ return basic_symbol_iterator_range(symbol_begin(), symbol_end());
+ }
+
+ // construction aux.
+ static ErrorOr<SymbolicFile *>
+ createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
+ sys::fs::file_magic Type, LLVMContext *Context);
+
+ static ErrorOr<SymbolicFile *>
+ createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) {
+ return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
+ }
+ static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
+
+ static inline bool classof(const Binary *v) {
+ return v->isSymbolic();
+ }
+};
+
+inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
+ const SymbolicFile *Owner)
+ : SymbolPimpl(SymbolP), OwningObject(Owner) {}
+
+inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
+ return SymbolPimpl == Other.SymbolPimpl;
+}
+
+inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
+ return SymbolPimpl < Other.SymbolPimpl;
+}
+
+inline void BasicSymbolRef::moveNext() {
+ return OwningObject->moveSymbolNext(SymbolPimpl);
+}
+
+inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
+ return OwningObject->printSymbolName(OS, SymbolPimpl);
+}
+
+inline uint32_t BasicSymbolRef::getFlags() const {
+ return OwningObject->getSymbolFlags(SymbolPimpl);
+}
+
+inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
+ return SymbolPimpl;
+}
+
+inline const SymbolicFile *BasicSymbolRef::getObject() const {
+ return OwningObject;
+}
+
+}
+}
+
+#endif
diff --git a/include/llvm/Object/YAML.h b/include/llvm/Object/YAML.h
deleted file mode 100644
index 89fe5047a86e..000000000000
--- a/include/llvm/Object/YAML.h
+++ /dev/null
@@ -1,116 +0,0 @@
-//===- YAML.h - YAMLIO utilities for object files ---------------*- 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 utility classes for handling the YAML representation of
-// object files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_YAML_H
-#define LLVM_OBJECT_YAML_H
-
-#include "llvm/Support/YAMLTraits.h"
-
-namespace llvm {
-namespace object {
-namespace yaml {
-
-/// \brief Specialized YAMLIO scalar type for representing a binary blob.
-///
-/// A typical use case would be to represent the content of a section in a
-/// binary file.
-/// This class has custom YAMLIO traits for convenient reading and writing.
-/// It renders as a string of hex digits in a YAML file.
-/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not
-/// require the quotation marks, so for simplicity when outputting they are
-/// omitted).
-/// When reading, any string whose content is an even number of hex digits
-/// will be accepted.
-/// For example, all of the following are acceptable:
-/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D')
-///
-/// A significant advantage of using this class is that it never allocates
-/// temporary strings or buffers for any of its functionality.
-///
-/// Example:
-///
-/// The YAML mapping:
-/// \code
-/// Foo: DEADBEEFCAFEBABE
-/// \endcode
-///
-/// Could be modeled in YAMLIO by the struct:
-/// \code
-/// struct FooHolder {
-/// BinaryRef Foo;
-/// };
-/// namespace llvm {
-/// namespace yaml {
-/// template <>
-/// struct MappingTraits<FooHolder> {
-/// static void mapping(IO &IO, FooHolder &FH) {
-/// IO.mapRequired("Foo", FH.Foo);
-/// }
-/// };
-/// } // end namespace yaml
-/// } // end namespace llvm
-/// \endcode
-class BinaryRef {
- friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS);
- /// \brief Either raw binary data, or a string of hex bytes (must always
- /// be an even number of characters).
- ArrayRef<uint8_t> Data;
- /// \brief Discriminator between the two states of the `Data` member.
- bool DataIsHexString;
-
-public:
- BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
- BinaryRef(StringRef Data)
- : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
- DataIsHexString(true) {}
- BinaryRef() : DataIsHexString(true) {}
- /// \brief The number of bytes that are represented by this BinaryRef.
- /// This is the number of bytes that writeAsBinary() will write.
- ArrayRef<uint8_t>::size_type binary_size() const {
- if (DataIsHexString)
- return Data.size() / 2;
- return Data.size();
- }
- /// \brief Write the contents (regardless of whether it is binary or a
- /// hex string) as binary to the given raw_ostream.
- void writeAsBinary(raw_ostream &OS) const;
- /// \brief Write the contents (regardless of whether it is binary or a
- /// hex string) as hex to the given raw_ostream.
- ///
- /// For example, a possible output could be `DEADBEEFCAFEBABE`.
- void writeAsHex(raw_ostream &OS) const;
-};
-
-inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
- // Special case for default constructed BinaryRef.
- if (LHS.Data.empty() && RHS.Data.empty())
- return true;
-
- return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data;
-}
-
-}
-}
-
-namespace yaml {
-template <> struct ScalarTraits<object::yaml::BinaryRef> {
- static void output(const object::yaml::BinaryRef &, void *,
- llvm::raw_ostream &);
- static StringRef input(StringRef, void *, object::yaml::BinaryRef &);
-};
-}
-
-}
-
-#endif