summaryrefslogtreecommitdiffstats
path: root/lib/Object
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /lib/Object
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'lib/Object')
-rw-r--r--lib/Object/Android.mk6
-rw-r--r--lib/Object/Archive.cpp71
-rw-r--r--lib/Object/Binary.cpp85
-rw-r--r--lib/Object/CMakeLists.txt2
-rw-r--r--lib/Object/COFFObjectFile.cpp885
-rw-r--r--lib/Object/COFFYAML.cpp105
-rw-r--r--lib/Object/ELF.cpp94
-rw-r--r--lib/Object/ELFObjectFile.cpp44
-rw-r--r--lib/Object/ELFYAML.cpp43
-rw-r--r--lib/Object/Error.cpp8
-rw-r--r--lib/Object/IRObjectFile.cpp151
-rw-r--r--lib/Object/LLVMBuild.txt2
-rw-r--r--lib/Object/MachOObjectFile.cpp232
-rw-r--r--lib/Object/MachOUniversal.cpp27
-rw-r--r--lib/Object/Object.cpp31
-rw-r--r--lib/Object/ObjectFile.cpp47
-rw-r--r--lib/Object/SymbolicFile.cpp67
-rw-r--r--lib/Object/YAML.cpp4
18 files changed, 1255 insertions, 649 deletions
diff --git a/lib/Object/Android.mk b/lib/Object/Android.mk
index 93b5434..7dfa44f 100644
--- a/lib/Object/Android.mk
+++ b/lib/Object/Android.mk
@@ -7,10 +7,12 @@ object_SRC_FILES := \
ELF.cpp \
ELFObjectFile.cpp \
Error.cpp \
+ IRObjectFile.cpp \
MachOObjectFile.cpp \
MachOUniversal.cpp \
Object.cpp \
- ObjectFile.cpp
+ ObjectFile.cpp \
+ SymbolicFile.cpp
# For the host
@@ -29,6 +31,7 @@ include $(BUILD_HOST_STATIC_LIBRARY)
# For the device only
# =====================================================
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
include $(CLEAR_VARS)
LOCAL_MODULE:= libLLVMObject
@@ -39,3 +42,4 @@ LOCAL_SRC_FILES := $(object_SRC_FILES)
include $(LLVM_DEVICE_BUILD_MK)
include $(LLVM_GEN_INTRINSICS_MK)
include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp
index 71efca2..999bf28 100644
--- a/lib/Object/Archive.cpp
+++ b/lib/Object/Archive.cpp
@@ -13,6 +13,7 @@
#include "llvm/Object/Archive.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Endian.h"
@@ -136,7 +137,7 @@ error_code Archive::Child::getName(StringRef &Result) const {
+ sizeof(ArchiveMemberHeader)
+ offset;
// Verify it.
- if (Parent->StringTable == Parent->end_children()
+ if (Parent->StringTable == Parent->child_end()
|| addr < (Parent->StringTable->Data.begin()
+ sizeof(ArchiveMemberHeader))
|| addr > (Parent->StringTable->Data.begin()
@@ -168,7 +169,7 @@ error_code Archive::Child::getName(StringRef &Result) const {
return object_error::success;
}
-error_code Archive::Child::getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
+error_code Archive::Child::getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
bool FullPath) const {
StringRef Name;
if (error_code ec = getName(Name))
@@ -182,19 +183,45 @@ error_code Archive::Child::getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
return error_code::success();
}
-error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const {
- OwningPtr<Binary> ret;
- OwningPtr<MemoryBuffer> Buff;
+error_code Archive::Child::getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
+ bool FullPath) const {
+ std::unique_ptr<MemoryBuffer> MB;
+ error_code ec = getMemoryBuffer(MB, FullPath);
+ Result = std::move(MB);
+ return ec;
+}
+
+error_code Archive::Child::getAsBinary(std::unique_ptr<Binary> &Result,
+ LLVMContext *Context) const {
+ std::unique_ptr<Binary> ret;
+ std::unique_ptr<MemoryBuffer> Buff;
if (error_code ec = getMemoryBuffer(Buff))
return ec;
- if (error_code ec = createBinary(Buff.take(), ret))
- return ec;
- Result.swap(ret);
+ ErrorOr<Binary *> BinaryOrErr = createBinary(Buff.release(), Context);
+ if (error_code EC = BinaryOrErr.getError())
+ return EC;
+ Result.reset(BinaryOrErr.get());
return object_error::success;
}
+error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result,
+ LLVMContext *Context) const {
+ std::unique_ptr<Binary> B;
+ error_code ec = getAsBinary(B, Context);
+ Result = std::move(B);
+ return ec;
+}
+
+ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
+ error_code EC;
+ std::unique_ptr<Archive> Ret(new Archive(Source, EC));
+ if (EC)
+ return EC;
+ return Ret.release();
+}
+
Archive::Archive(MemoryBuffer *source, error_code &ec)
- : Binary(Binary::ID_Archive, source), SymbolTable(end_children()) {
+ : Binary(Binary::ID_Archive, source), SymbolTable(child_end()) {
// Check for sufficient magic.
assert(source);
if (source->getBufferSize() < 8 ||
@@ -204,8 +231,8 @@ Archive::Archive(MemoryBuffer *source, error_code &ec)
}
// Get the special members.
- child_iterator i = begin_children(false);
- child_iterator e = end_children();
+ child_iterator i = child_begin(false);
+ child_iterator e = child_end();
if (i == e) {
ec = object_error::success;
@@ -309,9 +336,9 @@ Archive::Archive(MemoryBuffer *source, error_code &ec)
ec = object_error::success;
}
-Archive::child_iterator Archive::begin_children(bool SkipInternal) const {
+Archive::child_iterator Archive::child_begin(bool SkipInternal) const {
if (Data->getBufferSize() == 8) // empty archive.
- return end_children();
+ return child_end();
if (SkipInternal)
return FirstRegular;
@@ -321,7 +348,7 @@ Archive::child_iterator Archive::begin_children(bool SkipInternal) const {
return c;
}
-Archive::child_iterator Archive::end_children() const {
+Archive::child_iterator Archive::child_end() const {
return Child(this, NULL);
}
@@ -384,7 +411,7 @@ Archive::Symbol Archive::Symbol::getNext() const {
return t;
}
-Archive::symbol_iterator Archive::begin_symbols() const {
+Archive::symbol_iterator Archive::symbol_begin() const {
if (!hasSymbolTable())
return symbol_iterator(Symbol(this, 0, 0));
@@ -407,7 +434,7 @@ Archive::symbol_iterator Archive::begin_symbols() const {
return symbol_iterator(Symbol(this, 0, string_start_offset));
}
-Archive::symbol_iterator Archive::end_symbols() const {
+Archive::symbol_iterator Archive::symbol_end() const {
if (!hasSymbolTable())
return symbol_iterator(Symbol(this, 0, 0));
@@ -428,23 +455,23 @@ Archive::symbol_iterator Archive::end_symbols() const {
}
Archive::child_iterator Archive::findSym(StringRef name) const {
- Archive::symbol_iterator bs = begin_symbols();
- Archive::symbol_iterator es = end_symbols();
+ Archive::symbol_iterator bs = symbol_begin();
+ Archive::symbol_iterator es = symbol_end();
Archive::child_iterator result;
StringRef symname;
for (; bs != es; ++bs) {
if (bs->getName(symname))
- return end_children();
+ return child_end();
if (symname == name) {
if (bs->getMember(result))
- return end_children();
+ return child_end();
return result;
}
}
- return end_children();
+ return child_end();
}
bool Archive::hasSymbolTable() const {
- return SymbolTable != end_children();
+ return SymbolTable != child_end();
}
diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp
index de57b4c..63fd3ed 100644
--- a/lib/Object/Binary.cpp
+++ b/lib/Object/Binary.cpp
@@ -13,13 +13,12 @@
#include "llvm/Object/Binary.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
// Include headers for createBinary.
#include "llvm/Object/Archive.h"
-#include "llvm/Object/COFF.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
@@ -27,12 +26,12 @@ using namespace llvm;
using namespace object;
Binary::~Binary() {
- delete Data;
+ if (BufferOwned)
+ delete Data;
}
-Binary::Binary(unsigned int Type, MemoryBuffer *Source)
- : TypeID(Type)
- , Data(Source) {}
+Binary::Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned)
+ : TypeID(Type), BufferOwned(BufferOwned), Data(Source) {}
StringRef Binary::getData() const {
return Data->getBuffer();
@@ -42,31 +41,18 @@ StringRef Binary::getFileName() const {
return Data->getBufferIdentifier();
}
-error_code object::createBinary(MemoryBuffer *Source,
- OwningPtr<Binary> &Result) {
- OwningPtr<MemoryBuffer> scopedSource(Source);
- if (!Source)
- return make_error_code(errc::invalid_argument);
- sys::fs::file_magic type = sys::fs::identify_magic(Source->getBuffer());
- error_code ec;
- switch (type) {
- case sys::fs::file_magic::archive: {
- OwningPtr<Binary> ret(new Archive(scopedSource.take(), ec));
- if (ec) return ec;
- Result.swap(ret);
- return object_error::success;
- }
+ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
+ LLVMContext *Context) {
+ std::unique_ptr<MemoryBuffer> scopedSource(Source);
+ sys::fs::file_magic Type = sys::fs::identify_magic(Source->getBuffer());
+
+ switch (Type) {
+ case sys::fs::file_magic::archive:
+ return Archive::create(scopedSource.release());
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
- case sys::fs::file_magic::elf_core: {
- OwningPtr<Binary> ret(
- ObjectFile::createELFObjectFile(scopedSource.take()));
- if (!ret)
- return object_error::invalid_file_type;
- Result.swap(ret);
- return object_error::success;
- }
+ case sys::fs::file_magic::elf_core:
case sys::fs::file_magic::macho_object:
case sys::fs::file_magic::macho_executable:
case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
@@ -76,43 +62,26 @@ error_code object::createBinary(MemoryBuffer *Source,
case sys::fs::file_magic::macho_dynamic_linker:
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
- case sys::fs::file_magic::macho_dsym_companion: {
- OwningPtr<Binary> ret(
- ObjectFile::createMachOObjectFile(scopedSource.take()));
- if (!ret)
- return object_error::invalid_file_type;
- Result.swap(ret);
- return object_error::success;
- }
- case sys::fs::file_magic::macho_universal_binary: {
- OwningPtr<Binary> ret(new MachOUniversalBinary(scopedSource.take(), ec));
- if (ec) return ec;
- Result.swap(ret);
- return object_error::success;
- }
+ case sys::fs::file_magic::macho_dsym_companion:
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
- case sys::fs::file_magic::pecoff_executable: {
- OwningPtr<Binary> ret(
- ObjectFile::createCOFFObjectFile(scopedSource.take()));
- if (!ret)
- return object_error::invalid_file_type;
- Result.swap(ret);
- return object_error::success;
- }
- case sys::fs::file_magic::unknown:
+ case sys::fs::file_magic::pecoff_executable:
case sys::fs::file_magic::bitcode:
- case sys::fs::file_magic::windows_resource: {
+ return ObjectFile::createSymbolicFile(scopedSource.release(), true, Type,
+ Context);
+ case sys::fs::file_magic::macho_universal_binary:
+ return MachOUniversalBinary::create(scopedSource.release());
+ case sys::fs::file_magic::unknown:
+ case sys::fs::file_magic::windows_resource:
// Unrecognized object file format.
return object_error::invalid_file_type;
- }
}
llvm_unreachable("Unexpected Binary File Type");
}
-error_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) {
- OwningPtr<MemoryBuffer> File;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(Path, File))
- return ec;
- return createBinary(File.take(), Result);
+ErrorOr<Binary *> object::createBinary(StringRef Path) {
+ std::unique_ptr<MemoryBuffer> File;
+ if (error_code EC = MemoryBuffer::getFileOrSTDIN(Path, File))
+ return EC;
+ return createBinary(File.release());
}
diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt
index 1f07cbb..dc18296 100644
--- a/lib/Object/CMakeLists.txt
+++ b/lib/Object/CMakeLists.txt
@@ -7,9 +7,11 @@ add_llvm_library(LLVMObject
ELFObjectFile.cpp
ELFYAML.cpp
Error.cpp
+ IRObjectFile.cpp
MachOObjectFile.cpp
MachOUniversal.cpp
Object.cpp
ObjectFile.cpp
+ SymbolicFile.cpp
YAML.cpp
)
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp
index 3434e70..a75ebbf 100644
--- a/lib/Object/COFFObjectFile.cpp
+++ b/lib/Object/COFFObjectFile.cpp
@@ -16,27 +16,24 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
-
-#include <ctype.h>
+#include <limits>
using namespace llvm;
using namespace object;
-namespace {
using support::ulittle8_t;
using support::ulittle16_t;
using support::ulittle32_t;
using support::little16_t;
-}
-namespace {
// Returns false if size is greater than the buffer size. And sets ec.
-bool checkSize(const MemoryBuffer *m, error_code &ec, uint64_t size) {
- if (m->getBufferSize() < size) {
- ec = object_error::unexpected_eof;
+static bool checkSize(const MemoryBuffer *M, error_code &EC, uint64_t Size) {
+ if (M->getBufferSize() < Size) {
+ EC = object_error::unexpected_eof;
return false;
}
return true;
@@ -45,8 +42,8 @@ bool checkSize(const MemoryBuffer *m, error_code &ec, uint64_t size) {
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error.
template<typename T>
-error_code getObject(const T *&Obj, const MemoryBuffer *M, const uint8_t *Ptr,
- const size_t Size = sizeof(T)) {
+static error_code getObject(const T *&Obj, const MemoryBuffer *M,
+ const uint8_t *Ptr, const size_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
if (Addr + Size < Addr ||
Addr + Size < Size ||
@@ -56,320 +53,353 @@ error_code getObject(const T *&Obj, const MemoryBuffer *M, const uint8_t *Ptr,
Obj = reinterpret_cast<const T *>(Addr);
return object_error::success;
}
+
+// Decode a string table entry in base 64 (//AAAAAA). Expects \arg Str without
+// prefixed slashes.
+static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result) {
+ assert(Str.size() <= 6 && "String too long, possible overflow.");
+ if (Str.size() > 6)
+ return true;
+
+ uint64_t Value = 0;
+ while (!Str.empty()) {
+ unsigned CharVal;
+ if (Str[0] >= 'A' && Str[0] <= 'Z') // 0..25
+ CharVal = Str[0] - 'A';
+ else if (Str[0] >= 'a' && Str[0] <= 'z') // 26..51
+ CharVal = Str[0] - 'a' + 26;
+ else if (Str[0] >= '0' && Str[0] <= '9') // 52..61
+ CharVal = Str[0] - '0' + 52;
+ else if (Str[0] == '+') // 62
+ CharVal = 62;
+ else if (Str[0] == '/') // 63
+ CharVal = 63;
+ else
+ return true;
+
+ Value = (Value * 64) + CharVal;
+ Str = Str.substr(1);
+ }
+
+ if (Value > std::numeric_limits<uint32_t>::max())
+ return true;
+
+ Result = static_cast<uint32_t>(Value);
+ return false;
}
-const coff_symbol *COFFObjectFile::toSymb(DataRefImpl Symb) const {
- const coff_symbol *addr = reinterpret_cast<const coff_symbol*>(Symb.p);
+const coff_symbol *COFFObjectFile::toSymb(DataRefImpl Ref) const {
+ const coff_symbol *Addr = reinterpret_cast<const coff_symbol*>(Ref.p);
# ifndef NDEBUG
// Verify that the symbol points to a valid entry in the symbol table.
- uintptr_t offset = uintptr_t(addr) - uintptr_t(base());
- if (offset < COFFHeader->PointerToSymbolTable
- || offset >= COFFHeader->PointerToSymbolTable
+ uintptr_t Offset = uintptr_t(Addr) - uintptr_t(base());
+ if (Offset < COFFHeader->PointerToSymbolTable
+ || Offset >= COFFHeader->PointerToSymbolTable
+ (COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
report_fatal_error("Symbol was outside of symbol table.");
- assert((offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol)
+ assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol)
== 0 && "Symbol did not point to the beginning of a symbol");
# endif
- return addr;
+ return Addr;
}
-const coff_section *COFFObjectFile::toSec(DataRefImpl Sec) const {
- const coff_section *addr = reinterpret_cast<const coff_section*>(Sec.p);
+const coff_section *COFFObjectFile::toSec(DataRefImpl Ref) const {
+ const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);
# ifndef NDEBUG
// Verify that the section points to a valid entry in the section table.
- if (addr < SectionTable
- || addr >= (SectionTable + COFFHeader->NumberOfSections))
+ if (Addr < SectionTable
+ || Addr >= (SectionTable + COFFHeader->NumberOfSections))
report_fatal_error("Section was outside of section table.");
- uintptr_t offset = uintptr_t(addr) - uintptr_t(SectionTable);
- assert(offset % sizeof(coff_section) == 0 &&
+ uintptr_t Offset = uintptr_t(Addr) - uintptr_t(SectionTable);
+ assert(Offset % sizeof(coff_section) == 0 &&
"Section did not point to the beginning of a section");
# endif
- return addr;
-}
-
-error_code COFFObjectFile::getSymbolNext(DataRefImpl Symb,
- SymbolRef &Result) const {
- const coff_symbol *symb = toSymb(Symb);
- symb += 1 + symb->NumberOfAuxSymbols;
- Symb.p = reinterpret_cast<uintptr_t>(symb);
- Result = SymbolRef(Symb, this);
- return object_error::success;
+ return Addr;
}
- error_code COFFObjectFile::getSymbolName(DataRefImpl Symb,
- StringRef &Result) const {
- const coff_symbol *symb = toSymb(Symb);
- return getSymbolName(symb, Result);
+void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
+ const coff_symbol *Symb = toSymb(Ref);
+ Symb += 1 + Symb->NumberOfAuxSymbols;
+ Ref.p = reinterpret_cast<uintptr_t>(Symb);
}
-error_code COFFObjectFile::getSymbolFileOffset(DataRefImpl Symb,
- uint64_t &Result) const {
- const coff_symbol *symb = toSymb(Symb);
- const coff_section *Section = NULL;
- if (error_code ec = getSection(symb->SectionNumber, Section))
- return ec;
-
- if (symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
- Result = UnknownAddressOrSize;
- else if (Section)
- Result = Section->PointerToRawData + symb->Value;
- else
- Result = symb->Value;
- return object_error::success;
+error_code COFFObjectFile::getSymbolName(DataRefImpl Ref,
+ StringRef &Result) const {
+ const coff_symbol *Symb = toSymb(Ref);
+ return getSymbolName(Symb, Result);
}
-error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb,
+error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
uint64_t &Result) const {
- const coff_symbol *symb = toSymb(Symb);
+ const coff_symbol *Symb = toSymb(Ref);
const coff_section *Section = NULL;
- if (error_code ec = getSection(symb->SectionNumber, Section))
- return ec;
+ if (error_code EC = getSection(Symb->SectionNumber, Section))
+ return EC;
- if (symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
+ if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
Result = UnknownAddressOrSize;
else if (Section)
- Result = Section->VirtualAddress + symb->Value;
+ Result = Section->VirtualAddress + Symb->Value;
else
- Result = symb->Value;
+ Result = Symb->Value;
return object_error::success;
}
-error_code COFFObjectFile::getSymbolType(DataRefImpl Symb,
+error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
SymbolRef::Type &Result) const {
- const coff_symbol *symb = toSymb(Symb);
+ const coff_symbol *Symb = toSymb(Ref);
Result = SymbolRef::ST_Other;
- if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
+ if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
Result = SymbolRef::ST_Unknown;
+ } else if (Symb->isFunctionDefinition()) {
+ Result = SymbolRef::ST_Function;
} else {
- if (symb->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
- Result = SymbolRef::ST_Function;
- } else {
- uint32_t Characteristics = 0;
- if (symb->SectionNumber > 0) {
- const coff_section *Section = NULL;
- if (error_code ec = getSection(symb->SectionNumber, Section))
- return ec;
- Characteristics = Section->Characteristics;
- }
- if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
- ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
- Result = SymbolRef::ST_Data;
+ uint32_t Characteristics = 0;
+ if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) {
+ const coff_section *Section = NULL;
+ if (error_code EC = getSection(Symb->SectionNumber, Section))
+ return EC;
+ Characteristics = Section->Characteristics;
}
+ if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
+ ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
+ Result = SymbolRef::ST_Data;
}
return object_error::success;
}
-error_code COFFObjectFile::getSymbolFlags(DataRefImpl Symb,
- uint32_t &Result) const {
- const coff_symbol *symb = toSymb(Symb);
- Result = SymbolRef::SF_None;
+uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
+ const coff_symbol *Symb = toSymb(Ref);
+ uint32_t Result = SymbolRef::SF_None;
- // TODO: Correctly set SF_FormatSpecific, SF_ThreadLocal, SF_Common
+ // TODO: Correctly set SF_FormatSpecific, SF_Common
+
+ if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) {
+ if (Symb->Value == 0)
+ Result |= SymbolRef::SF_Undefined;
+ else
+ Result |= SymbolRef::SF_Common;
+ }
- if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
- Result |= SymbolRef::SF_Undefined;
// TODO: This are certainly too restrictive.
- if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
+ if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
Result |= SymbolRef::SF_Global;
- if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
+ if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
Result |= SymbolRef::SF_Weak;
- if (symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)
+ if (Symb->SectionNumber == COFF::IMAGE_SYM_ABSOLUTE)
Result |= SymbolRef::SF_Absolute;
- return object_error::success;
+ return Result;
}
-error_code COFFObjectFile::getSymbolSize(DataRefImpl Symb,
+error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
uint64_t &Result) const {
// FIXME: Return the correct size. This requires looking at all the symbols
// in the same section as this symbol, and looking for either the next
// symbol, or the end of the section.
- const coff_symbol *symb = toSymb(Symb);
+ const coff_symbol *Symb = toSymb(Ref);
const coff_section *Section = NULL;
- if (error_code ec = getSection(symb->SectionNumber, Section))
- return ec;
+ if (error_code EC = getSection(Symb->SectionNumber, Section))
+ return EC;
- if (symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
+ if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
Result = UnknownAddressOrSize;
else if (Section)
- Result = Section->SizeOfRawData - symb->Value;
+ Result = Section->SizeOfRawData - Symb->Value;
else
Result = 0;
return object_error::success;
}
-error_code COFFObjectFile::getSymbolSection(DataRefImpl Symb,
+error_code COFFObjectFile::getSymbolSection(DataRefImpl Ref,
section_iterator &Result) const {
- const coff_symbol *symb = toSymb(Symb);
- if (symb->SectionNumber <= COFF::IMAGE_SYM_UNDEFINED)
- Result = end_sections();
- else {
- const coff_section *sec = 0;
- if (error_code ec = getSection(symb->SectionNumber, sec)) return ec;
- DataRefImpl Sec;
- Sec.p = reinterpret_cast<uintptr_t>(sec);
- Result = section_iterator(SectionRef(Sec, this));
+ const coff_symbol *Symb = toSymb(Ref);
+ if (COFF::isReservedSectionNumber(Symb->SectionNumber)) {
+ Result = section_end();
+ } else {
+ const coff_section *Sec = 0;
+ if (error_code EC = getSection(Symb->SectionNumber, Sec)) return EC;
+ DataRefImpl Ref;
+ Ref.p = reinterpret_cast<uintptr_t>(Sec);
+ Result = section_iterator(SectionRef(Ref, this));
}
return object_error::success;
}
-error_code COFFObjectFile::getSymbolValue(DataRefImpl Symb,
- uint64_t &Val) const {
- report_fatal_error("getSymbolValue unimplemented in COFFObjectFile");
-}
-
-error_code COFFObjectFile::getSectionNext(DataRefImpl Sec,
- SectionRef &Result) const {
- const coff_section *sec = toSec(Sec);
- sec += 1;
- Sec.p = reinterpret_cast<uintptr_t>(sec);
- Result = SectionRef(Sec, this);
- return object_error::success;
+void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
+ const coff_section *Sec = toSec(Ref);
+ Sec += 1;
+ Ref.p = reinterpret_cast<uintptr_t>(Sec);
}
-error_code COFFObjectFile::getSectionName(DataRefImpl Sec,
+error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
StringRef &Result) const {
- const coff_section *sec = toSec(Sec);
- return getSectionName(sec, Result);
+ const coff_section *Sec = toSec(Ref);
+ return getSectionName(Sec, Result);
}
-error_code COFFObjectFile::getSectionAddress(DataRefImpl Sec,
+error_code COFFObjectFile::getSectionAddress(DataRefImpl Ref,
uint64_t &Result) const {
- const coff_section *sec = toSec(Sec);
- Result = sec->VirtualAddress;
+ const coff_section *Sec = toSec(Ref);
+ Result = Sec->VirtualAddress;
return object_error::success;
}
-error_code COFFObjectFile::getSectionSize(DataRefImpl Sec,
+error_code COFFObjectFile::getSectionSize(DataRefImpl Ref,
uint64_t &Result) const {
- const coff_section *sec = toSec(Sec);
- Result = sec->SizeOfRawData;
+ const coff_section *Sec = toSec(Ref);
+ Result = Sec->SizeOfRawData;
return object_error::success;
}
-error_code COFFObjectFile::getSectionContents(DataRefImpl Sec,
+error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
StringRef &Result) const {
- const coff_section *sec = toSec(Sec);
+ const coff_section *Sec = toSec(Ref);
ArrayRef<uint8_t> Res;
- error_code EC = getSectionContents(sec, Res);
+ error_code EC = getSectionContents(Sec, Res);
Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
return EC;
}
-error_code COFFObjectFile::getSectionAlignment(DataRefImpl Sec,
+error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref,
uint64_t &Res) const {
- const coff_section *sec = toSec(Sec);
- if (!sec)
+ const coff_section *Sec = toSec(Ref);
+ if (!Sec)
return object_error::parse_failed;
- Res = uint64_t(1) << (((sec->Characteristics & 0x00F00000) >> 20) - 1);
+ Res = uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1);
return object_error::success;
}
-error_code COFFObjectFile::isSectionText(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionText(DataRefImpl Ref,
bool &Result) const {
- const coff_section *sec = toSec(Sec);
- Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
+ const coff_section *Sec = toSec(Ref);
+ Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
return object_error::success;
}
-error_code COFFObjectFile::isSectionData(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionData(DataRefImpl Ref,
bool &Result) const {
- const coff_section *sec = toSec(Sec);
- Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
+ const coff_section *Sec = toSec(Ref);
+ Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
return object_error::success;
}
-error_code COFFObjectFile::isSectionBSS(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionBSS(DataRefImpl Ref,
bool &Result) const {
- const coff_section *sec = toSec(Sec);
- Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+ const coff_section *Sec = toSec(Ref);
+ Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
return object_error::success;
}
-error_code COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref,
bool &Result) const {
// FIXME: Unimplemented
Result = true;
return object_error::success;
}
-error_code COFFObjectFile::isSectionVirtual(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref,
bool &Result) const {
- const coff_section *sec = toSec(Sec);
- Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+ const coff_section *Sec = toSec(Ref);
+ Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
return object_error::success;
}
-error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref,
bool &Result) const {
// FIXME: Unimplemented.
Result = false;
return object_error::success;
}
-error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
+error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref,
bool &Result) const {
// FIXME: Unimplemented.
Result = false;
return object_error::success;
}
-error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec,
- DataRefImpl Symb,
+error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
+ DataRefImpl SymbRef,
bool &Result) const {
- const coff_section *sec = toSec(Sec);
- const coff_symbol *symb = toSymb(Symb);
- const coff_section *symb_sec = 0;
- if (error_code ec = getSection(symb->SectionNumber, symb_sec)) return ec;
- if (symb_sec == sec)
+ const coff_section *Sec = toSec(SecRef);
+ const coff_symbol *Symb = toSymb(SymbRef);
+ const coff_section *SymbSec = 0;
+ if (error_code EC = getSection(Symb->SectionNumber, SymbSec)) return EC;
+ if (SymbSec == Sec)
Result = true;
else
Result = false;
return object_error::success;
}
-relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
- const coff_section *sec = toSec(Sec);
- DataRefImpl ret;
- if (sec->NumberOfRelocations == 0)
- ret.p = 0;
- else
- ret.p = reinterpret_cast<uintptr_t>(base() + sec->PointerToRelocations);
-
- return relocation_iterator(RelocationRef(ret, this));
+relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const {
+ const coff_section *Sec = toSec(Ref);
+ DataRefImpl Ret;
+ if (Sec->NumberOfRelocations == 0) {
+ Ret.p = 0;
+ } else {
+ auto begin = reinterpret_cast<const coff_relocation*>(
+ base() + Sec->PointerToRelocations);
+ if (Sec->hasExtendedRelocations()) {
+ // Skip the first relocation entry repurposed to store the number of
+ // relocations.
+ begin++;
+ }
+ Ret.p = reinterpret_cast<uintptr_t>(begin);
+ }
+ return relocation_iterator(RelocationRef(Ret, this));
+}
+
+static uint32_t getNumberOfRelocations(const coff_section *Sec,
+ const uint8_t *base) {
+ // The field for the number of relocations in COFF section table is only
+ // 16-bit wide. If a section has more than 65535 relocations, 0xFFFF is set to
+ // NumberOfRelocations field, and the actual relocation count is stored in the
+ // VirtualAddress field in the first relocation entry.
+ if (Sec->hasExtendedRelocations()) {
+ auto *FirstReloc = reinterpret_cast<const coff_relocation*>(
+ base + Sec->PointerToRelocations);
+ return FirstReloc->VirtualAddress;
+ }
+ return Sec->NumberOfRelocations;
}
-relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Sec) const {
- const coff_section *sec = toSec(Sec);
- DataRefImpl ret;
- if (sec->NumberOfRelocations == 0)
- ret.p = 0;
- else
- ret.p = reinterpret_cast<uintptr_t>(
- reinterpret_cast<const coff_relocation*>(
- base() + sec->PointerToRelocations)
- + sec->NumberOfRelocations);
+relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
+ const coff_section *Sec = toSec(Ref);
+ DataRefImpl Ret;
+ if (Sec->NumberOfRelocations == 0) {
+ Ret.p = 0;
+ } else {
+ auto begin = reinterpret_cast<const coff_relocation*>(
+ base() + Sec->PointerToRelocations);
+ uint32_t NumReloc = getNumberOfRelocations(Sec, base());
+ Ret.p = reinterpret_cast<uintptr_t>(begin + NumReloc);
+ }
+ return relocation_iterator(RelocationRef(Ret, this));
+}
- return relocation_iterator(RelocationRef(ret, this));
+bool COFFObjectFile::section_rel_empty(DataRefImpl Ref) const {
+ const coff_section *Sec = toSec(Ref);
+ return Sec->NumberOfRelocations == 0;
}
// Initialize the pointer to the symbol table.
error_code COFFObjectFile::initSymbolTablePtr() {
- if (error_code ec = getObject(
+ if (error_code EC = getObject(
SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable,
COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
- return ec;
+ return EC;
// Find string table. The first four byte of the string table contains the
// total size of the string table, including the size field itself. If the
@@ -378,32 +408,41 @@ error_code COFFObjectFile::initSymbolTablePtr() {
base() + COFFHeader->PointerToSymbolTable +
COFFHeader->NumberOfSymbols * sizeof(coff_symbol);
const ulittle32_t *StringTableSizePtr;
- if (error_code ec = getObject(StringTableSizePtr, Data, StringTableAddr))
- return ec;
+ if (error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
+ return EC;
StringTableSize = *StringTableSizePtr;
- if (error_code ec =
+ if (error_code EC =
getObject(StringTable, Data, StringTableAddr, StringTableSize))
- return ec;
+ return EC;
+
+ // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
+ // tools like cvtres write a size of 0 for an empty table instead of 4.
+ if (StringTableSize < 4)
+ StringTableSize = 4;
// Check that the string table is null terminated if has any in it.
- if (StringTableSize < 4 ||
- (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0))
+ if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)
return object_error::parse_failed;
return object_error::success;
}
+// Returns the file offset for the given VA.
+error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
+ uint64_t ImageBase = PE32Header ? (uint64_t)PE32Header->ImageBase
+ : (uint64_t)PE32PlusHeader->ImageBase;
+ uint64_t Rva = Addr - ImageBase;
+ assert(Rva <= UINT32_MAX);
+ return getRvaPtr((uint32_t)Rva, Res);
+}
+
// Returns the file offset for the given RVA.
-error_code COFFObjectFile::getRvaPtr(uint32_t Rva, uintptr_t &Res) const {
- error_code ec;
- for (section_iterator i = begin_sections(), e = end_sections(); i != e;
- i.increment(ec)) {
- if (ec)
- return ec;
- const coff_section *Section = getCOFFSection(i);
+error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
+ for (const SectionRef &S : sections()) {
+ const coff_section *Section = getCOFFSection(S);
uint32_t SectionStart = Section->VirtualAddress;
uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
- if (SectionStart <= Rva && Rva < SectionEnd) {
- uint32_t Offset = Rva - SectionStart;
+ if (SectionStart <= Addr && Addr < SectionEnd) {
+ uint32_t Offset = Addr - SectionStart;
Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
return object_error::success;
}
@@ -416,8 +455,8 @@ error_code COFFObjectFile::getRvaPtr(uint32_t Rva, uintptr_t &Res) const {
error_code COFFObjectFile::
getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const {
uintptr_t IntPtr = 0;
- if (error_code ec = getRvaPtr(Rva, IntPtr))
- return ec;
+ if (error_code EC = getRvaPtr(Rva, IntPtr))
+ return EC;
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);
Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);
Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));
@@ -443,118 +482,136 @@ error_code COFFObjectFile::initImportTablePtr() {
// Find the section that contains the RVA. This is needed because the RVA is
// the import table's memory address which is different from its file offset.
uintptr_t IntPtr = 0;
- if (error_code ec = getRvaPtr(ImportTableRva, IntPtr))
- return ec;
+ if (error_code EC = getRvaPtr(ImportTableRva, IntPtr))
+ return EC;
ImportDirectory = reinterpret_cast<
const import_directory_table_entry *>(IntPtr);
+ return object_error::success;
+}
- // It's an error if there's no section containing the Import Table RVA.
- return object_error::parse_failed;
+// Find the export table.
+error_code COFFObjectFile::initExportTablePtr() {
+ // First, we get the RVA of the export table. If the file lacks a pointer to
+ // the export table, do nothing.
+ const data_directory *DataEntry;
+ if (getDataDirectory(COFF::EXPORT_TABLE, DataEntry))
+ return object_error::success;
+
+ // Do nothing if the pointer to export table is NULL.
+ if (DataEntry->RelativeVirtualAddress == 0)
+ return object_error::success;
+
+ uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
+ uintptr_t IntPtr = 0;
+ if (error_code EC = getRvaPtr(ExportTableRva, IntPtr))
+ return EC;
+ ExportDirectory =
+ reinterpret_cast<const export_directory_table_entry *>(IntPtr);
+ return object_error::success;
}
-COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec)
- : ObjectFile(Binary::ID_COFF, Object)
- , COFFHeader(0)
- , PE32Header(0)
- , DataDirectory(0)
- , SectionTable(0)
- , SymbolTable(0)
- , StringTable(0)
- , StringTableSize(0)
- , ImportDirectory(0)
- , NumberOfImportDirectory(0) {
+COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
+ bool BufferOwned)
+ : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(0),
+ PE32Header(0), PE32PlusHeader(0), DataDirectory(0), SectionTable(0),
+ SymbolTable(0), StringTable(0), StringTableSize(0), ImportDirectory(0),
+ NumberOfImportDirectory(0), ExportDirectory(0) {
// Check that we at least have enough room for a header.
- if (!checkSize(Data, ec, sizeof(coff_file_header))) return;
+ if (!checkSize(Data, EC, sizeof(coff_file_header))) return;
// The current location in the file where we are looking at.
uint64_t CurPtr = 0;
// PE header is optional and is present only in executables. If it exists,
// it is placed right after COFF header.
- bool hasPEHeader = false;
+ bool HasPEHeader = false;
// Check if this is a PE/COFF file.
if (base()[0] == 0x4d && base()[1] == 0x5a) {
// PE/COFF, seek through MS-DOS compatibility stub and 4-byte
// PE signature to find 'normal' COFF header.
- if (!checkSize(Data, ec, 0x3c + 8)) return;
+ if (!checkSize(Data, EC, 0x3c + 8)) return;
CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
// Check the PE magic bytes. ("PE\0\0")
if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) {
- ec = object_error::parse_failed;
+ EC = object_error::parse_failed;
return;
}
CurPtr += 4; // Skip the PE magic bytes.
- hasPEHeader = true;
+ HasPEHeader = true;
}
- if ((ec = getObject(COFFHeader, Data, base() + CurPtr)))
+ if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
return;
CurPtr += sizeof(coff_file_header);
- if (hasPEHeader) {
- if ((ec = getObject(PE32Header, Data, base() + CurPtr)))
+ if (HasPEHeader) {
+ const pe32_header *Header;
+ if ((EC = getObject(Header, Data, base() + CurPtr)))
+ return;
+
+ const uint8_t *DataDirAddr;
+ uint64_t DataDirSize;
+ if (Header->Magic == 0x10b) {
+ PE32Header = Header;
+ DataDirAddr = base() + CurPtr + sizeof(pe32_header);
+ DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
+ } else if (Header->Magic == 0x20b) {
+ PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
+ DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
+ DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
+ } else {
+ // It's neither PE32 nor PE32+.
+ EC = object_error::parse_failed;
return;
- if (PE32Header->Magic != 0x10b) {
- // We only support PE32. If this is PE32 (not PE32+), the magic byte
- // should be 0x10b. If this is not PE32, continue as if there's no PE
- // header in this file.
- PE32Header = 0;
- } else if (PE32Header->NumberOfRvaAndSize > 0) {
- const uint8_t *addr = base() + CurPtr + sizeof(pe32_header);
- uint64_t size = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
- if ((ec = getObject(DataDirectory, Data, addr, size)))
- return;
}
+ if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
+ return;
CurPtr += COFFHeader->SizeOfOptionalHeader;
}
- if (!COFFHeader->isImportLibrary())
- if ((ec = getObject(SectionTable, Data, base() + CurPtr,
- COFFHeader->NumberOfSections * sizeof(coff_section))))
- return;
+ if (COFFHeader->isImportLibrary())
+ return;
+
+ if ((EC = getObject(SectionTable, Data, base() + CurPtr,
+ COFFHeader->NumberOfSections * sizeof(coff_section))))
+ return;
// Initialize the pointer to the symbol table.
if (COFFHeader->PointerToSymbolTable != 0)
- if ((ec = initSymbolTablePtr()))
+ if ((EC = initSymbolTablePtr()))
return;
// Initialize the pointer to the beginning of the import table.
- if ((ec = initImportTablePtr()))
+ if ((EC = initImportTablePtr()))
return;
- ec = object_error::success;
-}
-
-symbol_iterator COFFObjectFile::begin_symbols() const {
- DataRefImpl ret;
- ret.p = reinterpret_cast<uintptr_t>(SymbolTable);
- return symbol_iterator(SymbolRef(ret, this));
-}
+ // Initialize the pointer to the export table.
+ if ((EC = initExportTablePtr()))
+ return;
-symbol_iterator COFFObjectFile::end_symbols() const {
- // The symbol table ends where the string table begins.
- DataRefImpl ret;
- ret.p = reinterpret_cast<uintptr_t>(StringTable);
- return symbol_iterator(SymbolRef(ret, this));
+ EC = object_error::success;
}
-symbol_iterator COFFObjectFile::begin_dynamic_symbols() const {
- // TODO: implement
- report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
+basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const {
+ DataRefImpl Ret;
+ Ret.p = reinterpret_cast<uintptr_t>(SymbolTable);
+ return basic_symbol_iterator(SymbolRef(Ret, this));
}
-symbol_iterator COFFObjectFile::end_dynamic_symbols() const {
- // TODO: implement
- report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
+basic_symbol_iterator COFFObjectFile::symbol_end_impl() const {
+ // The symbol table ends where the string table begins.
+ DataRefImpl Ret;
+ Ret.p = reinterpret_cast<uintptr_t>(StringTable);
+ return basic_symbol_iterator(SymbolRef(Ret, this));
}
-library_iterator COFFObjectFile::begin_libraries_needed() const {
+library_iterator COFFObjectFile::needed_library_begin() const {
// TODO: implement
report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
}
-library_iterator COFFObjectFile::end_libraries_needed() const {
+library_iterator COFFObjectFile::needed_library_end() const {
// TODO: implement
report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
}
@@ -565,34 +622,40 @@ StringRef COFFObjectFile::getLoadName() const {
}
import_directory_iterator COFFObjectFile::import_directory_begin() const {
- DataRefImpl Imp;
- Imp.p = reinterpret_cast<uintptr_t>(ImportDirectory);
- return import_directory_iterator(ImportDirectoryEntryRef(Imp, this));
+ return import_directory_iterator(
+ ImportDirectoryEntryRef(ImportDirectory, 0, this));
}
import_directory_iterator COFFObjectFile::import_directory_end() const {
- DataRefImpl Imp;
- if (ImportDirectory) {
- Imp.p = reinterpret_cast<uintptr_t>(
- ImportDirectory + (NumberOfImportDirectory - 1));
- } else {
- Imp.p = 0;
- }
- return import_directory_iterator(ImportDirectoryEntryRef(Imp, this));
+ return import_directory_iterator(
+ ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this));
+}
+
+export_directory_iterator COFFObjectFile::export_directory_begin() const {
+ return export_directory_iterator(
+ ExportDirectoryEntryRef(ExportDirectory, 0, this));
+}
+
+export_directory_iterator COFFObjectFile::export_directory_end() const {
+ if (ExportDirectory == 0)
+ return export_directory_iterator(ExportDirectoryEntryRef(0, 0, this));
+ ExportDirectoryEntryRef Ref(ExportDirectory,
+ ExportDirectory->AddressTableEntries, this);
+ return export_directory_iterator(Ref);
}
-section_iterator COFFObjectFile::begin_sections() const {
- DataRefImpl ret;
- ret.p = reinterpret_cast<uintptr_t>(SectionTable);
- return section_iterator(SectionRef(ret, this));
+section_iterator COFFObjectFile::section_begin() const {
+ DataRefImpl Ret;
+ Ret.p = reinterpret_cast<uintptr_t>(SectionTable);
+ return section_iterator(SectionRef(Ret, this));
}
-section_iterator COFFObjectFile::end_sections() const {
- DataRefImpl ret;
- int numSections = COFFHeader->isImportLibrary()
+section_iterator COFFObjectFile::section_end() const {
+ DataRefImpl Ret;
+ int NumSections = COFFHeader->isImportLibrary()
? 0 : COFFHeader->NumberOfSections;
- ret.p = reinterpret_cast<uintptr_t>(SectionTable + numSections);
- return section_iterator(SectionRef(ret, this));
+ Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);
+ return section_iterator(SectionRef(Ret, this));
}
uint8_t COFFObjectFile::getBytesInAddress() const {
@@ -605,6 +668,8 @@ StringRef COFFObjectFile::getFileFormatName() const {
return "COFF-i386";
case COFF::IMAGE_FILE_MACHINE_AMD64:
return "COFF-x86-64";
+ case COFF::IMAGE_FILE_MACHINE_ARMNT:
+ return "COFF-ARM";
default:
return "COFF-<unknown arch>";
}
@@ -616,6 +681,8 @@ unsigned COFFObjectFile::getArch() const {
return Triple::x86;
case COFF::IMAGE_FILE_MACHINE_AMD64:
return Triple::x86_64;
+ case COFF::IMAGE_FILE_MACHINE_ARMNT:
+ return Triple::thumb;
default:
return Triple::UnknownArch;
}
@@ -637,89 +704,99 @@ error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
return object_error::success;
}
-error_code COFFObjectFile::getDataDirectory(uint32_t index,
+error_code
+COFFObjectFile::getPE32PlusHeader(const pe32plus_header *&Res) const {
+ Res = PE32PlusHeader;
+ return object_error::success;
+}
+
+error_code COFFObjectFile::getDataDirectory(uint32_t Index,
const data_directory *&Res) const {
// Error if if there's no data directory or the index is out of range.
- if (!DataDirectory || index > PE32Header->NumberOfRvaAndSize)
+ if (!DataDirectory)
+ return object_error::parse_failed;
+ assert(PE32Header || PE32PlusHeader);
+ uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize
+ : PE32PlusHeader->NumberOfRvaAndSize;
+ if (Index > NumEnt)
return object_error::parse_failed;
- Res = &DataDirectory[index];
+ Res = &DataDirectory[Index];
return object_error::success;
}
-error_code COFFObjectFile::getSection(int32_t index,
+error_code COFFObjectFile::getSection(int32_t Index,
const coff_section *&Result) const {
// Check for special index values.
- if (index == COFF::IMAGE_SYM_UNDEFINED ||
- index == COFF::IMAGE_SYM_ABSOLUTE ||
- index == COFF::IMAGE_SYM_DEBUG)
+ if (COFF::isReservedSectionNumber(Index))
Result = NULL;
- else if (index > 0 && index <= COFFHeader->NumberOfSections)
+ else if (Index > 0 && Index <= COFFHeader->NumberOfSections)
// We already verified the section table data, so no need to check again.
- Result = SectionTable + (index - 1);
+ Result = SectionTable + (Index - 1);
else
return object_error::parse_failed;
return object_error::success;
}
-error_code COFFObjectFile::getString(uint32_t offset,
+error_code COFFObjectFile::getString(uint32_t Offset,
StringRef &Result) const {
if (StringTableSize <= 4)
// Tried to get a string from an empty string table.
return object_error::parse_failed;
- if (offset >= StringTableSize)
+ if (Offset >= StringTableSize)
return object_error::unexpected_eof;
- Result = StringRef(StringTable + offset);
+ Result = StringRef(StringTable + Offset);
return object_error::success;
}
-error_code COFFObjectFile::getSymbol(uint32_t index,
+error_code COFFObjectFile::getSymbol(uint32_t Index,
const coff_symbol *&Result) const {
- if (index < COFFHeader->NumberOfSymbols)
- Result = SymbolTable + index;
+ if (Index < COFFHeader->NumberOfSymbols)
+ Result = SymbolTable + Index;
else
return object_error::parse_failed;
return object_error::success;
}
-error_code COFFObjectFile::getSymbolName(const coff_symbol *symbol,
+error_code COFFObjectFile::getSymbolName(const coff_symbol *Symbol,
StringRef &Res) const {
// Check for string table entry. First 4 bytes are 0.
- if (symbol->Name.Offset.Zeroes == 0) {
- uint32_t Offset = symbol->Name.Offset.Offset;
- if (error_code ec = getString(Offset, Res))
- return ec;
+ if (Symbol->Name.Offset.Zeroes == 0) {
+ uint32_t Offset = Symbol->Name.Offset.Offset;
+ if (error_code EC = getString(Offset, Res))
+ return EC;
return object_error::success;
}
- if (symbol->Name.ShortName[7] == 0)
+ if (Symbol->Name.ShortName[7] == 0)
// Null terminated, let ::strlen figure out the length.
- Res = StringRef(symbol->Name.ShortName);
+ Res = StringRef(Symbol->Name.ShortName);
else
// Not null terminated, use all 8 bytes.
- Res = StringRef(symbol->Name.ShortName, 8);
+ Res = StringRef(Symbol->Name.ShortName, 8);
return object_error::success;
}
ArrayRef<uint8_t> COFFObjectFile::getSymbolAuxData(
- const coff_symbol *symbol) const {
- const uint8_t *aux = NULL;
+ const coff_symbol *Symbol) const {
+ const uint8_t *Aux = NULL;
- if ( symbol->NumberOfAuxSymbols > 0 ) {
+ if (Symbol->NumberOfAuxSymbols > 0) {
// AUX data comes immediately after the symbol in COFF
- aux = reinterpret_cast<const uint8_t *>(symbol + 1);
+ Aux = reinterpret_cast<const uint8_t *>(Symbol + 1);
# ifndef NDEBUG
- // Verify that the aux symbol points to a valid entry in the symbol table.
- uintptr_t offset = uintptr_t(aux) - uintptr_t(base());
- if (offset < COFFHeader->PointerToSymbolTable
- || offset >= COFFHeader->PointerToSymbolTable
+ // Verify that the Aux symbol points to a valid entry in the symbol table.
+ uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());
+ if (Offset < COFFHeader->PointerToSymbolTable
+ || Offset >= COFFHeader->PointerToSymbolTable
+ (COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
report_fatal_error("Aux Symbol data was outside of symbol table.");
- assert((offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol)
+ assert((Offset - COFFHeader->PointerToSymbolTable) % sizeof(coff_symbol)
== 0 && "Aux Symbol data did not point to the beginning of a symbol");
# endif
}
- return ArrayRef<uint8_t>(aux, symbol->NumberOfAuxSymbols * sizeof(coff_symbol));
+ return ArrayRef<uint8_t>(Aux,
+ Symbol->NumberOfAuxSymbols * sizeof(coff_symbol));
}
error_code COFFObjectFile::getSectionName(const coff_section *Sec,
@@ -735,10 +812,15 @@ error_code COFFObjectFile::getSectionName(const coff_section *Sec,
// Check for string table entry. First byte is '/'.
if (Name[0] == '/') {
uint32_t Offset;
- if (Name.substr(1).getAsInteger(10, Offset))
- return object_error::parse_failed;
- if (error_code ec = getString(Offset, Name))
- return ec;
+ if (Name[1] == '/') {
+ if (decodeBase64StringEntry(Name.substr(2), Offset))
+ return object_error::parse_failed;
+ } else {
+ if (Name.substr(1).getAsInteger(10, Offset))
+ return object_error::parse_failed;
+ }
+ if (error_code EC = getString(Offset, Name))
+ return EC;
}
Res = Name;
@@ -762,28 +844,30 @@ error_code COFFObjectFile::getSectionContents(const coff_section *Sec,
const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const {
return reinterpret_cast<const coff_relocation*>(Rel.p);
}
-error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const {
+
+void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
Rel.p = reinterpret_cast<uintptr_t>(
reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
- Res = RelocationRef(Rel, this);
- return object_error::success;
}
+
error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
uint64_t &Res) const {
report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
}
+
error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const {
Res = toRel(Rel)->VirtualAddress;
return object_error::success;
}
+
symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
const coff_relocation* R = toRel(Rel);
- DataRefImpl Symb;
- Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex);
- return symbol_iterator(SymbolRef(Symb, this));
+ DataRefImpl Ref;
+ Ref.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex);
+ return symbol_iterator(SymbolRef(Ref, this));
}
+
error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
uint64_t &Res) const {
const coff_relocation* R = toRel(Rel);
@@ -791,29 +875,33 @@ error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
return object_error::success;
}
-const coff_section *COFFObjectFile::getCOFFSection(section_iterator &It) const {
- return toSec(It->getRawDataRefImpl());
+const coff_section *
+COFFObjectFile::getCOFFSection(const SectionRef &Section) const {
+ return toSec(Section.getRawDataRefImpl());
}
-const coff_symbol *COFFObjectFile::getCOFFSymbol(symbol_iterator &It) const {
- return toSymb(It->getRawDataRefImpl());
+const coff_symbol *
+COFFObjectFile::getCOFFSymbol(const SymbolRef &Symbol) const {
+ return toSymb(Symbol.getRawDataRefImpl());
}
-const coff_relocation *COFFObjectFile::getCOFFRelocation(
- relocation_iterator &It) const {
- return toRel(It->getRawDataRefImpl());
+const coff_relocation *
+COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
+ return toRel(Reloc.getRawDataRefImpl());
}
-#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \
- case COFF::enum: res = #enum; break;
+#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \
+ case COFF::reloc_type: \
+ Res = #reloc_type; \
+ break;
error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
- const coff_relocation *reloc = toRel(Rel);
- StringRef res;
+ const coff_relocation *Reloc = toRel(Rel);
+ StringRef Res;
switch (COFFHeader->Machine) {
case COFF::IMAGE_FILE_MACHINE_AMD64:
- switch (reloc->Type) {
+ switch (Reloc->Type) {
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE);
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64);
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32);
@@ -832,11 +920,11 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR);
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32);
default:
- res = "Unknown";
+ Res = "Unknown";
}
break;
case COFF::IMAGE_FILE_MACHINE_I386:
- switch (reloc->Type) {
+ switch (Reloc->Type) {
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16);
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16);
@@ -849,13 +937,13 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7);
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32);
default:
- res = "Unknown";
+ Res = "Unknown";
}
break;
default:
- res = "Unknown";
+ Res = "Unknown";
}
- Result.append(res.begin(), res.end());
+ Result.append(Res.begin(), Res.end());
return object_error::success;
}
@@ -863,14 +951,14 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
- const coff_relocation *reloc = toRel(Rel);
- const coff_symbol *symb = 0;
- if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec;
- DataRefImpl sym;
- sym.p = reinterpret_cast<uintptr_t>(symb);
- StringRef symname;
- if (error_code ec = getSymbolName(sym, symname)) return ec;
- Result.append(symname.begin(), symname.end());
+ const coff_relocation *Reloc = toRel(Rel);
+ const coff_symbol *Symb = 0;
+ if (error_code EC = getSymbol(Reloc->SymbolTableIndex, Symb)) return EC;
+ DataRefImpl Sym;
+ Sym.p = reinterpret_cast<uintptr_t>(Symb);
+ StringRef SymName;
+ if (error_code EC = getSymbolName(Sym, SymName)) return EC;
+ Result.append(SymName.begin(), SymName.end());
return object_error::success;
}
@@ -886,55 +974,114 @@ error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
bool ImportDirectoryEntryRef::
operator==(const ImportDirectoryEntryRef &Other) const {
- return ImportDirectoryPimpl == Other.ImportDirectoryPimpl;
+ return ImportTable == Other.ImportTable && Index == Other.Index;
}
-static const import_directory_table_entry *toImportEntry(DataRefImpl Imp) {
- return reinterpret_cast<const import_directory_table_entry *>(Imp.p);
-}
-
-error_code
-ImportDirectoryEntryRef::getNext(ImportDirectoryEntryRef &Result) const {
- const import_directory_table_entry *Dir = toImportEntry(ImportDirectoryPimpl);
- Dir += 1;
- DataRefImpl Next;
- Next.p = reinterpret_cast<uintptr_t>(Dir);
- Result = ImportDirectoryEntryRef(Next, OwningObject);
- return object_error::success;
+void ImportDirectoryEntryRef::moveNext() {
+ ++Index;
}
error_code ImportDirectoryEntryRef::
getImportTableEntry(const import_directory_table_entry *&Result) const {
- Result = toImportEntry(ImportDirectoryPimpl);
+ Result = ImportTable;
return object_error::success;
}
error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
- const import_directory_table_entry *Dir = toImportEntry(ImportDirectoryPimpl);
uintptr_t IntPtr = 0;
- if (error_code ec = OwningObject->getRvaPtr(Dir->NameRVA, IntPtr))
- return ec;
- const char *Ptr = reinterpret_cast<const char *>(IntPtr);
- Result = StringRef(Ptr);
+ if (error_code EC = OwningObject->getRvaPtr(ImportTable->NameRVA, IntPtr))
+ return EC;
+ Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return object_error::success;
}
error_code ImportDirectoryEntryRef::getImportLookupEntry(
const import_lookup_table_entry32 *&Result) const {
- const import_directory_table_entry *Dir = toImportEntry(ImportDirectoryPimpl);
uintptr_t IntPtr = 0;
- if (error_code ec = OwningObject->getRvaPtr(
- Dir->ImportLookupTableRVA, IntPtr))
- return ec;
+ if (error_code EC =
+ OwningObject->getRvaPtr(ImportTable->ImportLookupTableRVA, IntPtr))
+ return EC;
Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
return object_error::success;
}
-namespace llvm {
+bool ExportDirectoryEntryRef::
+operator==(const ExportDirectoryEntryRef &Other) const {
+ return ExportTable == Other.ExportTable && Index == Other.Index;
+}
+
+void ExportDirectoryEntryRef::moveNext() {
+ ++Index;
+}
- ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
- error_code ec;
- return new COFFObjectFile(Object, ec);
+// Returns the name of the current export symbol. If the symbol is exported only
+// by ordinal, the empty string is set as a result.
+error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
+ uintptr_t IntPtr = 0;
+ if (error_code EC = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
+ return EC;
+ Result = StringRef(reinterpret_cast<const char *>(IntPtr));
+ return object_error::success;
+}
+
+// Returns the starting ordinal number.
+error_code ExportDirectoryEntryRef::getOrdinalBase(uint32_t &Result) const {
+ Result = ExportTable->OrdinalBase;
+ return object_error::success;
+}
+
+// Returns the export ordinal of the current export symbol.
+error_code ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
+ Result = ExportTable->OrdinalBase + Index;
+ return object_error::success;
+}
+
+// Returns the address of the current export symbol.
+error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
+ uintptr_t IntPtr = 0;
+ if (error_code EC = OwningObject->getRvaPtr(
+ ExportTable->ExportAddressTableRVA, IntPtr))
+ return EC;
+ const export_address_table_entry *entry =
+ reinterpret_cast<const export_address_table_entry *>(IntPtr);
+ Result = entry[Index].ExportRVA;
+ return object_error::success;
+}
+
+// Returns the name of the current export symbol. If the symbol is exported only
+// by ordinal, the empty string is set as a result.
+error_code ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
+ uintptr_t IntPtr = 0;
+ if (error_code EC = OwningObject->getRvaPtr(
+ ExportTable->OrdinalTableRVA, IntPtr))
+ return EC;
+ const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
+
+ uint32_t NumEntries = ExportTable->NumberOfNamePointers;
+ int Offset = 0;
+ for (const ulittle16_t *I = Start, *E = Start + NumEntries;
+ I < E; ++I, ++Offset) {
+ if (*I != Index)
+ continue;
+ if (error_code EC = OwningObject->getRvaPtr(
+ ExportTable->NamePointerRVA, IntPtr))
+ return EC;
+ const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);
+ if (error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
+ return EC;
+ Result = StringRef(reinterpret_cast<const char *>(IntPtr));
+ return object_error::success;
}
+ Result = "";
+ return object_error::success;
+}
-} // end namespace llvm
+ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object,
+ bool BufferOwned) {
+ error_code EC;
+ std::unique_ptr<COFFObjectFile> Ret(
+ new COFFObjectFile(Object, EC, BufferOwned));
+ if (EC)
+ return EC;
+ return Ret.release();
+}
diff --git a/lib/Object/COFFYAML.cpp b/lib/Object/COFFYAML.cpp
index e549b4e..94b72ff 100644
--- a/lib/Object/COFFYAML.cpp
+++ b/lib/Object/COFFYAML.cpp
@@ -23,13 +23,38 @@ Object::Object() { memset(&Header, 0, sizeof(COFF::header)); }
}
namespace yaml {
+void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration(
+ IO &IO, COFFYAML::COMDATType &Value) {
+ IO.enumCase(Value, "0", 0);
+ ECase(IMAGE_COMDAT_SELECT_NODUPLICATES);
+ ECase(IMAGE_COMDAT_SELECT_ANY);
+ ECase(IMAGE_COMDAT_SELECT_SAME_SIZE);
+ ECase(IMAGE_COMDAT_SELECT_EXACT_MATCH);
+ ECase(IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+ ECase(IMAGE_COMDAT_SELECT_LARGEST);
+ ECase(IMAGE_COMDAT_SELECT_NEWEST);
+}
+
+void
+ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics>::enumeration(
+ IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
+ ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
+ ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
+ ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
+}
+
+void ScalarEnumerationTraits<COFFYAML::AuxSymbolType>::enumeration(
+ IO &IO, COFFYAML::AuxSymbolType &Value) {
+ ECase(IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF);
+}
+
void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
IO &IO, COFF::MachineTypes &Value) {
ECase(IMAGE_FILE_MACHINE_UNKNOWN);
ECase(IMAGE_FILE_MACHINE_AM33);
ECase(IMAGE_FILE_MACHINE_AMD64);
ECase(IMAGE_FILE_MACHINE_ARM);
- ECase(IMAGE_FILE_MACHINE_ARMV7);
+ ECase(IMAGE_FILE_MACHINE_ARMNT);
ECase(IMAGE_FILE_MACHINE_EBC);
ECase(IMAGE_FILE_MACHINE_I386);
ECase(IMAGE_FILE_MACHINE_IA64);
@@ -187,6 +212,24 @@ void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset(
#undef BCase
namespace {
+struct NSectionSelectionType {
+ NSectionSelectionType(IO &)
+ : SelectionType(COFFYAML::COMDATType(0)) {}
+ NSectionSelectionType(IO &, uint8_t C)
+ : SelectionType(COFFYAML::COMDATType(C)) {}
+ uint8_t denormalize(IO &) { return SelectionType; }
+ COFFYAML::COMDATType SelectionType;
+};
+
+struct NWeakExternalCharacteristics {
+ NWeakExternalCharacteristics(IO &)
+ : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {}
+ NWeakExternalCharacteristics(IO &, uint32_t C)
+ : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {}
+ uint32_t denormalize(IO &) { return Characteristics; }
+ COFFYAML::WeakExternalCharacteristics Characteristics;
+};
+
struct NSectionCharacteristics {
NSectionCharacteristics(IO &)
: Characteristics(COFF::SectionCharacteristics(0)) {}
@@ -196,6 +239,15 @@ struct NSectionCharacteristics {
COFF::SectionCharacteristics Characteristics;
};
+struct NAuxTokenType {
+ NAuxTokenType(IO &)
+ : AuxType(COFFYAML::AuxSymbolType(0)) {}
+ NAuxTokenType(IO &, uint8_t C)
+ : AuxType(COFFYAML::AuxSymbolType(C)) {}
+ uint32_t denormalize(IO &) { return AuxType; }
+ COFFYAML::AuxSymbolType AuxType;
+};
+
struct NStorageClass {
NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {}
NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {}
@@ -247,6 +299,48 @@ void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
IO.mapOptional("Characteristics", NC->Characteristics);
}
+void MappingTraits<COFF::AuxiliaryFunctionDefinition>::mapping(
+ IO &IO, COFF::AuxiliaryFunctionDefinition &AFD) {
+ IO.mapRequired("TagIndex", AFD.TagIndex);
+ IO.mapRequired("TotalSize", AFD.TotalSize);
+ IO.mapRequired("PointerToLinenumber", AFD.PointerToLinenumber);
+ IO.mapRequired("PointerToNextFunction", AFD.PointerToNextFunction);
+}
+
+void MappingTraits<COFF::AuxiliarybfAndefSymbol>::mapping(
+ IO &IO, COFF::AuxiliarybfAndefSymbol &AAS) {
+ IO.mapRequired("Linenumber", AAS.Linenumber);
+ IO.mapRequired("PointerToNextFunction", AAS.PointerToNextFunction);
+}
+
+void MappingTraits<COFF::AuxiliaryWeakExternal>::mapping(
+ IO &IO, COFF::AuxiliaryWeakExternal &AWE) {
+ MappingNormalization<NWeakExternalCharacteristics, uint32_t> NWEC(
+ IO, AWE.Characteristics);
+ IO.mapRequired("TagIndex", AWE.TagIndex);
+ IO.mapRequired("Characteristics", NWEC->Characteristics);
+}
+
+void MappingTraits<COFF::AuxiliarySectionDefinition>::mapping(
+ IO &IO, COFF::AuxiliarySectionDefinition &ASD) {
+ MappingNormalization<NSectionSelectionType, uint8_t> NSST(
+ IO, ASD.Selection);
+
+ IO.mapRequired("Length", ASD.Length);
+ IO.mapRequired("NumberOfRelocations", ASD.NumberOfRelocations);
+ IO.mapRequired("NumberOfLinenumbers", ASD.NumberOfLinenumbers);
+ IO.mapRequired("CheckSum", ASD.CheckSum);
+ IO.mapRequired("Number", ASD.Number);
+ IO.mapOptional("Selection", NSST->SelectionType, COFFYAML::COMDATType(0));
+}
+
+void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
+ IO &IO, COFF::AuxiliaryCLRToken &ACT) {
+ MappingNormalization<NAuxTokenType, uint8_t> NATT(IO, ACT.AuxType);
+ IO.mapRequired("AuxType", NATT->AuxType);
+ IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
+}
+
void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass);
@@ -256,9 +350,12 @@ void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
IO.mapRequired("SimpleType", S.SimpleType);
IO.mapRequired("ComplexType", S.ComplexType);
IO.mapRequired("StorageClass", NS->StorageClass);
- IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols,
- (uint8_t) 0);
- IO.mapOptional("AuxiliaryData", S.AuxiliaryData, object::yaml::BinaryRef());
+ IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
+ IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
+ IO.mapOptional("WeakExternal", S.WeakExternal);
+ IO.mapOptional("File", S.File, StringRef());
+ IO.mapOptional("SectionDefinition", S.SectionDefinition);
+ IO.mapOptional("CLRToken", S.CLRToken);
}
void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
diff --git a/lib/Object/ELF.cpp b/lib/Object/ELF.cpp
index 7c80d41..e9a88bf 100644
--- a/lib/Object/ELF.cpp
+++ b/lib/Object/ELF.cpp
@@ -170,6 +170,8 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_DISP);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_PAGE);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_OFST);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_GD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_LDM);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_DTPREL_HI16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_DTPREL_LO16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_TPREL_HI16);
@@ -702,6 +704,98 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
break;
}
break;
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ case ELF::EM_SPARCV9:
+ switch (Type) {
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_NONE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP30);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HI22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_13);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LO10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOT10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOT13);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOT22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WPLT30);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_COPY);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GLOB_DAT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_JMP_SLOT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_RELATIVE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_UA32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PLT32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HIPLT22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LOPLT10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PCPLT32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PCPLT22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PCPLT10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_11);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_OLO10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HH22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HM10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LM22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC_HH22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC_HM10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PC_LM22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_WDISP19);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_7);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_5);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_6);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_DISP64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_PLT64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_HIX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_LOX10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_H44);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_M44);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_L44);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_REGISTER);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_UA64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_UA16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_HI22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_LO10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_ADD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_GD_CALL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_HI22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_LO10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_ADD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDM_CALL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDO_HIX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDO_LOX10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LDO_ADD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_HI22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_LO10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_LD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_LDX);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_IE_ADD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LE_HIX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_LE_LOX10);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPMOD32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPMOD64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPOFF32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_DTPOFF64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_TPOFF32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_TLS_TPOFF64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_HIX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_LOX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_OP_HIX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_OP_LOX22);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_SPARC_GOTDATA_OP);
+ default:
+ break;
+ }
+ break;
default:
break;
}
diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp
index 20b7307..a2c4df2 100644
--- a/lib/Object/ELFObjectFile.cpp
+++ b/lib/Object/ELFObjectFile.cpp
@@ -14,62 +14,72 @@
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/MathExtras.h"
-#include <ctype.h>
-
namespace llvm {
using namespace object;
-// Creates an in-memory object-file by default: createELFObjectFile(Buffer)
-ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
- std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
- error_code ec;
-
+ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj,
+ bool BufferOwned) {
+ std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
std::size_t MaxAlignment =
- 1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart()));
+ 1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
+ error_code EC;
+ std::unique_ptr<ObjectFile> R;
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::little, 4, false> >(
+ Obj, EC, BufferOwned));
else
#endif
if (MaxAlignment >= 2)
- return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::little, 2, false> >(
+ Obj, EC, BufferOwned));
else
llvm_unreachable("Invalid alignment for ELF file!");
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::big, 4, false> >(Obj, EC,
+ BufferOwned));
else
#endif
if (MaxAlignment >= 2)
- return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::big, 2, false> >(Obj, EC,
+ BufferOwned));
else
llvm_unreachable("Invalid alignment for ELF file!");
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::big, 8, true> >(Obj, EC,
+ BufferOwned));
else
#endif
if (MaxAlignment >= 2)
- return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::big, 2, true> >(Obj, EC,
+ BufferOwned));
else
llvm_unreachable("Invalid alignment for ELF file!");
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::little, 8, true> >(
+ Obj, EC, BufferOwned));
else
#endif
if (MaxAlignment >= 2)
- return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
+ R.reset(new ELFObjectFile<ELFType<support::little, 2, true> >(
+ Obj, EC, BufferOwned));
else
llvm_unreachable("Invalid alignment for ELF file!");
}
+ else
+ report_fatal_error("Buffer is not an ELF object file!");
- report_fatal_error("Buffer is not an ELF object file!");
+ if (EC)
+ return EC;
+ return R.release();
}
} // end namespace llvm
diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp
index 2f35cf9..d513670 100644
--- a/lib/Object/ELFYAML.cpp
+++ b/lib/Object/ELFYAML.cpp
@@ -237,6 +237,48 @@ void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
#undef ECase
}
+void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
+ ELFYAML::ELF_EF &Value) {
+#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
+ BCase(EF_ARM_SOFT_FLOAT)
+ BCase(EF_ARM_VFP_FLOAT)
+ BCase(EF_ARM_EABI_UNKNOWN)
+ BCase(EF_ARM_EABI_VER1)
+ BCase(EF_ARM_EABI_VER2)
+ BCase(EF_ARM_EABI_VER3)
+ BCase(EF_ARM_EABI_VER4)
+ BCase(EF_ARM_EABI_VER5)
+ BCase(EF_ARM_EABIMASK)
+ BCase(EF_MIPS_NOREORDER)
+ BCase(EF_MIPS_PIC)
+ BCase(EF_MIPS_CPIC)
+ BCase(EF_MIPS_ABI2)
+ BCase(EF_MIPS_32BITMODE)
+ BCase(EF_MIPS_ABI_O32)
+ BCase(EF_MIPS_MICROMIPS)
+ BCase(EF_MIPS_ARCH_ASE_M16)
+ BCase(EF_MIPS_ARCH_1)
+ BCase(EF_MIPS_ARCH_2)
+ BCase(EF_MIPS_ARCH_3)
+ BCase(EF_MIPS_ARCH_4)
+ BCase(EF_MIPS_ARCH_5)
+ BCase(EF_MIPS_ARCH_32)
+ BCase(EF_MIPS_ARCH_64)
+ BCase(EF_MIPS_ARCH_32R2)
+ BCase(EF_MIPS_ARCH_64R2)
+ BCase(EF_MIPS_ARCH)
+ BCase(EF_HEXAGON_MACH_V2)
+ BCase(EF_HEXAGON_MACH_V3)
+ BCase(EF_HEXAGON_MACH_V4)
+ BCase(EF_HEXAGON_MACH_V5)
+ BCase(EF_HEXAGON_ISA_MACH)
+ BCase(EF_HEXAGON_ISA_V2)
+ BCase(EF_HEXAGON_ISA_V3)
+ BCase(EF_HEXAGON_ISA_V4)
+ BCase(EF_HEXAGON_ISA_V5)
+#undef BCase
+}
+
void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
IO &IO, ELFYAML::ELF_SHT &Value) {
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
@@ -299,6 +341,7 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
IO.mapRequired("Type", FileHdr.Type);
IO.mapRequired("Machine", FileHdr.Machine);
+ IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
}
diff --git a/lib/Object/Error.cpp b/lib/Object/Error.cpp
index 47ce38c..8e50869 100644
--- a/lib/Object/Error.cpp
+++ b/lib/Object/Error.cpp
@@ -18,11 +18,11 @@ using namespace llvm;
using namespace object;
namespace {
-class _object_error_category : public _do_message {
+class _object_error_category : public error_category {
public:
- virtual const char* name() const;
- virtual std::string message(int ev) const;
- virtual error_condition default_error_condition(int ev) const;
+ const char* name() const override;
+ std::string message(int ev) const override;
+ error_condition default_error_condition(int ev) const override;
};
}
diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp
new file mode 100644
index 0000000..a8aba26
--- /dev/null
+++ b/lib/Object/IRObjectFile.cpp
@@ -0,0 +1,151 @@
+//===- IRObjectFile.cpp - 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Part of the IRObjectFile class implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+using namespace object;
+
+IRObjectFile::IRObjectFile(MemoryBuffer *Object, error_code &EC,
+ LLVMContext &Context, bool BufferOwned)
+ : SymbolicFile(Binary::ID_IR, Object, BufferOwned) {
+ ErrorOr<Module*> MOrErr = parseBitcodeFile(Object, Context);
+ if ((EC = MOrErr.getError()))
+ return;
+
+ M.reset(MOrErr.get());
+
+ // If we have a DataLayout, setup a mangler.
+ const DataLayout *DL = M->getDataLayout();
+ if (!DL)
+ return;
+
+ Mang.reset(new Mangler(DL));
+}
+
+static const GlobalValue &getGV(DataRefImpl &Symb) {
+ return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
+}
+
+static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
+ if (I == M.alias_end())
+ return 3;
+ const GlobalValue *GV = &*I;
+ return reinterpret_cast<uintptr_t>(GV) | 2;
+}
+
+static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
+ if (I == M.global_end())
+ return skipEmpty(M.alias_begin(), M);
+ const GlobalValue *GV = &*I;
+ return reinterpret_cast<uintptr_t>(GV) | 1;
+}
+
+static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
+ if (I == M.end())
+ return skipEmpty(M.global_begin(), M);
+ const GlobalValue *GV = &*I;
+ return reinterpret_cast<uintptr_t>(GV) | 0;
+}
+
+void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
+ const GlobalValue *GV = &getGV(Symb);
+ const Module &M = *GV->getParent();
+ uintptr_t Res;
+ switch (Symb.p & 3) {
+ case 0: {
+ Module::const_iterator Iter(static_cast<const Function*>(GV));
+ ++Iter;
+ Res = skipEmpty(Iter, M);
+ break;
+ }
+ case 1: {
+ Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
+ ++Iter;
+ Res = skipEmpty(Iter, M);
+ break;
+ }
+ case 2: {
+ Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
+ ++Iter;
+ Res = skipEmpty(Iter, M);
+ break;
+ }
+ case 3:
+ llvm_unreachable("Invalid symbol reference");
+ }
+
+ Symb.p = Res;
+}
+
+error_code IRObjectFile::printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const {
+ const GlobalValue &GV = getGV(Symb);
+
+ if (Mang)
+ Mang->getNameWithPrefix(OS, &GV, false);
+ else
+ OS << GV.getName();
+
+ return object_error::success;
+}
+
+uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
+ const GlobalValue &GV = getGV(Symb);
+
+ uint32_t Res = BasicSymbolRef::SF_None;
+ if (GV.isDeclaration() || GV.hasAvailableExternallyLinkage())
+ Res |= BasicSymbolRef::SF_Undefined;
+ if (GV.hasPrivateLinkage())
+ Res |= BasicSymbolRef::SF_FormatSpecific;
+ if (!GV.hasLocalLinkage())
+ Res |= BasicSymbolRef::SF_Global;
+ if (GV.hasCommonLinkage())
+ Res |= BasicSymbolRef::SF_Common;
+ if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage())
+ Res |= BasicSymbolRef::SF_Weak;
+
+ return Res;
+}
+
+const GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
+ const GlobalValue &GV = getGV(Symb);
+ return GV;
+}
+
+basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
+ Module::const_iterator I = M->begin();
+ DataRefImpl Ret;
+ Ret.p = skipEmpty(I, *M);
+ return basic_symbol_iterator(BasicSymbolRef(Ret, this));
+}
+
+basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
+ DataRefImpl Ret;
+ Ret.p = 3;
+ return basic_symbol_iterator(BasicSymbolRef(Ret, this));
+}
+
+ErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile(
+ MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) {
+ error_code EC;
+ std::unique_ptr<IRObjectFile> Ret(
+ new IRObjectFile(Object, EC, Context, BufferOwned));
+ if (EC)
+ return EC;
+ return Ret.release();
+}
diff --git a/lib/Object/LLVMBuild.txt b/lib/Object/LLVMBuild.txt
index 69610f9..a87da6e 100644
--- a/lib/Object/LLVMBuild.txt
+++ b/lib/Object/LLVMBuild.txt
@@ -19,4 +19,4 @@
type = Library
name = Object
parent = Libraries
-required_libraries = Support
+required_libraries = Support BitReader
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index d2cb8bd..12132a4 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/MachO.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
@@ -214,6 +215,14 @@ void SwapStruct(MachO::linker_options_command &C) {
}
template<>
+void SwapStruct(MachO::version_min_command&C) {
+ SwapValue(C.cmd);
+ SwapValue(C.cmdsize);
+ SwapValue(C.version);
+ SwapValue(C.reserved);
+}
+
+template<>
void SwapStruct(MachO::data_in_code_entry &C) {
SwapValue(C.offset);
SwapValue(C.length);
@@ -275,18 +284,9 @@ static StringRef parseSegmentOrSectionName(const char *P) {
// Helper to advance a section or symbol iterator multiple increments at a time.
template<class T>
-static error_code advance(T &it, size_t Val) {
- error_code ec;
- while (Val--) {
- it.increment(ec);
- }
- return ec;
-}
-
-template<class T>
-static void advanceTo(T &it, size_t Val) {
- if (error_code ec = advance(it, Val))
- report_fatal_error(ec.message());
+static void advance(T &it, size_t Val) {
+ while (Val--)
+ ++it;
}
static unsigned getCPUType(const MachOObjectFile *O) {
@@ -305,18 +305,16 @@ static void printRelocationTargetName(const MachOObjectFile *O,
if (IsScattered) {
uint32_t Val = O->getPlainRelocationSymbolNum(RE);
- error_code ec;
- for (symbol_iterator SI = O->begin_symbols(), SE = O->end_symbols();
- SI != SE; SI.increment(ec)) {
- if (ec) report_fatal_error(ec.message());
-
+ for (const SymbolRef &Symbol : O->symbols()) {
+ error_code ec;
uint64_t Addr;
StringRef Name;
- if ((ec = SI->getAddress(Addr)))
+ if ((ec = Symbol.getAddress(Addr)))
report_fatal_error(ec.message());
- if (Addr != Val) continue;
- if ((ec = SI->getName(Name)))
+ if (Addr != Val)
+ continue;
+ if ((ec = Symbol.getName(Name)))
report_fatal_error(ec.message());
fmt << Name;
return;
@@ -324,17 +322,16 @@ static void printRelocationTargetName(const MachOObjectFile *O,
// If we couldn't find a symbol that this relocation refers to, try
// to find a section beginning instead.
- for (section_iterator SI = O->begin_sections(), SE = O->end_sections();
- SI != SE; SI.increment(ec)) {
- if (ec) report_fatal_error(ec.message());
-
+ for (const SectionRef &Section : O->sections()) {
+ error_code ec;
uint64_t Addr;
StringRef Name;
- if ((ec = SI->getAddress(Addr)))
+ if ((ec = Section.getAddress(Addr)))
report_fatal_error(ec.message());
- if (Addr != Val) continue;
- if ((ec = SI->getName(Name)))
+ if (Addr != Val)
+ continue;
+ if ((ec = Section.getName(Name)))
report_fatal_error(ec.message());
fmt << Name;
return;
@@ -349,13 +346,13 @@ static void printRelocationTargetName(const MachOObjectFile *O,
uint64_t Val = O->getPlainRelocationSymbolNum(RE);
if (isExtern) {
- symbol_iterator SI = O->begin_symbols();
- advanceTo(SI, Val);
+ symbol_iterator SI = O->symbol_begin();
+ advance(SI, Val);
SI->getName(S);
} else {
- section_iterator SI = O->begin_sections();
+ section_iterator SI = O->section_begin();
// Adjust for the fact that sections are 1-indexed.
- advanceTo(SI, Val - 1);
+ advance(SI, Val - 1);
SI->getName(S);
}
@@ -419,10 +416,10 @@ static uint32_t getSectionFlags(const MachOObjectFile *O,
return Sect.flags;
}
-MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
- bool IsLittleEndian, bool Is64bits,
- error_code &ec)
- : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
+MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
+ bool Is64bits, error_code &EC,
+ bool BufferOwned)
+ : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
MachO::LoadCommandType SegmentLoadType = is64Bit() ?
@@ -454,14 +451,11 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
}
}
-error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb,
- SymbolRef &Res) const {
+void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
unsigned SymbolTableEntrySize = is64Bit() ?
sizeof(MachO::nlist_64) :
sizeof(MachO::nlist);
Symb.p += SymbolTableEntrySize;
- Res = SymbolRef(Symb, this);
- return object_error::success;
}
error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
@@ -485,33 +479,9 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
return object_error::success;
}
-error_code
-MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
- uint64_t &Res) const {
- nlist_base Entry = getSymbolTableEntryBase(this, Symb);
- getSymbolAddress(Symb, Res);
- if (Entry.n_sect) {
- uint64_t Delta;
- DataRefImpl SecRel;
- SecRel.d.a = Entry.n_sect-1;
- if (is64Bit()) {
- MachO::section_64 Sec = getSection64(SecRel);
- Delta = Sec.offset - Sec.addr;
- } else {
- MachO::section Sec = getSection(SecRel);
- Delta = Sec.offset - Sec.addr;
- }
-
- Res += Delta;
- }
-
- return object_error::success;
-}
-
error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
uint32_t &Result) const {
- uint32_t flags;
- this->getSymbolFlags(DRI, flags);
+ uint32_t flags = getSymbolFlags(DRI);
if (flags & SymbolRef::SF_Common) {
nlist_base Entry = getSymbolTableEntryBase(this, DRI);
Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc);
@@ -535,8 +505,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
SectionIndex = Entry.n_sect;
if (!SectionIndex) {
- uint32_t flags = SymbolRef::SF_None;
- this->getSymbolFlags(DRI, flags);
+ uint32_t flags = getSymbolFlags(DRI);
if (flags & SymbolRef::SF_Common)
Result = Value;
else
@@ -545,10 +514,8 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
}
// Unfortunately symbols are unsorted so we need to touch all
// symbols from load command
- error_code ec;
- for (symbol_iterator I = begin_symbols(), E = end_symbols(); I != E;
- I.increment(ec)) {
- DataRefImpl DRI = I->getRawDataRefImpl();
+ for (const SymbolRef &Symbol : symbols()) {
+ DataRefImpl DRI = Symbol.getRawDataRefImpl();
Entry = getSymbolTableEntryBase(this, DRI);
getSymbolAddress(DRI, Value);
if (Entry.n_sect == SectionIndex && Value > BeginOffset)
@@ -591,15 +558,13 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
return object_error::success;
}
-error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
- uint32_t &Result) const {
+uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
nlist_base Entry = getSymbolTableEntryBase(this, DRI);
uint8_t MachOType = Entry.n_type;
uint16_t MachOFlags = Entry.n_desc;
- // TODO: Correctly set SF_ThreadLocal
- Result = SymbolRef::SF_None;
+ uint32_t Result = SymbolRef::SF_None;
if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
Result |= SymbolRef::SF_Undefined;
@@ -623,7 +588,7 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
if ((MachOType & MachO::N_TYPE) == MachO::N_ABS)
Result |= SymbolRef::SF_Absolute;
- return object_error::success;
+ return Result;
}
error_code
@@ -633,7 +598,7 @@ MachOObjectFile::getSymbolSection(DataRefImpl Symb,
uint8_t index = Entry.n_sect;
if (index == 0) {
- Res = end_sections();
+ Res = section_end();
} else {
DataRefImpl DRI;
DRI.d.a = index - 1;
@@ -643,16 +608,8 @@ MachOObjectFile::getSymbolSection(DataRefImpl Symb,
return object_error::success;
}
-error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
- uint64_t &Val) const {
- report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
-}
-
-error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,
- SectionRef &Res) const {
+void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
Sec.d.a++;
- Res = SectionRef(Sec, this);
- return object_error::success;
}
error_code
@@ -834,13 +791,20 @@ MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
return relocation_iterator(RelocationRef(Ret, this));
}
-error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const {
+bool MachOObjectFile::section_rel_empty(DataRefImpl Sec) const {
+ if (is64Bit()) {
+ MachO::section_64 Sect = getSection64(Sec);
+ return Sect.nreloc == 0;
+ } else {
+ MachO::section Sect = getSection(Sec);
+ return Sect.nreloc == 0;
+ }
+}
+
+void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
const MachO::any_relocation_info *P =
reinterpret_cast<const MachO::any_relocation_info *>(Rel.p);
Rel.p = reinterpret_cast<uintptr_t>(P + 1);
- Res = RelocationRef(Rel, this);
- return object_error::success;
}
error_code
@@ -861,7 +825,7 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
bool isExtern = getPlainRelocationExternal(RE);
if (!isExtern)
- return end_symbols();
+ return symbol_end();
MachO::symtab_command S = getSymtabLoadCommand();
unsigned SymbolTableEntrySize = is64Bit() ?
@@ -899,7 +863,7 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
"GENERIC_RELOC_LOCAL_SECTDIFF",
"GENERIC_RELOC_TLV" };
- if (RType > 6)
+ if (RType > 5)
res = "Unknown";
else
res = Table[RType];
@@ -943,6 +907,23 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
res = Table[RType];
break;
}
+ case Triple::arm64:
+ case Triple::aarch64: {
+ static const char *const Table[] = {
+ "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR",
+ "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21",
+ "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21",
+ "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
+ "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
+ "ARM64_RELOC_ADDEND"
+ };
+
+ if (RType >= array_lengthof(Table))
+ res = "Unknown";
+ else
+ res = Table[RType];
+ break;
+ }
case Triple::ppc: {
static const char *const Table[] = {
"PPC_RELOC_VANILLA",
@@ -962,7 +943,10 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
"PPC_RELOC_LO14_SECTDIFF",
"PPC_RELOC_LOCAL_SECTDIFF" };
- res = Table[RType];
+ if (RType > 15)
+ res = "Unknown";
+ else
+ res = Table[RType];
break;
}
case Triple::UnknownArch:
@@ -1187,20 +1171,20 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}
-symbol_iterator MachOObjectFile::begin_symbols() const {
+basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
DataRefImpl DRI;
if (!SymtabLoadCmd)
- return symbol_iterator(SymbolRef(DRI, this));
+ return basic_symbol_iterator(SymbolRef(DRI, this));
MachO::symtab_command Symtab = getSymtabLoadCommand();
DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
- return symbol_iterator(SymbolRef(DRI, this));
+ return basic_symbol_iterator(SymbolRef(DRI, this));
}
-symbol_iterator MachOObjectFile::end_symbols() const {
+basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
DataRefImpl DRI;
if (!SymtabLoadCmd)
- return symbol_iterator(SymbolRef(DRI, this));
+ return basic_symbol_iterator(SymbolRef(DRI, this));
MachO::symtab_command Symtab = getSymtabLoadCommand();
unsigned SymbolTableEntrySize = is64Bit() ?
@@ -1209,36 +1193,26 @@ symbol_iterator MachOObjectFile::end_symbols() const {
unsigned Offset = Symtab.symoff +
Symtab.nsyms * SymbolTableEntrySize;
DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
- return symbol_iterator(SymbolRef(DRI, this));
-}
-
-symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
- // TODO: implement
- report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
-}
-
-symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
- // TODO: implement
- report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
+ return basic_symbol_iterator(SymbolRef(DRI, this));
}
-section_iterator MachOObjectFile::begin_sections() const {
+section_iterator MachOObjectFile::section_begin() const {
DataRefImpl DRI;
return section_iterator(SectionRef(DRI, this));
}
-section_iterator MachOObjectFile::end_sections() const {
+section_iterator MachOObjectFile::section_end() const {
DataRefImpl DRI;
DRI.d.a = Sections.size();
return section_iterator(SectionRef(DRI, this));
}
-library_iterator MachOObjectFile::begin_libraries_needed() const {
+library_iterator MachOObjectFile::needed_library_begin() const {
// TODO: implement
report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}
-library_iterator MachOObjectFile::end_libraries_needed() const {
+library_iterator MachOObjectFile::needed_library_end() const {
// TODO: implement
report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}
@@ -1272,6 +1246,8 @@ StringRef MachOObjectFile::getFileFormatName() const {
switch (CPUType) {
case llvm::MachO::CPU_TYPE_X86_64:
return "Mach-O 64-bit x86-64";
+ case llvm::MachO::CPU_TYPE_ARM64:
+ return "Mach-O arm64";
case llvm::MachO::CPU_TYPE_POWERPC64:
return "Mach-O 64-bit ppc64";
default:
@@ -1287,6 +1263,8 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
return Triple::x86_64;
case llvm::MachO::CPU_TYPE_ARM:
return Triple::arm;
+ case llvm::MachO::CPU_TYPE_ARM64:
+ return Triple::arm64;
case llvm::MachO::CPU_TYPE_POWERPC:
return Triple::ppc;
case llvm::MachO::CPU_TYPE_POWERPC64:
@@ -1423,7 +1401,7 @@ SectionRef
MachOObjectFile::getRelocationSection(
const MachO::any_relocation_info &RE) const {
if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
- return *end_sections();
+ return *section_end();
unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
DataRefImpl DRI;
DRI.d.a = SecNum;
@@ -1501,6 +1479,11 @@ MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
return getStruct<MachO::linker_options_command>(this, L.Ptr);
}
+MachO::version_min_command
+MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
+ return getStruct<MachO::version_min_command>(this, L.Ptr);
+}
+
MachO::any_relocation_info
MachOObjectFile::getRelocation(DataRefImpl Rel) const {
const char *P = reinterpret_cast<const char *>(Rel.p);
@@ -1579,26 +1562,27 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index,
}
}
-ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
+ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
+ bool BufferOwned) {
StringRef Magic = Buffer->getBuffer().slice(0, 4);
- error_code ec;
- OwningPtr<ObjectFile> Ret;
+ error_code EC;
+ std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE")
- Ret.reset(new MachOObjectFile(Buffer, false, false, ec));
+ Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
else if (Magic == "\xCE\xFA\xED\xFE")
- Ret.reset(new MachOObjectFile(Buffer, true, false, ec));
+ Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
else if (Magic == "\xFE\xED\xFA\xCF")
- Ret.reset(new MachOObjectFile(Buffer, false, true, ec));
+ Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
else if (Magic == "\xCF\xFA\xED\xFE")
- Ret.reset(new MachOObjectFile(Buffer, true, true, ec));
+ Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
else {
delete Buffer;
- return NULL;
+ return object_error::parse_failed;
}
- if (ec)
- return NULL;
- return Ret.take();
+ if (EC)
+ return EC;
+ return Ret.release();
}
} // end namespace object
diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp
index 75160af..70baa9f 100644
--- a/lib/Object/MachOUniversal.cpp
+++ b/lib/Object/MachOUniversal.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/MachOUniversal.h"
-
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
@@ -73,7 +72,7 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch(
}
error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile(
- OwningPtr<ObjectFile> &Result) const {
+ std::unique_ptr<ObjectFile> &Result) const {
if (Parent) {
StringRef ParentData = Parent->getData();
StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
@@ -82,16 +81,27 @@ error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile(
Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
ObjectData, ObjectName, false);
- if (ObjectFile *Obj = ObjectFile::createMachOObjectFile(ObjBuffer)) {
- Result.reset(Obj);
- return object_error::success;
- }
+ ErrorOr<ObjectFile *> Obj = ObjectFile::createMachOObjectFile(ObjBuffer);
+ if (error_code EC = Obj.getError())
+ return EC;
+ Result.reset(Obj.get());
+ return object_error::success;
}
return object_error::parse_failed;
}
void MachOUniversalBinary::anchor() { }
+ErrorOr<MachOUniversalBinary *>
+MachOUniversalBinary::create(MemoryBuffer *Source) {
+ error_code EC;
+ std::unique_ptr<MachOUniversalBinary> Ret(
+ new MachOUniversalBinary(Source, EC));
+ if (EC)
+ return EC;
+ return Ret.release();
+}
+
MachOUniversalBinary::MachOUniversalBinary(MemoryBuffer *Source,
error_code &ec)
: Binary(Binary::ID_MachOUniversalBinary, Source),
@@ -125,9 +135,8 @@ static bool getCTMForArch(Triple::ArchType Arch, MachO::CPUType &CTM) {
}
}
-error_code
-MachOUniversalBinary::getObjectForArch(Triple::ArchType Arch,
- OwningPtr<ObjectFile> &Result) const {
+error_code MachOUniversalBinary::getObjectForArch(
+ Triple::ArchType Arch, std::unique_ptr<ObjectFile> &Result) const {
MachO::CPUType CTM;
if (!getCTMForArch(Arch, CTM))
return object_error::arch_not_found;
diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp
index 6941708..243bd44 100644
--- a/lib/Object/Object.cpp
+++ b/lib/Object/Object.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm-c/Object.h"
+#include "llvm/Object/ObjectFile.h"
using namespace llvm;
using namespace object;
@@ -59,7 +59,9 @@ wrap(const relocation_iterator *SI) {
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
- return wrap(ObjectFile::createObjectFile(unwrap(MemBuf)));
+ ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf)));
+ ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : 0;
+ return wrap(Obj);
}
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
@@ -68,7 +70,7 @@ void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
// ObjectFile Section iterators
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) {
- section_iterator SI = unwrap(ObjectFile)->begin_sections();
+ section_iterator SI = unwrap(ObjectFile)->section_begin();
return wrap(new section_iterator(SI));
}
@@ -78,13 +80,11 @@ void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
LLVMSectionIteratorRef SI) {
- return (*unwrap(SI) == unwrap(ObjectFile)->end_sections()) ? 1 : 0;
+ return (*unwrap(SI) == unwrap(ObjectFile)->section_end()) ? 1 : 0;
}
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
- error_code ec;
- unwrap(SI)->increment(ec);
- if (ec) report_fatal_error("LLVMMoveToNextSection failed: " + ec.message());
+ ++(*unwrap(SI));
}
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
@@ -95,7 +95,7 @@ void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
// ObjectFile Symbol iterators
LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) {
- symbol_iterator SI = unwrap(ObjectFile)->begin_symbols();
+ symbol_iterator SI = unwrap(ObjectFile)->symbol_begin();
return wrap(new symbol_iterator(SI));
}
@@ -105,13 +105,11 @@ void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
LLVMSymbolIteratorRef SI) {
- return (*unwrap(SI) == unwrap(ObjectFile)->end_symbols()) ? 1 : 0;
+ return (*unwrap(SI) == unwrap(ObjectFile)->symbol_end()) ? 1 : 0;
}
void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
- error_code ec;
- unwrap(SI)->increment(ec);
- if (ec) report_fatal_error("LLVMMoveToNextSymbol failed: " + ec.message());
+ ++(*unwrap(SI));
}
// SectionRef accessors
@@ -153,7 +151,7 @@ LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
// Section Relocation iterators
LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
- relocation_iterator SI = (*unwrap(Section))->begin_relocations();
+ relocation_iterator SI = (*unwrap(Section))->relocation_begin();
return wrap(new relocation_iterator(SI));
}
@@ -163,14 +161,11 @@ void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
LLVMRelocationIteratorRef SI) {
- return (*unwrap(SI) == (*unwrap(Section))->end_relocations()) ? 1 : 0;
+ return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
}
void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
- error_code ec;
- unwrap(SI)->increment(ec);
- if (ec) report_fatal_error("LLVMMoveToNextRelocation failed: " +
- ec.message());
+ ++(*unwrap(SI));
}
diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp
index 0e626d6..d30f0cc 100644
--- a/lib/Object/ObjectFile.cpp
+++ b/lib/Object/ObjectFile.cpp
@@ -12,10 +12,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/ObjectFile.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
using namespace llvm;
@@ -23,8 +23,17 @@ using namespace object;
void ObjectFile::anchor() { }
-ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *source)
- : Binary(Type, source) {
+ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *Source,
+ bool BufferOwned)
+ : SymbolicFile(Type, Source, BufferOwned) {}
+
+error_code ObjectFile::printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const {
+ StringRef Name;
+ if (error_code EC = getSymbolName(Symb, Name))
+ return EC;
+ OS << Name;
+ return object_error::success;
}
error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI,
@@ -37,26 +46,26 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
return section_iterator(SectionRef(Sec, this));
}
-ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
- if (Object->getBufferSize() < 64) {
- delete Object;
- return 0;
- }
+ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
+ bool BufferOwned,
+ sys::fs::file_magic Type) {
+ if (Type == sys::fs::file_magic::unknown)
+ Type = sys::fs::identify_magic(Object->getBuffer());
- sys::fs::file_magic Type = sys::fs::identify_magic(Object->getBuffer());
switch (Type) {
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::bitcode:
case sys::fs::file_magic::archive:
case sys::fs::file_magic::macho_universal_binary:
case sys::fs::file_magic::windows_resource:
- delete Object;
- return 0;
+ if (BufferOwned)
+ delete Object;
+ return object_error::invalid_file_type;
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
case sys::fs::file_magic::elf_core:
- return createELFObjectFile(Object);
+ return createELFObjectFile(Object, BufferOwned);
case sys::fs::file_magic::macho_object:
case sys::fs::file_magic::macho_executable:
case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
@@ -67,18 +76,18 @@ ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
case sys::fs::file_magic::macho_dsym_companion:
- return createMachOObjectFile(Object);
+ return createMachOObjectFile(Object, BufferOwned);
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
- return createCOFFObjectFile(Object);
+ return createCOFFObjectFile(Object, BufferOwned);
}
llvm_unreachable("Unexpected Object File Type");
}
-ObjectFile *ObjectFile::createObjectFile(StringRef ObjectPath) {
- OwningPtr<MemoryBuffer> File;
- if (MemoryBuffer::getFile(ObjectPath, File))
- return NULL;
- return createObjectFile(File.take());
+ErrorOr<ObjectFile *> ObjectFile::createObjectFile(StringRef ObjectPath) {
+ std::unique_ptr<MemoryBuffer> File;
+ if (error_code EC = MemoryBuffer::getFile(ObjectPath, File))
+ return EC;
+ return createObjectFile(File.release());
}
diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp
new file mode 100644
index 0000000..495f0b6
--- /dev/null
+++ b/lib/Object/SymbolicFile.cpp
@@ -0,0 +1,67 @@
+//===- SymbolicFile.cpp - 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 defines a file format independent SymbolicFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace object;
+
+SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source,
+ bool BufferOwned)
+ : Binary(Type, Source, BufferOwned) {}
+
+SymbolicFile::~SymbolicFile() {}
+
+ErrorOr<SymbolicFile *>
+SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
+ sys::fs::file_magic Type,
+ LLVMContext *Context) {
+ if (Type == sys::fs::file_magic::unknown)
+ Type = sys::fs::identify_magic(Object->getBuffer());
+
+ switch (Type) {
+ case sys::fs::file_magic::bitcode:
+ if (Context)
+ return IRObjectFile::createIRObjectFile(Object, *Context, BufferOwned);
+ // Fallthrough
+ case sys::fs::file_magic::unknown:
+ case sys::fs::file_magic::archive:
+ case sys::fs::file_magic::macho_universal_binary:
+ case sys::fs::file_magic::windows_resource:
+ if (BufferOwned)
+ delete Object;
+ return object_error::invalid_file_type;
+ case sys::fs::file_magic::elf_relocatable:
+ case sys::fs::file_magic::elf_executable:
+ case sys::fs::file_magic::elf_shared_object:
+ case sys::fs::file_magic::elf_core:
+ case sys::fs::file_magic::macho_object:
+ case sys::fs::file_magic::macho_executable:
+ case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
+ case sys::fs::file_magic::macho_core:
+ case sys::fs::file_magic::macho_preload_executable:
+ case sys::fs::file_magic::macho_dynamically_linked_shared_lib:
+ case sys::fs::file_magic::macho_dynamic_linker:
+ case sys::fs::file_magic::macho_bundle:
+ case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
+ case sys::fs::file_magic::macho_dsym_companion:
+ case sys::fs::file_magic::coff_object:
+ case sys::fs::file_magic::coff_import_library:
+ case sys::fs::file_magic::pecoff_executable:
+ return ObjectFile::createObjectFile(Object, BufferOwned, Type);
+ }
+ llvm_unreachable("Unexpected Binary File Type");
+}
diff --git a/lib/Object/YAML.cpp b/lib/Object/YAML.cpp
index c527bde..61e9da3 100644
--- a/lib/Object/YAML.cpp
+++ b/lib/Object/YAML.cpp
@@ -51,10 +51,8 @@ void BinaryRef::writeAsBinary(raw_ostream &OS) const {
}
void BinaryRef::writeAsHex(raw_ostream &OS) const {
- if (binary_size() == 0) {
- OS << "\"\"";
+ if (binary_size() == 0)
return;
- }
if (DataIsHexString) {
OS.write((const char *)Data.data(), Data.size());
return;