aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Object
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Object')
-rw-r--r--lib/Object/Android.mk8
-rw-r--r--lib/Object/Archive.cpp182
-rw-r--r--lib/Object/Binary.cpp28
-rw-r--r--lib/Object/CMakeLists.txt3
-rw-r--r--lib/Object/COFFObjectFile.cpp287
-rw-r--r--lib/Object/ELFObjectFile.cpp51
-rw-r--r--lib/Object/ELFYAML.cpp13
-rw-r--r--lib/Object/Error.cpp17
-rw-r--r--lib/Object/IRObjectFile.cpp208
-rw-r--r--lib/Object/LLVMBuild.txt2
-rw-r--r--lib/Object/MachOObjectFile.cpp696
-rw-r--r--lib/Object/MachOUniversal.cpp75
-rw-r--r--lib/Object/Object.cpp32
-rw-r--r--lib/Object/ObjectFile.cpp38
-rw-r--r--lib/Object/RecordStreamer.cpp100
-rw-r--r--lib/Object/RecordStreamer.h42
-rw-r--r--lib/Object/StringTableBuilder.cpp51
-rw-r--r--lib/Object/SymbolicFile.cpp14
-rw-r--r--lib/Object/YAML.cpp66
19 files changed, 1225 insertions, 688 deletions
diff --git a/lib/Object/Android.mk b/lib/Object/Android.mk
index 4385f5a..acda4f2 100644
--- a/lib/Object/Android.mk
+++ b/lib/Object/Android.mk
@@ -7,17 +7,15 @@ object_SRC_FILES := \
COFFYAML.cpp \
ELF.cpp \
ELFObjectFile.cpp \
+ ELFYAML.cpp \
Error.cpp \
IRObjectFile.cpp \
MachOObjectFile.cpp \
MachOUniversal.cpp \
Object.cpp \
ObjectFile.cpp \
- StringTableBuilder.cpp \
- SymbolicFile.cpp \
- YAML.cpp \
- ELFYAML.cpp \
-
+ RecordStreamer.cpp \
+ SymbolicFile.cpp
# For the host
# =====================================================
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp
index 304ca47..6d09bdb 100644
--- a/lib/Object/Archive.cpp
+++ b/lib/Object/Archive.cpp
@@ -115,18 +115,14 @@ Archive::Child Archive::Child::getNext() const {
return Child(Parent, NextLoc);
}
-error_code Archive::Child::getName(StringRef &Result) const {
+ErrorOr<StringRef> Archive::Child::getName() const {
StringRef name = getRawName();
// Check if it's a special name.
if (name[0] == '/') {
- if (name.size() == 1) { // Linker member.
- Result = name;
- return object_error::success;
- }
- if (name.size() == 2 && name[1] == '/') { // String table.
- Result = name;
- return object_error::success;
- }
+ if (name.size() == 1) // Linker member.
+ return name;
+ if (name.size() == 2 && name[1] == '/') // String table.
+ return name;
// It's a long name.
// Get the offset.
std::size_t offset;
@@ -147,68 +143,62 @@ error_code Archive::Child::getName(StringRef &Result) const {
// GNU long file names end with a /.
if (Parent->kind() == K_GNU) {
StringRef::size_type End = StringRef(addr).find('/');
- Result = StringRef(addr, End);
- } else {
- Result = addr;
+ return StringRef(addr, End);
}
- return object_error::success;
+ return StringRef(addr);
} else if (name.startswith("#1/")) {
uint64_t name_size;
if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
llvm_unreachable("Long name length is not an ingeter");
- Result = Data.substr(sizeof(ArchiveMemberHeader), name_size)
+ return Data.substr(sizeof(ArchiveMemberHeader), name_size)
.rtrim(StringRef("\0", 1));
- return object_error::success;
}
// It's a simple name.
if (name[name.size() - 1] == '/')
- Result = name.substr(0, name.size() - 1);
- else
- Result = name;
- return object_error::success;
+ return name.substr(0, name.size() - 1);
+ return name;
}
-error_code Archive::Child::getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
- bool FullPath) const {
- StringRef Name;
- if (error_code ec = getName(Name))
- return ec;
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+Archive::Child::getMemoryBuffer(bool FullPath) const {
+ ErrorOr<StringRef> NameOrErr = getName();
+ if (std::error_code EC = NameOrErr.getError())
+ return EC;
+ StringRef Name = NameOrErr.get();
SmallString<128> Path;
- Result.reset(MemoryBuffer::getMemBuffer(
- getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name + ")")
- .toStringRef(Path)
- : Name,
+ std::unique_ptr<MemoryBuffer> Ret(MemoryBuffer::getMemBuffer(
+ getBuffer(),
+ FullPath
+ ? (Twine(Parent->getFileName()) + "(" + Name + ")").toStringRef(Path)
+ : Name,
false));
- return error_code::success();
+ return std::move(Ret);
}
-error_code Archive::Child::getAsBinary(std::unique_ptr<Binary> &Result,
- LLVMContext *Context) const {
+ErrorOr<std::unique_ptr<Binary>>
+Archive::Child::getAsBinary(LLVMContext *Context) const {
std::unique_ptr<Binary> ret;
- std::unique_ptr<MemoryBuffer> Buff;
- if (error_code ec = getMemoryBuffer(Buff))
- return ec;
- ErrorOr<Binary *> BinaryOrErr = createBinary(Buff.release(), Context);
- if (error_code EC = BinaryOrErr.getError())
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = getMemoryBuffer();
+ if (std::error_code EC = BuffOrErr.getError())
return EC;
- Result.reset(BinaryOrErr.get());
- return object_error::success;
+
+ std::unique_ptr<MemoryBuffer> Buff(BuffOrErr.get().release());
+ return createBinary(Buff, Context);
}
-ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
- error_code EC;
- std::unique_ptr<Archive> Ret(new Archive(Source, EC));
+ErrorOr<Archive *> Archive::create(std::unique_ptr<MemoryBuffer> Source) {
+ std::error_code EC;
+ std::unique_ptr<Archive> Ret(new Archive(std::move(Source), EC));
if (EC)
return EC;
return Ret.release();
}
-Archive::Archive(MemoryBuffer *source, error_code &ec)
- : Binary(Binary::ID_Archive, source), SymbolTable(child_end()) {
+Archive::Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &ec)
+ : Binary(Binary::ID_Archive, std::move(Source)), SymbolTable(child_end()) {
// Check for sufficient magic.
- assert(source);
- if (source->getBufferSize() < 8 ||
- StringRef(source->getBufferStart(), 8) != Magic) {
+ if (Data->getBufferSize() < 8 ||
+ StringRef(Data->getBufferStart(), 8) != Magic) {
ec = object_error::invalid_file_type;
return;
}
@@ -255,9 +245,11 @@ Archive::Archive(MemoryBuffer *source, error_code &ec)
if (Name.startswith("#1/")) {
Format = K_BSD;
// We know this is BSD, so getName will work since there is no string table.
- ec = i->getName(Name);
+ ErrorOr<StringRef> NameOrErr = i->getName();
+ ec = NameOrErr.getError();
if (ec)
return;
+ Name = NameOrErr.get();
if (Name == "__.SYMDEF SORTED") {
SymbolTable = i;
++i;
@@ -335,12 +327,11 @@ Archive::child_iterator Archive::child_end() const {
return Child(this, nullptr);
}
-error_code Archive::Symbol::getName(StringRef &Result) const {
- Result = StringRef(Parent->SymbolTable->getBuffer().begin() + StringIndex);
- return object_error::success;
+StringRef Archive::Symbol::getName() const {
+ return Parent->SymbolTable->getBuffer().begin() + StringIndex;
}
-error_code Archive::Symbol::getMember(child_iterator &Result) const {
+ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const {
const char *Buf = Parent->SymbolTable->getBuffer().begin();
const char *Offsets = Buf + 4;
uint32_t Offset = 0;
@@ -348,7 +339,14 @@ error_code Archive::Symbol::getMember(child_iterator &Result) const {
Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets)
+ SymbolIndex);
} else if (Parent->kind() == K_BSD) {
- llvm_unreachable("BSD format is not supported");
+ // The SymbolIndex is an index into the ranlib structs that start at
+ // Offsets (the first uint32_t is the number of bytes of the ranlib
+ // structs). The ranlib structs are a pair of uint32_t's the first
+ // being a string table offset and the second being the offset into
+ // the archive of the member that defines the symbol. Which is what
+ // is needed here.
+ Offset = *(reinterpret_cast<const support::ulittle32_t *>(Offsets) +
+ (SymbolIndex * 2) + 1);
} else {
uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
@@ -380,16 +378,49 @@ error_code Archive::Symbol::getMember(child_iterator &Result) const {
}
const char *Loc = Parent->getData().begin() + Offset;
- Result = Child(Parent, Loc);
-
- return object_error::success;
+ child_iterator Iter(Child(Parent, Loc));
+ return Iter;
}
Archive::Symbol Archive::Symbol::getNext() const {
Symbol t(*this);
- // Go to one past next null.
- t.StringIndex =
- Parent->SymbolTable->getBuffer().find('\0', t.StringIndex) + 1;
+ if (Parent->kind() == K_BSD) {
+ // t.StringIndex is an offset from the start of the __.SYMDEF or
+ // "__.SYMDEF SORTED" member into the string table for the ranlib
+ // struct indexed by t.SymbolIndex . To change t.StringIndex to the
+ // offset in the string table for t.SymbolIndex+1 we subtract the
+ // its offset from the start of the string table for t.SymbolIndex
+ // and add the offset of the string table for t.SymbolIndex+1.
+
+ // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
+ // which is the number of bytes of ranlib structs that follow. The ranlib
+ // structs are a pair of uint32_t's the first being a string table offset
+ // and the second being the offset into the archive of the member that
+ // define the symbol. After that the next uint32_t is the byte count of
+ // the string table followed by the string table.
+ const char *Buf = Parent->SymbolTable->getBuffer().begin();
+ uint32_t RanlibCount = 0;
+ RanlibCount = (*reinterpret_cast<const support::ulittle32_t *>(Buf)) /
+ (sizeof(uint32_t) * 2);
+ // If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
+ // don't change the t.StringIndex as we don't want to reference a ranlib
+ // past RanlibCount.
+ if (t.SymbolIndex + 1 < RanlibCount) {
+ const char *Ranlibs = Buf + 4;
+ uint32_t CurRanStrx = 0;
+ uint32_t NextRanStrx = 0;
+ CurRanStrx = *(reinterpret_cast<const support::ulittle32_t *>(Ranlibs) +
+ (t.SymbolIndex * 2));
+ NextRanStrx = *(reinterpret_cast<const support::ulittle32_t *>(Ranlibs) +
+ ((t.SymbolIndex + 1) * 2));
+ t.StringIndex -= CurRanStrx;
+ t.StringIndex += NextRanStrx;
+ }
+ } else {
+ // Go to one past next null.
+ t.StringIndex =
+ Parent->SymbolTable->getBuffer().find('\0', t.StringIndex) + 1;
+ }
++t.SymbolIndex;
return t;
}
@@ -404,7 +435,22 @@ Archive::symbol_iterator Archive::symbol_begin() const {
symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
} else if (kind() == K_BSD) {
- llvm_unreachable("BSD archive format is not supported");
+ // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
+ // which is the number of bytes of ranlib structs that follow. The ranlib
+ // structs are a pair of uint32_t's the first being a string table offset
+ // and the second being the offset into the archive of the member that
+ // define the symbol. After that the next uint32_t is the byte count of
+ // the string table followed by the string table.
+ uint32_t ranlib_count = 0;
+ ranlib_count = (*reinterpret_cast<const support::ulittle32_t *>(buf)) /
+ (sizeof(uint32_t) * 2);
+ const char *ranlibs = buf + 4;
+ uint32_t ran_strx = 0;
+ ran_strx = *(reinterpret_cast<const support::ulittle32_t *>(ranlibs));
+ buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));
+ // Skip the byte count of the string table.
+ buf += sizeof(uint32_t);
+ buf += ran_strx;
} else {
uint32_t member_count = 0;
uint32_t symbol_count = 0;
@@ -426,7 +472,8 @@ Archive::symbol_iterator Archive::symbol_end() const {
if (kind() == K_GNU) {
symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
} else if (kind() == K_BSD) {
- llvm_unreachable("BSD archive format is not supported");
+ symbol_count = (*reinterpret_cast<const support::ulittle32_t *>(buf)) /
+ (sizeof(uint32_t) * 2);
} else {
uint32_t member_count = 0;
member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
@@ -440,16 +487,15 @@ Archive::symbol_iterator Archive::symbol_end() const {
Archive::child_iterator Archive::findSym(StringRef name) const {
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 child_end();
- if (symname == name) {
- if (bs->getMember(result))
+ StringRef SymName = bs->getName();
+ if (SymName == name) {
+ ErrorOr<Archive::child_iterator> ResultOrErr = bs->getMember();
+ // FIXME: Should we really eat the error?
+ if (ResultOrErr.getError())
return child_end();
- return result;
+ return ResultOrErr.get();
}
}
return child_end();
diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp
index 63fd3ed..9f6a685 100644
--- a/lib/Object/Binary.cpp
+++ b/lib/Object/Binary.cpp
@@ -25,13 +25,10 @@
using namespace llvm;
using namespace object;
-Binary::~Binary() {
- if (BufferOwned)
- delete Data;
-}
+Binary::~Binary() {}
-Binary::Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned)
- : TypeID(Type), BufferOwned(BufferOwned), Data(Source) {}
+Binary::Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source)
+ : TypeID(Type), Data(std::move(Source)) {}
StringRef Binary::getData() const {
return Data->getBuffer();
@@ -41,14 +38,13 @@ StringRef Binary::getFileName() const {
return Data->getBufferIdentifier();
}
-ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
+ErrorOr<Binary *> object::createBinary(std::unique_ptr<MemoryBuffer> &Buffer,
LLVMContext *Context) {
- std::unique_ptr<MemoryBuffer> scopedSource(Source);
- sys::fs::file_magic Type = sys::fs::identify_magic(Source->getBuffer());
+ sys::fs::file_magic Type = sys::fs::identify_magic(Buffer->getBuffer());
switch (Type) {
case sys::fs::file_magic::archive:
- return Archive::create(scopedSource.release());
+ return Archive::create(std::move(Buffer));
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
@@ -67,10 +63,9 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
case sys::fs::file_magic::bitcode:
- return ObjectFile::createSymbolicFile(scopedSource.release(), true, Type,
- Context);
+ return ObjectFile::createSymbolicFile(Buffer, Type, Context);
case sys::fs::file_magic::macho_universal_binary:
- return MachOUniversalBinary::create(scopedSource.release());
+ return MachOUniversalBinary::create(std::move(Buffer));
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::windows_resource:
// Unrecognized object file format.
@@ -80,8 +75,9 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
}
ErrorOr<Binary *> object::createBinary(StringRef Path) {
- std::unique_ptr<MemoryBuffer> File;
- if (error_code EC = MemoryBuffer::getFileOrSTDIN(Path, File))
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFileOrSTDIN(Path);
+ if (std::error_code EC = FileOrErr.getError())
return EC;
- return createBinary(File.release());
+ return createBinary(FileOrErr.get());
}
diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt
index cd8c9ef..5b08e42 100644
--- a/lib/Object/CMakeLists.txt
+++ b/lib/Object/CMakeLists.txt
@@ -12,7 +12,6 @@ add_llvm_library(LLVMObject
MachOUniversal.cpp
Object.cpp
ObjectFile.cpp
- StringTableBuilder.cpp
+ RecordStreamer.cpp
SymbolicFile.cpp
- YAML.cpp
)
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp
index 262c040..46ef87d 100644
--- a/lib/Object/COFFObjectFile.cpp
+++ b/lib/Object/COFFObjectFile.cpp
@@ -31,8 +31,9 @@ using support::ulittle32_t;
using support::little16_t;
// Returns false if size is greater than the buffer size. And sets ec.
-static bool checkSize(const MemoryBuffer *M, error_code &EC, uint64_t Size) {
- if (M->getBufferSize() < Size) {
+static bool checkSize(const MemoryBuffer &M, std::error_code &EC,
+ uint64_t Size) {
+ if (M.getBufferSize() < Size) {
EC = object_error::unexpected_eof;
return false;
}
@@ -41,13 +42,13 @@ static 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>
-static error_code getObject(const T *&Obj, const MemoryBuffer *M,
- const uint8_t *Ptr, const size_t Size = sizeof(T)) {
+template <typename T>
+static std::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 ||
- Addr + Size > uintptr_t(M->getBufferEnd())) {
+ if (Addr + Size < Addr || Addr + Size < Size ||
+ Addr + Size > uintptr_t(M.getBufferEnd())) {
return object_error::unexpected_eof;
}
Obj = reinterpret_cast<const T *>(Addr);
@@ -129,17 +130,17 @@ void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
Ref.p = reinterpret_cast<uintptr_t>(Symb);
}
-error_code COFFObjectFile::getSymbolName(DataRefImpl Ref,
- StringRef &Result) const {
+std::error_code COFFObjectFile::getSymbolName(DataRefImpl Ref,
+ StringRef &Result) const {
const coff_symbol *Symb = toSymb(Ref);
return getSymbolName(Symb, Result);
}
-error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
- uint64_t &Result) const {
+std::error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
+ uint64_t &Result) const {
const coff_symbol *Symb = toSymb(Ref);
const coff_section *Section = nullptr;
- if (error_code EC = getSection(Symb->SectionNumber, Section))
+ if (std::error_code EC = getSection(Symb->SectionNumber, Section))
return EC;
if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
@@ -151,8 +152,8 @@ error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
return object_error::success;
}
-error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
- SymbolRef::Type &Result) const {
+std::error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
+ SymbolRef::Type &Result) const {
const coff_symbol *Symb = toSymb(Ref);
Result = SymbolRef::ST_Other;
if (Symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
@@ -164,7 +165,7 @@ error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
uint32_t Characteristics = 0;
if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) {
const coff_section *Section = nullptr;
- if (error_code EC = getSection(Symb->SectionNumber, Section))
+ if (std::error_code EC = getSection(Symb->SectionNumber, Section))
return EC;
Characteristics = Section->Characteristics;
}
@@ -202,14 +203,14 @@ uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
return Result;
}
-error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
- uint64_t &Result) const {
+std::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(Ref);
const coff_section *Section = nullptr;
- if (error_code EC = getSection(Symb->SectionNumber, Section))
+ if (std::error_code EC = getSection(Symb->SectionNumber, Section))
return EC;
if (Symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED)
@@ -221,14 +222,16 @@ error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
return object_error::success;
}
-error_code COFFObjectFile::getSymbolSection(DataRefImpl Ref,
- section_iterator &Result) const {
+std::error_code
+COFFObjectFile::getSymbolSection(DataRefImpl Ref,
+ section_iterator &Result) const {
const coff_symbol *Symb = toSymb(Ref);
if (COFF::isReservedSectionNumber(Symb->SectionNumber)) {
Result = section_end();
} else {
const coff_section *Sec = nullptr;
- if (error_code EC = getSection(Symb->SectionNumber, Sec)) return EC;
+ if (std::error_code EC = getSection(Symb->SectionNumber, Sec))
+ return EC;
DataRefImpl Ref;
Ref.p = reinterpret_cast<uintptr_t>(Sec);
Result = section_iterator(SectionRef(Ref, this));
@@ -242,37 +245,37 @@ void COFFObjectFile::moveSectionNext(DataRefImpl &Ref) const {
Ref.p = reinterpret_cast<uintptr_t>(Sec);
}
-error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
- StringRef &Result) const {
+std::error_code COFFObjectFile::getSectionName(DataRefImpl Ref,
+ StringRef &Result) const {
const coff_section *Sec = toSec(Ref);
return getSectionName(Sec, Result);
}
-error_code COFFObjectFile::getSectionAddress(DataRefImpl Ref,
- uint64_t &Result) const {
+std::error_code COFFObjectFile::getSectionAddress(DataRefImpl Ref,
+ uint64_t &Result) const {
const coff_section *Sec = toSec(Ref);
Result = Sec->VirtualAddress;
return object_error::success;
}
-error_code COFFObjectFile::getSectionSize(DataRefImpl Ref,
- uint64_t &Result) const {
+std::error_code COFFObjectFile::getSectionSize(DataRefImpl Ref,
+ uint64_t &Result) const {
const coff_section *Sec = toSec(Ref);
Result = Sec->SizeOfRawData;
return object_error::success;
}
-error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
- StringRef &Result) const {
+std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
+ StringRef &Result) const {
const coff_section *Sec = toSec(Ref);
ArrayRef<uint8_t> Res;
- error_code EC = getSectionContents(Sec, Res);
+ std::error_code EC = getSectionContents(Sec, Res);
Result = StringRef(reinterpret_cast<const char*>(Res.data()), Res.size());
return EC;
}
-error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref,
- uint64_t &Res) const {
+std::error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref,
+ uint64_t &Res) const {
const coff_section *Sec = toSec(Ref);
if (!Sec)
return object_error::parse_failed;
@@ -280,62 +283,64 @@ error_code COFFObjectFile::getSectionAlignment(DataRefImpl Ref,
return object_error::success;
}
-error_code COFFObjectFile::isSectionText(DataRefImpl Ref,
- bool &Result) const {
+std::error_code COFFObjectFile::isSectionText(DataRefImpl Ref,
+ bool &Result) const {
const coff_section *Sec = toSec(Ref);
Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
return object_error::success;
}
-error_code COFFObjectFile::isSectionData(DataRefImpl Ref,
- bool &Result) const {
+std::error_code COFFObjectFile::isSectionData(DataRefImpl Ref,
+ bool &Result) const {
const coff_section *Sec = toSec(Ref);
Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
return object_error::success;
}
-error_code COFFObjectFile::isSectionBSS(DataRefImpl Ref,
- bool &Result) const {
+std::error_code COFFObjectFile::isSectionBSS(DataRefImpl Ref,
+ bool &Result) const {
const coff_section *Sec = toSec(Ref);
Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
return object_error::success;
}
-error_code COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref,
- bool &Result) const {
+std::error_code
+COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref,
+ bool &Result) const {
// FIXME: Unimplemented
Result = true;
return object_error::success;
}
-error_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref,
- bool &Result) const {
+std::error_code COFFObjectFile::isSectionVirtual(DataRefImpl Ref,
+ bool &Result) const {
const coff_section *Sec = toSec(Ref);
Result = Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
return object_error::success;
}
-error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref,
- bool &Result) const {
+std::error_code COFFObjectFile::isSectionZeroInit(DataRefImpl Ref,
+ bool &Result) const {
// FIXME: Unimplemented.
Result = false;
return object_error::success;
}
-error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref,
- bool &Result) const {
+std::error_code COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref,
+ bool &Result) const {
// FIXME: Unimplemented.
Result = false;
return object_error::success;
}
-error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
- DataRefImpl SymbRef,
- bool &Result) const {
+std::error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
+ DataRefImpl SymbRef,
+ bool &Result) const {
const coff_section *Sec = toSec(SecRef);
const coff_symbol *Symb = toSymb(SymbRef);
const coff_section *SymbSec = nullptr;
- if (error_code EC = getSection(Symb->SectionNumber, SymbSec)) return EC;
+ if (std::error_code EC = getSection(Symb->SectionNumber, SymbSec))
+ return EC;
if (SymbSec == Sec)
Result = true;
else
@@ -390,9 +395,9 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
}
// Initialize the pointer to the symbol table.
-error_code COFFObjectFile::initSymbolTablePtr() {
- if (error_code EC = getObject(
- SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable,
+std::error_code COFFObjectFile::initSymbolTablePtr() {
+ if (std::error_code EC = getObject(
+ SymbolTable, *Data, base() + COFFHeader->PointerToSymbolTable,
COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
return EC;
@@ -403,11 +408,12 @@ error_code COFFObjectFile::initSymbolTablePtr() {
base() + COFFHeader->PointerToSymbolTable +
COFFHeader->NumberOfSymbols * sizeof(coff_symbol);
const ulittle32_t *StringTableSizePtr;
- if (error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
+ if (std::error_code EC =
+ getObject(StringTableSizePtr, *Data, StringTableAddr))
return EC;
StringTableSize = *StringTableSizePtr;
- if (error_code EC =
- getObject(StringTable, Data, StringTableAddr, StringTableSize))
+ if (std::error_code EC =
+ getObject(StringTable, *Data, StringTableAddr, StringTableSize))
return EC;
// Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
@@ -422,7 +428,7 @@ error_code COFFObjectFile::initSymbolTablePtr() {
}
// Returns the file offset for the given VA.
-error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
+std::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;
@@ -431,7 +437,7 @@ error_code COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
}
// Returns the file offset for the given RVA.
-error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
+std::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;
@@ -447,10 +453,10 @@ error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
// table entry.
-error_code COFFObjectFile::
-getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const {
+std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
+ StringRef &Name) const {
uintptr_t IntPtr = 0;
- if (error_code EC = getRvaPtr(Rva, IntPtr))
+ if (std::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);
@@ -459,7 +465,7 @@ getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const {
}
// Find the import table.
-error_code COFFObjectFile::initImportTablePtr() {
+std::error_code COFFObjectFile::initImportTablePtr() {
// First, we get the RVA of the import table. If the file lacks a pointer to
// the import table, do nothing.
const data_directory *DataEntry;
@@ -477,7 +483,7 @@ 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))
+ if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
return EC;
ImportDirectory = reinterpret_cast<
const import_directory_table_entry *>(IntPtr);
@@ -485,7 +491,7 @@ error_code COFFObjectFile::initImportTablePtr() {
}
// Find the export table.
-error_code COFFObjectFile::initExportTablePtr() {
+std::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;
@@ -498,22 +504,23 @@ error_code COFFObjectFile::initExportTablePtr() {
uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress;
uintptr_t IntPtr = 0;
- if (error_code EC = getRvaPtr(ExportTableRva, IntPtr))
+ if (std::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,
- bool BufferOwned)
- : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(nullptr),
+COFFObjectFile::COFFObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ std::error_code &EC)
+ : ObjectFile(Binary::ID_COFF, std::move(Object)), COFFHeader(nullptr),
PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr),
SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr),
StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0),
ExportDirectory(nullptr) {
// 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;
@@ -526,7 +533,8 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
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) {
@@ -537,13 +545,13 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
HasPEHeader = true;
}
- if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
+ if ((EC = getObject(COFFHeader, *Data, base() + CurPtr)))
return;
CurPtr += sizeof(coff_file_header);
if (HasPEHeader) {
const pe32_header *Header;
- if ((EC = getObject(Header, Data, base() + CurPtr)))
+ if ((EC = getObject(Header, *Data, base() + CurPtr)))
return;
const uint8_t *DataDirAddr;
@@ -561,7 +569,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
EC = object_error::parse_failed;
return;
}
- if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
+ if ((EC = getObject(DataDirectory, *Data, DataDirAddr, DataDirSize)))
return;
CurPtr += COFFHeader->SizeOfOptionalHeader;
}
@@ -569,7 +577,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
if (COFFHeader->isImportLibrary())
return;
- if ((EC = getObject(SectionTable, Data, base() + CurPtr,
+ if ((EC = getObject(SectionTable, *Data, base() + CurPtr,
COFFHeader->NumberOfSections * sizeof(coff_section))))
return;
@@ -686,28 +694,30 @@ unsigned COFFObjectFile::getArch() const {
// This method is kept here because lld uses this. As soon as we make
// lld to use getCOFFHeader, this method will be removed.
-error_code COFFObjectFile::getHeader(const coff_file_header *&Res) const {
+std::error_code COFFObjectFile::getHeader(const coff_file_header *&Res) const {
return getCOFFHeader(Res);
}
-error_code COFFObjectFile::getCOFFHeader(const coff_file_header *&Res) const {
+std::error_code
+COFFObjectFile::getCOFFHeader(const coff_file_header *&Res) const {
Res = COFFHeader;
return object_error::success;
}
-error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
+std::error_code COFFObjectFile::getPE32Header(const pe32_header *&Res) const {
Res = PE32Header;
return object_error::success;
}
-error_code
+std::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 {
+std::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)
return object_error::parse_failed;
@@ -720,8 +730,8 @@ error_code COFFObjectFile::getDataDirectory(uint32_t Index,
return object_error::success;
}
-error_code COFFObjectFile::getSection(int32_t Index,
- const coff_section *&Result) const {
+std::error_code COFFObjectFile::getSection(int32_t Index,
+ const coff_section *&Result) const {
// Check for special index values.
if (COFF::isReservedSectionNumber(Index))
Result = nullptr;
@@ -733,8 +743,8 @@ error_code COFFObjectFile::getSection(int32_t Index,
return object_error::success;
}
-error_code COFFObjectFile::getString(uint32_t Offset,
- StringRef &Result) const {
+std::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;
@@ -744,8 +754,8 @@ error_code COFFObjectFile::getString(uint32_t Offset,
return object_error::success;
}
-error_code COFFObjectFile::getSymbol(uint32_t Index,
- const coff_symbol *&Result) const {
+std::error_code COFFObjectFile::getSymbol(uint32_t Index,
+ const coff_symbol *&Result) const {
if (Index < COFFHeader->NumberOfSymbols)
Result = SymbolTable + Index;
else
@@ -753,12 +763,12 @@ error_code COFFObjectFile::getSymbol(uint32_t Index,
return object_error::success;
}
-error_code COFFObjectFile::getSymbolName(const coff_symbol *Symbol,
- StringRef &Res) const {
+std::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))
+ if (std::error_code EC = getString(Offset, Res))
return EC;
return object_error::success;
}
@@ -795,8 +805,8 @@ ArrayRef<uint8_t> COFFObjectFile::getSymbolAuxData(
Symbol->NumberOfAuxSymbols * sizeof(coff_symbol));
}
-error_code COFFObjectFile::getSectionName(const coff_section *Sec,
- StringRef &Res) const {
+std::error_code COFFObjectFile::getSectionName(const coff_section *Sec,
+ StringRef &Res) const {
StringRef Name;
if (Sec->Name[7] == 0)
// Null terminated, let ::strlen figure out the length.
@@ -815,7 +825,7 @@ error_code COFFObjectFile::getSectionName(const coff_section *Sec,
if (Name.substr(1).getAsInteger(10, Offset))
return object_error::parse_failed;
}
- if (error_code EC = getString(Offset, Name))
+ if (std::error_code EC = getString(Offset, Name))
return EC;
}
@@ -823,8 +833,9 @@ error_code COFFObjectFile::getSectionName(const coff_section *Sec,
return object_error::success;
}
-error_code COFFObjectFile::getSectionContents(const coff_section *Sec,
- ArrayRef<uint8_t> &Res) const {
+std::error_code
+COFFObjectFile::getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const {
// The only thing that we need to verify is that the contents is contained
// within the file bounds. We don't need to make sure it doesn't cover other
// data, as there's nothing that says that is not allowed.
@@ -846,13 +857,13 @@ void COFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
reinterpret_cast<const coff_relocation*>(Rel.p) + 1);
}
-error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
- uint64_t &Res) const {
+std::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 {
+std::error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const {
Res = toRel(Rel)->VirtualAddress;
return object_error::success;
}
@@ -864,8 +875,8 @@ symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_iterator(SymbolRef(Ref, this));
}
-error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const {
+std::error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const {
const coff_relocation* R = toRel(Rel);
Res = R->Type;
return object_error::success;
@@ -891,8 +902,9 @@ COFFObjectFile::getCOFFRelocation(const RelocationRef &Reloc) const {
Res = #reloc_type; \
break;
-error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const {
+std::error_code
+COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const {
const coff_relocation *Reloc = toRel(Rel);
StringRef Res;
switch (COFFHeader->Machine) {
@@ -966,26 +978,29 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME
-error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const {
+std::error_code
+COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const {
const coff_relocation *Reloc = toRel(Rel);
const coff_symbol *Symb = nullptr;
- if (error_code EC = getSymbol(Reloc->SymbolTableIndex, Symb)) return EC;
+ if (std::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;
+ if (std::error_code EC = getSymbolName(Sym, SymName))
+ return EC;
Result.append(SymName.begin(), SymName.end());
return object_error::success;
}
-error_code COFFObjectFile::getLibraryNext(DataRefImpl LibData,
- LibraryRef &Result) const {
+std::error_code COFFObjectFile::getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Result) const {
report_fatal_error("getLibraryNext not implemented in COFFObjectFile");
}
-error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
- StringRef &Result) const {
+std::error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
+ StringRef &Result) const {
report_fatal_error("getLibraryPath not implemented in COFFObjectFile");
}
@@ -998,24 +1013,25 @@ void ImportDirectoryEntryRef::moveNext() {
++Index;
}
-error_code ImportDirectoryEntryRef::
-getImportTableEntry(const import_directory_table_entry *&Result) const {
+std::error_code ImportDirectoryEntryRef::getImportTableEntry(
+ const import_directory_table_entry *&Result) const {
Result = ImportTable;
return object_error::success;
}
-error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
+std::error_code ImportDirectoryEntryRef::getName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (error_code EC = OwningObject->getRvaPtr(ImportTable->NameRVA, IntPtr))
+ if (std::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(
+std::error_code ImportDirectoryEntryRef::getImportLookupEntry(
const import_lookup_table_entry32 *&Result) const {
uintptr_t IntPtr = 0;
- if (error_code EC =
+ if (std::error_code EC =
OwningObject->getRvaPtr(ImportTable->ImportLookupTableRVA, IntPtr))
return EC;
Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
@@ -1033,31 +1049,33 @@ void ExportDirectoryEntryRef::moveNext() {
// 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 {
+std::error_code ExportDirectoryEntryRef::getDllName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (error_code EC = OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr))
+ if (std::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 {
+std::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 {
+std::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 {
+std::error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
uintptr_t IntPtr = 0;
- if (error_code EC = OwningObject->getRvaPtr(
- ExportTable->ExportAddressTableRVA, IntPtr))
+ if (std::error_code EC =
+ OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA, IntPtr))
return EC;
const export_address_table_entry *entry =
reinterpret_cast<const export_address_table_entry *>(IntPtr);
@@ -1067,10 +1085,11 @@ error_code ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
// 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 {
+std::error_code
+ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
uintptr_t IntPtr = 0;
- if (error_code EC = OwningObject->getRvaPtr(
- ExportTable->OrdinalTableRVA, IntPtr))
+ if (std::error_code EC =
+ OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr))
return EC;
const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);
@@ -1080,11 +1099,11 @@ error_code ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
I < E; ++I, ++Offset) {
if (*I != Index)
continue;
- if (error_code EC = OwningObject->getRvaPtr(
- ExportTable->NamePointerRVA, IntPtr))
+ if (std::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))
+ if (std::error_code EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr))
return EC;
Result = StringRef(reinterpret_cast<const char *>(IntPtr));
return object_error::success;
@@ -1093,11 +1112,11 @@ error_code ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
return object_error::success;
}
-ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object,
- bool BufferOwned) {
- error_code EC;
+ErrorOr<ObjectFile *>
+ObjectFile::createCOFFObjectFile(std::unique_ptr<MemoryBuffer> Object) {
+ std::error_code EC;
std::unique_ptr<COFFObjectFile> Ret(
- new COFFObjectFile(Object, EC, BufferOwned));
+ new COFFObjectFile(std::move(Object), EC));
if (EC)
return EC;
return Ret.release();
diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp
index a2c4df2..4f0f60b 100644
--- a/lib/Object/ELFObjectFile.cpp
+++ b/lib/Object/ELFObjectFile.cpp
@@ -17,65 +17,66 @@
namespace llvm {
using namespace object;
-ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj,
- bool BufferOwned) {
- std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
+ErrorOr<ObjectFile *>
+ObjectFile::createELFObjectFile(std::unique_ptr<MemoryBuffer> &Obj) {
+ std::pair<unsigned char, unsigned char> Ident =
+ getElfArchType(Obj->getBuffer());
std::size_t MaxAlignment =
1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
- error_code EC;
+ std::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)
- R.reset(new ELFObjectFile<ELFType<support::little, 4, false> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(
+ std::move(Obj), EC));
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::little, 2, false> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(
+ std::move(Obj), EC));
else
- llvm_unreachable("Invalid alignment for ELF file!");
+ return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- R.reset(new ELFObjectFile<ELFType<support::big, 4, false> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(std::move(Obj),
+ EC));
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::big, 2, false> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(std::move(Obj),
+ EC));
else
- llvm_unreachable("Invalid alignment for ELF file!");
+ return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- R.reset(new ELFObjectFile<ELFType<support::big, 8, true> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(std::move(Obj),
+ EC));
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::big, 2, true> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(std::move(Obj),
+ EC));
else
- llvm_unreachable("Invalid alignment for ELF file!");
+ return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- R.reset(new ELFObjectFile<ELFType<support::little, 8, true> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(
+ std::move(Obj), EC));
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::little, 2, true> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(
+ std::move(Obj), EC));
else
- llvm_unreachable("Invalid alignment for ELF file!");
+ return object_error::parse_failed;
}
else
- report_fatal_error("Buffer is not an ELF object file!");
+ llvm_unreachable("Buffer is not an ELF object file!");
if (EC)
return EC;
diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp
index 7d50f23..dc3d467 100644
--- a/lib/Object/ELFYAML.cpp
+++ b/lib/Object/ELFYAML.cpp
@@ -368,6 +368,16 @@ void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
#undef ECase
}
+void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration(
+ IO &IO, ELFYAML::ELF_STV &Value) {
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ ECase(STV_DEFAULT)
+ ECase(STV_INTERNAL)
+ ECase(STV_HIDDEN)
+ ECase(STV_PROTECTED)
+#undef ECase
+}
+
void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
IO &IO, ELFYAML::ELF_REL &Value) {
const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
@@ -649,6 +659,7 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Value", Symbol.Value, Hex64(0));
IO.mapOptional("Size", Symbol.Size, Hex64(0));
+ IO.mapOptional("Visibility", Symbol.Visibility, ELFYAML::ELF_STV(0));
}
void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
@@ -664,7 +675,6 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
IO.mapOptional("Address", Section.Address, Hex64(0));
IO.mapOptional("Link", Section.Link, StringRef());
- IO.mapOptional("Info", Section.Info, StringRef());
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
}
@@ -676,6 +686,7 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
commonSectionMapping(IO, Section);
+ IO.mapOptional("Info", Section.Info, StringRef());
IO.mapOptional("Relocations", Section.Relocations);
}
diff --git a/lib/Object/Error.cpp b/lib/Object/Error.cpp
index 8e50869..9d25269 100644
--- a/lib/Object/Error.cpp
+++ b/lib/Object/Error.cpp
@@ -18,11 +18,10 @@ using namespace llvm;
using namespace object;
namespace {
-class _object_error_category : public error_category {
+class _object_error_category : public std::error_category {
public:
- const char* name() const override;
+ const char* name() const LLVM_NOEXCEPT override;
std::string message(int ev) const override;
- error_condition default_error_condition(int ev) const override;
};
}
@@ -30,8 +29,8 @@ const char *_object_error_category::name() const {
return "llvm.object";
}
-std::string _object_error_category::message(int ev) const {
- object_error::Impl E = static_cast<object_error::Impl>(ev);
+std::string _object_error_category::message(int EV) const {
+ object_error E = static_cast<object_error>(EV);
switch (E) {
case object_error::success: return "Success";
case object_error::arch_not_found:
@@ -47,13 +46,7 @@ std::string _object_error_category::message(int ev) const {
"defined.");
}
-error_condition _object_error_category::default_error_condition(int ev) const {
- if (ev == object_error::success)
- return errc::success;
- return errc::invalid_argument;
-}
-
-const error_category &object::object_category() {
+const std::error_category &object::object_category() {
static _object_error_category o;
return o;
}
diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp
index a8aba26..5323d92 100644
--- a/lib/Object/IRObjectFile.cpp
+++ b/lib/Object/IRObjectFile.cpp
@@ -11,34 +11,119 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Object/IRObjectFile.h"
+#include "RecordStreamer.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
-#include "llvm/Object/IRObjectFile.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.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());
-
+IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ std::unique_ptr<Module> Mod)
+ : SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) {
// If we have a DataLayout, setup a mangler.
const DataLayout *DL = M->getDataLayout();
if (!DL)
return;
Mang.reset(new Mangler(DL));
+
+ const std::string &InlineAsm = M->getModuleInlineAsm();
+ if (InlineAsm.empty())
+ return;
+
+ StringRef Triple = M->getTargetTriple();
+ std::string Err;
+ const Target *T = TargetRegistry::lookupTarget(Triple, Err);
+ if (!T)
+ return;
+
+ std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple));
+ if (!MRI)
+ return;
+
+ std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple));
+ if (!MAI)
+ return;
+
+ std::unique_ptr<MCSubtargetInfo> STI(
+ T->createMCSubtargetInfo(Triple, "", ""));
+ if (!STI)
+ return;
+
+ std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
+ if (!MCII)
+ return;
+
+ MCObjectFileInfo MOFI;
+ MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
+ MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx);
+ std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx));
+
+ std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
+ SourceMgr SrcMgr;
+ SrcMgr.AddNewSourceBuffer(Buffer.release(), SMLoc());
+ std::unique_ptr<MCAsmParser> Parser(
+ createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI));
+
+ MCTargetOptions MCOptions;
+ std::unique_ptr<MCTargetAsmParser> TAP(
+ T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
+ if (!TAP)
+ return;
+
+ Parser->setTargetParser(*TAP);
+ if (Parser->Run(false))
+ return;
+
+ for (auto &KV : *Streamer) {
+ StringRef Key = KV.first();
+ RecordStreamer::State Value = KV.second;
+ uint32_t Res = BasicSymbolRef::SF_None;
+ switch (Value) {
+ case RecordStreamer::NeverSeen:
+ llvm_unreachable("foo");
+ case RecordStreamer::DefinedGlobal:
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::Defined:
+ break;
+ case RecordStreamer::Global:
+ case RecordStreamer::Used:
+ Res |= BasicSymbolRef::SF_Undefined;
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ }
+ AsmSymbols.push_back(
+ std::make_pair<std::string, uint32_t>(Key, std::move(Res)));
+ }
}
-static const GlobalValue &getGV(DataRefImpl &Symb) {
- return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
+IRObjectFile::~IRObjectFile() {
+ GVMaterializer *GVM = M->getMaterializer();
+ if (GVM)
+ GVM->releaseBuffer();
+ }
+
+static const GlobalValue *getGV(DataRefImpl &Symb) {
+ if ((Symb.p & 3) == 3)
+ return nullptr;
+
+ return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
}
static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
@@ -62,68 +147,109 @@ static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
return reinterpret_cast<uintptr_t>(GV) | 0;
}
+static unsigned getAsmSymIndex(DataRefImpl Symb) {
+ assert((Symb.p & uintptr_t(3)) == 3);
+ uintptr_t Index = Symb.p & ~uintptr_t(3);
+ Index >>= 2;
+ return Index;
+}
+
void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
- const GlobalValue *GV = &getGV(Symb);
- const Module &M = *GV->getParent();
+ const GlobalValue *GV = getGV(Symb);
uintptr_t Res;
+
switch (Symb.p & 3) {
case 0: {
Module::const_iterator Iter(static_cast<const Function*>(GV));
++Iter;
- Res = skipEmpty(Iter, M);
+ Res = skipEmpty(Iter, *M);
break;
}
case 1: {
Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
++Iter;
- Res = skipEmpty(Iter, M);
+ Res = skipEmpty(Iter, *M);
break;
}
case 2: {
Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
++Iter;
- Res = skipEmpty(Iter, M);
+ Res = skipEmpty(Iter, *M);
+ break;
+ }
+ case 3: {
+ unsigned Index = getAsmSymIndex(Symb);
+ assert(Index < AsmSymbols.size());
+ ++Index;
+ Res = (Index << 2) | 3;
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);
+std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const {
+ const GlobalValue *GV = getGV(Symb);
+ if (!GV) {
+ unsigned Index = getAsmSymIndex(Symb);
+ assert(Index <= AsmSymbols.size());
+ OS << AsmSymbols[Index].first;
+ return object_error::success;;
+ }
if (Mang)
- Mang->getNameWithPrefix(OS, &GV, false);
+ Mang->getNameWithPrefix(OS, GV, false);
else
- OS << GV.getName();
+ OS << GV->getName();
return object_error::success;
}
+static bool isDeclaration(const GlobalValue &V) {
+ if (V.hasAvailableExternallyLinkage())
+ return true;
+
+ if (V.isMaterializable())
+ return false;
+
+ return V.isDeclaration();
+}
+
uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
- const GlobalValue &GV = getGV(Symb);
+ const GlobalValue *GV = getGV(Symb);
+
+ if (!GV) {
+ unsigned Index = getAsmSymIndex(Symb);
+ assert(Index <= AsmSymbols.size());
+ return AsmSymbols[Index].second;
+ }
uint32_t Res = BasicSymbolRef::SF_None;
- if (GV.isDeclaration() || GV.hasAvailableExternallyLinkage())
+ if (isDeclaration(*GV))
Res |= BasicSymbolRef::SF_Undefined;
- if (GV.hasPrivateLinkage())
+ if (GV->hasPrivateLinkage())
Res |= BasicSymbolRef::SF_FormatSpecific;
- if (!GV.hasLocalLinkage())
+ if (!GV->hasLocalLinkage())
Res |= BasicSymbolRef::SF_Global;
- if (GV.hasCommonLinkage())
+ if (GV->hasCommonLinkage())
Res |= BasicSymbolRef::SF_Common;
- if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage())
+ if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage())
Res |= BasicSymbolRef::SF_Weak;
+ if (GV->getName().startswith("llvm."))
+ Res |= BasicSymbolRef::SF_FormatSpecific;
+ else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
+ if (Var->getSection() == StringRef("llvm.metadata"))
+ Res |= BasicSymbolRef::SF_FormatSpecific;
+ }
+
return Res;
}
-const GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
- const GlobalValue &GV = getGV(Symb);
+const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
+ const GlobalValue *GV = getGV(Symb);
return GV;
}
@@ -136,16 +262,18 @@ basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
DataRefImpl Ret;
- Ret.p = 3;
+ uint64_t NumAsm = AsmSymbols.size();
+ NumAsm <<= 2;
+ Ret.p = 3 | NumAsm;
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)
+ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile(
+ std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) {
+ ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object.get(), Context);
+ if (std::error_code EC = MOrErr.getError())
return EC;
- return Ret.release();
+
+ std::unique_ptr<Module> M(MOrErr.get());
+ return new IRObjectFile(std::move(Object), std::move(M));
}
diff --git a/lib/Object/LLVMBuild.txt b/lib/Object/LLVMBuild.txt
index 7813832..8acacba 100644
--- a/lib/Object/LLVMBuild.txt
+++ b/lib/Object/LLVMBuild.txt
@@ -19,4 +19,4 @@
type = Library
name = Object
parent = Libraries
-required_libraries = BitReader Core Support
+required_libraries = BitReader Core Support MC MCParser
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index c6bab03..4919114 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -28,6 +28,7 @@ using namespace llvm;
using namespace object;
namespace llvm {
+
namespace object {
struct nlist_base {
@@ -43,190 +44,195 @@ struct section_base {
};
template<typename T>
-static void SwapValue(T &Value) {
- Value = sys::SwapByteOrder(Value);
-}
-
-template<typename T>
static void SwapStruct(T &Value);
template<>
void SwapStruct(MachO::any_relocation_info &H) {
- SwapValue(H.r_word0);
- SwapValue(H.r_word1);
+ sys::swapByteOrder(H.r_word0);
+ sys::swapByteOrder(H.r_word1);
}
template<>
void SwapStruct(MachO::load_command &L) {
- SwapValue(L.cmd);
- SwapValue(L.cmdsize);
+ sys::swapByteOrder(L.cmd);
+ sys::swapByteOrder(L.cmdsize);
}
template<>
void SwapStruct(nlist_base &S) {
- SwapValue(S.n_strx);
- SwapValue(S.n_desc);
+ sys::swapByteOrder(S.n_strx);
+ sys::swapByteOrder(S.n_desc);
}
template<>
void SwapStruct(MachO::section &S) {
- SwapValue(S.addr);
- SwapValue(S.size);
- SwapValue(S.offset);
- SwapValue(S.align);
- SwapValue(S.reloff);
- SwapValue(S.nreloc);
- SwapValue(S.flags);
- SwapValue(S.reserved1);
- SwapValue(S.reserved2);
+ sys::swapByteOrder(S.addr);
+ sys::swapByteOrder(S.size);
+ sys::swapByteOrder(S.offset);
+ sys::swapByteOrder(S.align);
+ sys::swapByteOrder(S.reloff);
+ sys::swapByteOrder(S.nreloc);
+ sys::swapByteOrder(S.flags);
+ sys::swapByteOrder(S.reserved1);
+ sys::swapByteOrder(S.reserved2);
}
template<>
void SwapStruct(MachO::section_64 &S) {
- SwapValue(S.addr);
- SwapValue(S.size);
- SwapValue(S.offset);
- SwapValue(S.align);
- SwapValue(S.reloff);
- SwapValue(S.nreloc);
- SwapValue(S.flags);
- SwapValue(S.reserved1);
- SwapValue(S.reserved2);
- SwapValue(S.reserved3);
+ sys::swapByteOrder(S.addr);
+ sys::swapByteOrder(S.size);
+ sys::swapByteOrder(S.offset);
+ sys::swapByteOrder(S.align);
+ sys::swapByteOrder(S.reloff);
+ sys::swapByteOrder(S.nreloc);
+ sys::swapByteOrder(S.flags);
+ sys::swapByteOrder(S.reserved1);
+ sys::swapByteOrder(S.reserved2);
+ sys::swapByteOrder(S.reserved3);
}
template<>
void SwapStruct(MachO::nlist &S) {
- SwapValue(S.n_strx);
- SwapValue(S.n_desc);
- SwapValue(S.n_value);
+ sys::swapByteOrder(S.n_strx);
+ sys::swapByteOrder(S.n_desc);
+ sys::swapByteOrder(S.n_value);
}
template<>
void SwapStruct(MachO::nlist_64 &S) {
- SwapValue(S.n_strx);
- SwapValue(S.n_desc);
- SwapValue(S.n_value);
+ sys::swapByteOrder(S.n_strx);
+ sys::swapByteOrder(S.n_desc);
+ sys::swapByteOrder(S.n_value);
}
template<>
void SwapStruct(MachO::mach_header &H) {
- SwapValue(H.magic);
- SwapValue(H.cputype);
- SwapValue(H.cpusubtype);
- SwapValue(H.filetype);
- SwapValue(H.ncmds);
- SwapValue(H.sizeofcmds);
- SwapValue(H.flags);
+ sys::swapByteOrder(H.magic);
+ sys::swapByteOrder(H.cputype);
+ sys::swapByteOrder(H.cpusubtype);
+ sys::swapByteOrder(H.filetype);
+ sys::swapByteOrder(H.ncmds);
+ sys::swapByteOrder(H.sizeofcmds);
+ sys::swapByteOrder(H.flags);
}
template<>
void SwapStruct(MachO::mach_header_64 &H) {
- SwapValue(H.magic);
- SwapValue(H.cputype);
- SwapValue(H.cpusubtype);
- SwapValue(H.filetype);
- SwapValue(H.ncmds);
- SwapValue(H.sizeofcmds);
- SwapValue(H.flags);
- SwapValue(H.reserved);
+ sys::swapByteOrder(H.magic);
+ sys::swapByteOrder(H.cputype);
+ sys::swapByteOrder(H.cpusubtype);
+ sys::swapByteOrder(H.filetype);
+ sys::swapByteOrder(H.ncmds);
+ sys::swapByteOrder(H.sizeofcmds);
+ sys::swapByteOrder(H.flags);
+ sys::swapByteOrder(H.reserved);
}
template<>
void SwapStruct(MachO::symtab_command &C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.symoff);
- SwapValue(C.nsyms);
- SwapValue(C.stroff);
- SwapValue(C.strsize);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.symoff);
+ sys::swapByteOrder(C.nsyms);
+ sys::swapByteOrder(C.stroff);
+ sys::swapByteOrder(C.strsize);
}
template<>
void SwapStruct(MachO::dysymtab_command &C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.ilocalsym);
- SwapValue(C.nlocalsym);
- SwapValue(C.iextdefsym);
- SwapValue(C.nextdefsym);
- SwapValue(C.iundefsym);
- SwapValue(C.nundefsym);
- SwapValue(C.tocoff);
- SwapValue(C.ntoc);
- SwapValue(C.modtaboff);
- SwapValue(C.nmodtab);
- SwapValue(C.extrefsymoff);
- SwapValue(C.nextrefsyms);
- SwapValue(C.indirectsymoff);
- SwapValue(C.nindirectsyms);
- SwapValue(C.extreloff);
- SwapValue(C.nextrel);
- SwapValue(C.locreloff);
- SwapValue(C.nlocrel);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.ilocalsym);
+ sys::swapByteOrder(C.nlocalsym);
+ sys::swapByteOrder(C.iextdefsym);
+ sys::swapByteOrder(C.nextdefsym);
+ sys::swapByteOrder(C.iundefsym);
+ sys::swapByteOrder(C.nundefsym);
+ sys::swapByteOrder(C.tocoff);
+ sys::swapByteOrder(C.ntoc);
+ sys::swapByteOrder(C.modtaboff);
+ sys::swapByteOrder(C.nmodtab);
+ sys::swapByteOrder(C.extrefsymoff);
+ sys::swapByteOrder(C.nextrefsyms);
+ sys::swapByteOrder(C.indirectsymoff);
+ sys::swapByteOrder(C.nindirectsyms);
+ sys::swapByteOrder(C.extreloff);
+ sys::swapByteOrder(C.nextrel);
+ sys::swapByteOrder(C.locreloff);
+ sys::swapByteOrder(C.nlocrel);
}
template<>
void SwapStruct(MachO::linkedit_data_command &C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.dataoff);
- SwapValue(C.datasize);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.dataoff);
+ sys::swapByteOrder(C.datasize);
}
template<>
void SwapStruct(MachO::segment_command &C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.vmaddr);
- SwapValue(C.vmsize);
- SwapValue(C.fileoff);
- SwapValue(C.filesize);
- SwapValue(C.maxprot);
- SwapValue(C.initprot);
- SwapValue(C.nsects);
- SwapValue(C.flags);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.vmaddr);
+ sys::swapByteOrder(C.vmsize);
+ sys::swapByteOrder(C.fileoff);
+ sys::swapByteOrder(C.filesize);
+ sys::swapByteOrder(C.maxprot);
+ sys::swapByteOrder(C.initprot);
+ sys::swapByteOrder(C.nsects);
+ sys::swapByteOrder(C.flags);
}
template<>
void SwapStruct(MachO::segment_command_64 &C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.vmaddr);
- SwapValue(C.vmsize);
- SwapValue(C.fileoff);
- SwapValue(C.filesize);
- SwapValue(C.maxprot);
- SwapValue(C.initprot);
- SwapValue(C.nsects);
- SwapValue(C.flags);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.vmaddr);
+ sys::swapByteOrder(C.vmsize);
+ sys::swapByteOrder(C.fileoff);
+ sys::swapByteOrder(C.filesize);
+ sys::swapByteOrder(C.maxprot);
+ sys::swapByteOrder(C.initprot);
+ sys::swapByteOrder(C.nsects);
+ sys::swapByteOrder(C.flags);
}
template<>
void SwapStruct(uint32_t &C) {
- SwapValue(C);
+ sys::swapByteOrder(C);
}
template<>
void SwapStruct(MachO::linker_options_command &C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.count);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.count);
}
template<>
void SwapStruct(MachO::version_min_command&C) {
- SwapValue(C.cmd);
- SwapValue(C.cmdsize);
- SwapValue(C.version);
- SwapValue(C.reserved);
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.version);
+ sys::swapByteOrder(C.reserved);
+}
+
+template<>
+void SwapStruct(MachO::dylib_command&C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.dylib.name);
+ sys::swapByteOrder(C.dylib.timestamp);
+ sys::swapByteOrder(C.dylib.current_version);
+ sys::swapByteOrder(C.dylib.compatibility_version);
}
template<>
void SwapStruct(MachO::data_in_code_entry &C) {
- SwapValue(C.offset);
- SwapValue(C.length);
- SwapValue(C.kind);
+ sys::swapByteOrder(C.offset);
+ sys::swapByteOrder(C.length);
+ sys::swapByteOrder(C.kind);
}
template<typename T>
@@ -306,7 +312,7 @@ static void printRelocationTargetName(const MachOObjectFile *O,
uint32_t Val = O->getPlainRelocationSymbolNum(RE);
for (const SymbolRef &Symbol : O->symbols()) {
- error_code ec;
+ std::error_code ec;
uint64_t Addr;
StringRef Name;
@@ -323,7 +329,7 @@ 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 (const SectionRef &Section : O->sections()) {
- error_code ec;
+ std::error_code ec;
uint64_t Addr;
StringRef Name;
@@ -416,10 +422,10 @@ static uint32_t getSectionFlags(const MachOObjectFile *O,
return Sect.flags;
}
-MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
- bool Is64bits, error_code &EC,
- bool BufferOwned)
- : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
+MachOObjectFile::MachOObjectFile(std::unique_ptr<MemoryBuffer> Object,
+ bool IsLittleEndian, bool Is64bits,
+ std::error_code &EC)
+ : ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
DataInCodeLoadCmd(nullptr) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
@@ -443,6 +449,12 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
const char *Sec = getSectionPtr(this, Load, J);
Sections.push_back(Sec);
}
+ } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
+ Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
+ Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
+ Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
+ Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
+ Libraries.push_back(Load.Ptr);
}
if (I == LoadCommandCount - 1)
@@ -459,8 +471,8 @@ void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
Symb.p += SymbolTableEntrySize;
}
-error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
- StringRef &Res) const {
+std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
+ StringRef &Res) const {
StringRef StringTable = getStringTableData();
nlist_base Entry = getSymbolTableEntryBase(this, Symb);
const char *Start = &StringTable.data()[Entry.n_strx];
@@ -468,8 +480,32 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
return object_error::success;
}
-error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Res) const {
+// getIndirectName() returns the name of the alias'ed symbol who's string table
+// index is in the n_value field.
+std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb,
+ StringRef &Res) const {
+ StringRef StringTable = getStringTableData();
+ uint64_t NValue;
+ if (is64Bit()) {
+ MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
+ NValue = Entry.n_value;
+ if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
+ return object_error::parse_failed;
+ } else {
+ MachO::nlist Entry = getSymbolTableEntry(Symb);
+ NValue = Entry.n_value;
+ if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR)
+ return object_error::parse_failed;
+ }
+ if (NValue >= StringTable.size())
+ return object_error::parse_failed;
+ const char *Start = &StringTable.data()[NValue];
+ Res = StringRef(Start);
+ return object_error::success;
+}
+
+std::error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Res) const {
if (is64Bit()) {
MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
@@ -488,8 +524,8 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
return object_error::success;
}
-error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
- uint32_t &Result) const {
+std::error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
+ uint32_t &Result) const {
uint32_t flags = getSymbolFlags(DRI);
if (flags & SymbolRef::SF_Common) {
nlist_base Entry = getSymbolTableEntryBase(this, DRI);
@@ -500,8 +536,8 @@ error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI,
return object_error::success;
}
-error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
- uint64_t &Result) const {
+std::error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
+ uint64_t &Result) const {
uint64_t BeginOffset;
uint64_t EndOffset = 0;
uint8_t SectionIndex;
@@ -549,8 +585,8 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
return object_error::success;
}
-error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const {
+std::error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const {
nlist_base Entry = getSymbolTableEntryBase(this, Symb);
uint8_t n_type = Entry.n_type;
@@ -584,6 +620,9 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF)
Result |= SymbolRef::SF_Undefined;
+ if ((MachOType & MachO::N_TYPE) == MachO::N_INDR)
+ Result |= SymbolRef::SF_Indirect;
+
if (MachOType & MachO::N_STAB)
Result |= SymbolRef::SF_FormatSpecific;
@@ -606,9 +645,8 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
return Result;
}
-error_code
-MachOObjectFile::getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const {
+std::error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const {
nlist_base Entry = getSymbolTableEntryBase(this, Symb);
uint8_t index = Entry.n_sect;
@@ -627,15 +665,15 @@ void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const {
Sec.d.a++;
}
-error_code
-MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const {
+std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec,
+ StringRef &Result) const {
ArrayRef<char> Raw = getSectionRawName(Sec);
Result = parseSegmentOrSectionName(Raw.data());
return object_error::success;
}
-error_code
-MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
+std::error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec,
+ uint64_t &Res) const {
if (is64Bit()) {
MachO::section_64 Sect = getSection64(Sec);
Res = Sect.addr;
@@ -646,8 +684,8 @@ MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const {
return object_error::success;
}
-error_code
-MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
+std::error_code MachOObjectFile::getSectionSize(DataRefImpl Sec,
+ uint64_t &Res) const {
if (is64Bit()) {
MachO::section_64 Sect = getSection64(Sec);
Res = Sect.size;
@@ -659,8 +697,8 @@ MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const {
return object_error::success;
}
-error_code
-MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
+std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec,
+ StringRef &Res) const {
uint32_t Offset;
uint64_t Size;
@@ -678,8 +716,8 @@ MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const {
return object_error::success;
}
-error_code
-MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
+std::error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Res) const {
uint32_t Align;
if (is64Bit()) {
MachO::section_64 Sect = getSection64(Sec);
@@ -693,14 +731,15 @@ MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const {
return object_error::success;
}
-error_code
-MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
+std::error_code MachOObjectFile::isSectionText(DataRefImpl Sec,
+ bool &Res) const {
uint32_t Flags = getSectionFlags(this, Sec);
Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
return object_error::success;
}
-error_code MachOObjectFile::isSectionData(DataRefImpl Sec, bool &Result) const {
+std::error_code MachOObjectFile::isSectionData(DataRefImpl Sec,
+ bool &Result) const {
uint32_t Flags = getSectionFlags(this, Sec);
unsigned SectionType = Flags & MachO::SECTION_TYPE;
Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
@@ -709,7 +748,8 @@ error_code MachOObjectFile::isSectionData(DataRefImpl Sec, bool &Result) const {
return object_error::success;
}
-error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec, bool &Result) const {
+std::error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec,
+ bool &Result) const {
uint32_t Flags = getSectionFlags(this, Sec);
unsigned SectionType = Flags & MachO::SECTION_TYPE;
Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
@@ -718,7 +758,7 @@ error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec, bool &Result) const {
return object_error::success;
}
-error_code
+std::error_code
MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
bool &Result) const {
// FIXME: Unimplemented.
@@ -726,15 +766,15 @@ MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
return object_error::success;
}
-error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
- bool &Result) const {
+std::error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
+ bool &Result) const {
// FIXME: Unimplemented.
Result = false;
return object_error::success;
}
-error_code
-MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
+std::error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec,
+ bool &Res) const {
uint32_t Flags = getSectionFlags(this, Sec);
unsigned SectionType = Flags & MachO::SECTION_TYPE;
Res = SectionType == MachO::S_ZEROFILL ||
@@ -742,8 +782,8 @@ MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
return object_error::success;
}
-error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
- bool &Result) const {
+std::error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Result) const {
// Consider using the code from isSectionText to look for __const sections.
// Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
// to use section attributes to distinguish code from data.
@@ -753,9 +793,9 @@ error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
return object_error::success;
}
-error_code
-MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const {
+std::error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const {
SymbolRef::Type ST;
this->getSymbolType(Symb, ST);
if (ST == SymbolRef::ST_Unknown) {
@@ -803,8 +843,8 @@ void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
++Rel.d.b;
}
-error_code
-MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
+std::error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const {
uint64_t Offset;
getRelocationOffset(Rel, Offset);
@@ -816,8 +856,8 @@ MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
return object_error::success;
}
-error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
- uint64_t &Res) const {
+std::error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const {
assert(getHeader().filetype == MachO::MH_OBJECT &&
"Only implemented for MH_OBJECT");
MachO::any_relocation_info RE = getRelocation(Rel);
@@ -828,6 +868,9 @@ error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
symbol_iterator
MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
MachO::any_relocation_info RE = getRelocation(Rel);
+ if (isRelocationScattered(RE))
+ return symbol_end();
+
uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
bool isExtern = getPlainRelocationExternal(RE);
if (!isExtern)
@@ -843,14 +886,14 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_iterator(SymbolRef(Sym, this));
}
-error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const {
+std::error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const {
MachO::any_relocation_info RE = getRelocation(Rel);
Res = getAnyRelocationType(RE);
return object_error::success;
}
-error_code
+std::error_code
MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
StringRef res;
@@ -963,7 +1006,7 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
return object_error::success;
}
-error_code
+std::error_code
MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
MachO::any_relocation_info RE = getRelocation(Rel);
@@ -1139,8 +1182,8 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
return object_error::success;
}
-error_code
-MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
+std::error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
+ bool &Result) const {
unsigned Arch = getArch();
uint64_t Type;
getRelocationType(Rel, Type);
@@ -1167,16 +1210,199 @@ MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const {
return object_error::success;
}
-error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
- LibraryRef &Res) const {
+std::error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Res) const {
report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}
-error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
- StringRef &Res) const {
+std::error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
+ StringRef &Res) const {
report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
}
+//
+// guessLibraryShortName() is passed a name of a dynamic library and returns a
+// guess on what the short name is. Then name is returned as a substring of the
+// StringRef Name passed in. The name of the dynamic library is recognized as
+// a framework if it has one of the two following forms:
+// Foo.framework/Versions/A/Foo
+// Foo.framework/Foo
+// Where A and Foo can be any string. And may contain a trailing suffix
+// starting with an underbar. If the Name is recognized as a framework then
+// isFramework is set to true else it is set to false. If the Name has a
+// suffix then Suffix is set to the substring in Name that contains the suffix
+// else it is set to a NULL StringRef.
+//
+// The Name of the dynamic library is recognized as a library name if it has
+// one of the two following forms:
+// libFoo.A.dylib
+// libFoo.dylib
+// The library may have a suffix trailing the name Foo of the form:
+// libFoo_profile.A.dylib
+// libFoo_profile.dylib
+//
+// The Name of the dynamic library is also recognized as a library name if it
+// has the following form:
+// Foo.qtx
+//
+// If the Name of the dynamic library is none of the forms above then a NULL
+// StringRef is returned.
+//
+StringRef MachOObjectFile::guessLibraryShortName(StringRef Name,
+ bool &isFramework,
+ StringRef &Suffix) {
+ StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx;
+ size_t a, b, c, d, Idx;
+
+ isFramework = false;
+ Suffix = StringRef();
+
+ // Pull off the last component and make Foo point to it
+ a = Name.rfind('/');
+ if (a == Name.npos || a == 0)
+ goto guess_library;
+ Foo = Name.slice(a+1, Name.npos);
+
+ // Look for a suffix starting with a '_'
+ Idx = Foo.rfind('_');
+ if (Idx != Foo.npos && Foo.size() >= 2) {
+ Suffix = Foo.slice(Idx, Foo.npos);
+ Foo = Foo.slice(0, Idx);
+ }
+
+ // First look for the form Foo.framework/Foo
+ b = Name.rfind('/', a);
+ if (b == Name.npos)
+ Idx = 0;
+ else
+ Idx = b+1;
+ F = Name.slice(Idx, Idx + Foo.size());
+ DotFramework = Name.slice(Idx + Foo.size(),
+ Idx + Foo.size() + sizeof(".framework/")-1);
+ if (F == Foo && DotFramework == ".framework/") {
+ isFramework = true;
+ return Foo;
+ }
+
+ // Next look for the form Foo.framework/Versions/A/Foo
+ if (b == Name.npos)
+ goto guess_library;
+ c = Name.rfind('/', b);
+ if (c == Name.npos || c == 0)
+ goto guess_library;
+ V = Name.slice(c+1, Name.npos);
+ if (!V.startswith("Versions/"))
+ goto guess_library;
+ d = Name.rfind('/', c);
+ if (d == Name.npos)
+ Idx = 0;
+ else
+ Idx = d+1;
+ F = Name.slice(Idx, Idx + Foo.size());
+ DotFramework = Name.slice(Idx + Foo.size(),
+ Idx + Foo.size() + sizeof(".framework/")-1);
+ if (F == Foo && DotFramework == ".framework/") {
+ isFramework = true;
+ return Foo;
+ }
+
+guess_library:
+ // pull off the suffix after the "." and make a point to it
+ a = Name.rfind('.');
+ if (a == Name.npos || a == 0)
+ return StringRef();
+ Dylib = Name.slice(a, Name.npos);
+ if (Dylib != ".dylib")
+ goto guess_qtx;
+
+ // First pull off the version letter for the form Foo.A.dylib if any.
+ if (a >= 3) {
+ Dot = Name.slice(a-2, a-1);
+ if (Dot == ".")
+ a = a - 2;
+ }
+
+ b = Name.rfind('/', a);
+ if (b == Name.npos)
+ b = 0;
+ else
+ b = b+1;
+ // ignore any suffix after an underbar like Foo_profile.A.dylib
+ Idx = Name.find('_', b);
+ if (Idx != Name.npos && Idx != b) {
+ Lib = Name.slice(b, Idx);
+ Suffix = Name.slice(Idx, a);
+ }
+ else
+ Lib = Name.slice(b, a);
+ // There are incorrect library names of the form:
+ // libATS.A_profile.dylib so check for these.
+ if (Lib.size() >= 3) {
+ Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
+ if (Dot == ".")
+ Lib = Lib.slice(0, Lib.size()-2);
+ }
+ return Lib;
+
+guess_qtx:
+ Qtx = Name.slice(a, Name.npos);
+ if (Qtx != ".qtx")
+ return StringRef();
+ b = Name.rfind('/', a);
+ if (b == Name.npos)
+ Lib = Name.slice(0, a);
+ else
+ Lib = Name.slice(b+1, a);
+ // There are library names of the form: QT.A.qtx so check for these.
+ if (Lib.size() >= 3) {
+ Dot = Lib.slice(Lib.size()-2, Lib.size()-1);
+ if (Dot == ".")
+ Lib = Lib.slice(0, Lib.size()-2);
+ }
+ return Lib;
+}
+
+// getLibraryShortNameByIndex() is used to get the short name of the library
+// for an undefined symbol in a linked Mach-O binary that was linked with the
+// normal two-level namespace default (that is MH_TWOLEVEL in the header).
+// It is passed the index (0 - based) of the library as translated from
+// GET_LIBRARY_ORDINAL (1 - based).
+std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index,
+ StringRef &Res) {
+ if (Index >= Libraries.size())
+ return object_error::parse_failed;
+
+ MachO::dylib_command D =
+ getStruct<MachO::dylib_command>(this, Libraries[Index]);
+ if (D.dylib.name >= D.cmdsize)
+ return object_error::parse_failed;
+
+ // If the cache of LibrariesShortNames is not built up do that first for
+ // all the Libraries.
+ if (LibrariesShortNames.size() == 0) {
+ for (unsigned i = 0; i < Libraries.size(); i++) {
+ MachO::dylib_command D =
+ getStruct<MachO::dylib_command>(this, Libraries[i]);
+ if (D.dylib.name >= D.cmdsize) {
+ LibrariesShortNames.push_back(StringRef());
+ continue;
+ }
+ const char *P = (const char *)(Libraries[i]) + D.dylib.name;
+ StringRef Name = StringRef(P);
+ StringRef Suffix;
+ bool isFramework;
+ StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix);
+ if (shortName == StringRef())
+ LibrariesShortNames.push_back(Name);
+ else
+ LibrariesShortNames.push_back(shortName);
+ }
+ }
+
+ Res = LibrariesShortNames[Index];
+ return object_error::success;
+}
+
basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
return getSymbolByIndex(0);
}
@@ -1288,6 +1514,108 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
}
}
+Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType) {
+ switch (CPUType) {
+ case MachO::CPU_TYPE_I386:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_I386_ALL:
+ return Triple("i386-apple-darwin");
+ default:
+ return Triple();
+ }
+ case MachO::CPU_TYPE_X86_64:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_X86_64_ALL:
+ return Triple("x86_64-apple-darwin");
+ case MachO::CPU_SUBTYPE_X86_64_H:
+ return Triple("x86_64h-apple-darwin");
+ default:
+ return Triple();
+ }
+ case MachO::CPU_TYPE_ARM:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_ARM_V4T:
+ return Triple("armv4t-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V5TEJ:
+ return Triple("armv5e-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V6:
+ return Triple("armv6-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V6M:
+ return Triple("armv6m-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V7EM:
+ return Triple("armv7em-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V7K:
+ return Triple("armv7k-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V7M:
+ return Triple("armv7m-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM_V7S:
+ return Triple("armv7s-apple-darwin");
+ default:
+ return Triple();
+ }
+ case MachO::CPU_TYPE_ARM64:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_ARM64_ALL:
+ return Triple("arm64-apple-darwin");
+ default:
+ return Triple();
+ }
+ case MachO::CPU_TYPE_POWERPC:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_POWERPC_ALL:
+ return Triple("ppc-apple-darwin");
+ default:
+ return Triple();
+ }
+ case MachO::CPU_TYPE_POWERPC64:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_POWERPC_ALL:
+ return Triple("ppc64-apple-darwin");
+ default:
+ return Triple();
+ }
+ default:
+ return Triple();
+ }
+}
+
+Triple MachOObjectFile::getHostArch() {
+ return Triple(sys::getDefaultTargetTriple());
+}
+
+Triple MachOObjectFile::getArch(StringRef ArchFlag) {
+ if (ArchFlag == "i386")
+ return Triple("i386-apple-darwin");
+ else if (ArchFlag == "x86_64")
+ return Triple("x86_64-apple-darwin");
+ else if (ArchFlag == "x86_64h")
+ return Triple("x86_64h-apple-darwin");
+ else if (ArchFlag == "armv4t" || ArchFlag == "arm")
+ return Triple("armv4t-apple-darwin");
+ else if (ArchFlag == "armv5e")
+ return Triple("armv5e-apple-darwin");
+ else if (ArchFlag == "armv6")
+ return Triple("armv6-apple-darwin");
+ else if (ArchFlag == "armv6m")
+ return Triple("armv6m-apple-darwin");
+ else if (ArchFlag == "armv7em")
+ return Triple("armv7em-apple-darwin");
+ else if (ArchFlag == "armv7k")
+ return Triple("armv7k-apple-darwin");
+ else if (ArchFlag == "armv7k")
+ return Triple("armv7m-apple-darwin");
+ else if (ArchFlag == "armv7s")
+ return Triple("armv7s-apple-darwin");
+ else if (ArchFlag == "arm64")
+ return Triple("arm64-apple-darwin");
+ else if (ArchFlag == "ppc")
+ return Triple("ppc-apple-darwin");
+ else if (ArchFlag == "ppc64")
+ return Triple("ppc64-apple-darwin");
+ else
+ return Triple();
+}
+
unsigned MachOObjectFile::getArch() const {
return getArch(getCPUType(this));
}
@@ -1498,6 +1826,12 @@ MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
return getStruct<MachO::version_min_command>(this, L.Ptr);
}
+MachO::dylib_command
+MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const {
+ return getStruct<MachO::dylib_command>(this, L.Ptr);
+}
+
+
MachO::any_relocation_info
MachOObjectFile::getRelocation(DataRefImpl Rel) const {
DataRefImpl Sec;
@@ -1574,7 +1908,7 @@ StringRef MachOObjectFile::getStringTableData() const {
bool MachOObjectFile::is64Bit() const {
return getType() == getMachOType(false, true) ||
- getType() == getMachOType(true, true);
+ getType() == getMachOType(true, true);
}
void MachOObjectFile::ReadULEB128s(uint64_t Index,
@@ -1589,23 +1923,25 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index,
}
}
-ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
- bool BufferOwned) {
+const char *MachOObjectFile::getSectionPointer(DataRefImpl Rel) const {
+ return Sections[Rel.d.a];
+}
+
+ErrorOr<ObjectFile *>
+ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
StringRef Magic = Buffer->getBuffer().slice(0, 4);
- error_code EC;
+ std::error_code EC;
std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE")
- Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
+ Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC));
else if (Magic == "\xCE\xFA\xED\xFE")
- Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
+ Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC));
else if (Magic == "\xFE\xED\xFA\xCF")
- Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
+ Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC));
else if (Magic == "\xCF\xFA\xED\xFE")
- Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
- else {
- delete Buffer;
+ Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC));
+ else
return object_error::parse_failed;
- }
if (EC)
return EC;
diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp
index 5085efd..4ba5d96 100644
--- a/lib/Object/MachOUniversal.cpp
+++ b/lib/Object/MachOUniversal.cpp
@@ -23,26 +23,21 @@ using namespace llvm;
using namespace object;
template<typename T>
-static void SwapValue(T &Value) {
- Value = sys::SwapByteOrder(Value);
-}
-
-template<typename T>
static void SwapStruct(T &Value);
template<>
void SwapStruct(MachO::fat_header &H) {
- SwapValue(H.magic);
- SwapValue(H.nfat_arch);
+ sys::swapByteOrder(H.magic);
+ sys::swapByteOrder(H.nfat_arch);
}
template<>
void SwapStruct(MachO::fat_arch &H) {
- SwapValue(H.cputype);
- SwapValue(H.cpusubtype);
- SwapValue(H.offset);
- SwapValue(H.size);
- SwapValue(H.align);
+ sys::swapByteOrder(H.cputype);
+ sys::swapByteOrder(H.cpusubtype);
+ sys::swapByteOrder(H.offset);
+ sys::swapByteOrder(H.size);
+ sys::swapByteOrder(H.align);
}
template<typename T>
@@ -58,7 +53,7 @@ static T getUniversalBinaryStruct(const char *Ptr) {
MachOUniversalBinary::ObjectForArch::ObjectForArch(
const MachOUniversalBinary *Parent, uint32_t Index)
: Parent(Parent), Index(Index) {
- if (!Parent || Index > Parent->getNumberOfObjects()) {
+ if (!Parent || Index >= Parent->getNumberOfObjects()) {
clear();
} else {
// Parse object header.
@@ -72,37 +67,29 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch(
}
}
-error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile(
- std::unique_ptr<ObjectFile> &Result) const {
+ErrorOr<std::unique_ptr<ObjectFile>>
+MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
if (Parent) {
StringRef ParentData = Parent->getData();
StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
- std::string ObjectName =
- Parent->getFileName().str() + ":" +
- Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
- MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
- ObjectData, ObjectName, false);
- ErrorOr<ObjectFile *> Obj = ObjectFile::createMachOObjectFile(ObjBuffer);
- if (error_code EC = Obj.getError())
- return EC;
- Result.reset(Obj.get());
- return object_error::success;
+ std::string ObjectName = Parent->getFileName().str();
+ std::unique_ptr<MemoryBuffer> ObjBuffer(
+ MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false));
+ return ObjectFile::createMachOObjectFile(ObjBuffer);
}
return object_error::parse_failed;
}
-error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
+std::error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
std::unique_ptr<Archive> &Result) const {
if (Parent) {
StringRef ParentData = Parent->getData();
StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
- std::string ObjectName =
- Parent->getFileName().str() + ":" +
- Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
- MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
- ObjectData, ObjectName, false);
- ErrorOr<Archive *> Obj = Archive::create(ObjBuffer);
- if (error_code EC = Obj.getError())
+ std::string ObjectName = Parent->getFileName().str();
+ std::unique_ptr<MemoryBuffer> ObjBuffer(
+ MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false));
+ ErrorOr<Archive *> Obj = Archive::create(std::move(ObjBuffer));
+ if (std::error_code EC = Obj.getError())
return EC;
Result.reset(Obj.get());
return object_error::success;
@@ -113,20 +100,20 @@ error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
void MachOUniversalBinary::anchor() { }
ErrorOr<MachOUniversalBinary *>
-MachOUniversalBinary::create(MemoryBuffer *Source) {
- error_code EC;
+MachOUniversalBinary::create(std::unique_ptr<MemoryBuffer> Source) {
+ std::error_code EC;
std::unique_ptr<MachOUniversalBinary> Ret(
- new MachOUniversalBinary(Source, EC));
+ new MachOUniversalBinary(std::move(Source), EC));
if (EC)
return EC;
return Ret.release();
}
-MachOUniversalBinary::MachOUniversalBinary(MemoryBuffer *Source,
- error_code &ec)
- : Binary(Binary::ID_MachOUniversalBinary, Source),
- NumberOfObjects(0) {
- if (Source->getBufferSize() < sizeof(MachO::fat_header)) {
+MachOUniversalBinary::MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source,
+ std::error_code &ec)
+ : Binary(Binary::ID_MachOUniversalBinary, std::move(Source)),
+ NumberOfObjects(0) {
+ if (Data->getBufferSize() < sizeof(MachO::fat_header)) {
ec = object_error::invalid_file_type;
return;
}
@@ -155,14 +142,14 @@ static bool getCTMForArch(Triple::ArchType Arch, MachO::CPUType &CTM) {
}
}
-error_code MachOUniversalBinary::getObjectForArch(
- Triple::ArchType Arch, std::unique_ptr<ObjectFile> &Result) const {
+ErrorOr<std::unique_ptr<ObjectFile>>
+MachOUniversalBinary::getObjectForArch(Triple::ArchType Arch) const {
MachO::CPUType CTM;
if (!getCTMForArch(Arch, CTM))
return object_error::arch_not_found;
for (object_iterator I = begin_objects(), E = end_objects(); I != E; ++I) {
if (I->getCPUType() == static_cast<uint32_t>(CTM))
- return I->getAsObjectFile(Result);
+ return I->getAsObjectFile();
}
return object_error::arch_not_found;
}
diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp
index b0068a8..567d87f 100644
--- a/lib/Object/Object.cpp
+++ b/lib/Object/Object.cpp
@@ -59,7 +59,9 @@ wrap(const relocation_iterator *SI) {
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
- ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf)));
+ std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
+ ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buf));
+ Buf.release();
ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : nullptr;
return wrap(Obj);
}
@@ -89,7 +91,7 @@ void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
LLVMSymbolIteratorRef Sym) {
- if (error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect)))
+ if (std::error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect)))
report_fatal_error(ec.message());
}
@@ -115,28 +117,28 @@ void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
// SectionRef accessors
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
StringRef ret;
- if (error_code ec = (*unwrap(SI))->getName(ret))
+ if (std::error_code ec = (*unwrap(SI))->getName(ret))
report_fatal_error(ec.message());
return ret.data();
}
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
uint64_t ret;
- if (error_code ec = (*unwrap(SI))->getSize(ret))
+ if (std::error_code ec = (*unwrap(SI))->getSize(ret))
report_fatal_error(ec.message());
return ret;
}
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
StringRef ret;
- if (error_code ec = (*unwrap(SI))->getContents(ret))
+ if (std::error_code ec = (*unwrap(SI))->getContents(ret))
report_fatal_error(ec.message());
return ret.data();
}
uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
uint64_t ret;
- if (error_code ec = (*unwrap(SI))->getAddress(ret))
+ if (std::error_code ec = (*unwrap(SI))->getAddress(ret))
report_fatal_error(ec.message());
return ret;
}
@@ -144,7 +146,7 @@ uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
LLVMSymbolIteratorRef Sym) {
bool ret;
- if (error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret))
+ if (std::error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret))
report_fatal_error(ec.message());
return ret;
}
@@ -172,21 +174,21 @@ void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
// SymbolRef accessors
const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
StringRef ret;
- if (error_code ec = (*unwrap(SI))->getName(ret))
+ if (std::error_code ec = (*unwrap(SI))->getName(ret))
report_fatal_error(ec.message());
return ret.data();
}
uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
uint64_t ret;
- if (error_code ec = (*unwrap(SI))->getAddress(ret))
+ if (std::error_code ec = (*unwrap(SI))->getAddress(ret))
report_fatal_error(ec.message());
return ret;
}
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
uint64_t ret;
- if (error_code ec = (*unwrap(SI))->getSize(ret))
+ if (std::error_code ec = (*unwrap(SI))->getSize(ret))
report_fatal_error(ec.message());
return ret;
}
@@ -194,14 +196,14 @@ uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
// RelocationRef accessors
uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) {
uint64_t ret;
- if (error_code ec = (*unwrap(RI))->getAddress(ret))
+ if (std::error_code ec = (*unwrap(RI))->getAddress(ret))
report_fatal_error(ec.message());
return ret;
}
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
uint64_t ret;
- if (error_code ec = (*unwrap(RI))->getOffset(ret))
+ if (std::error_code ec = (*unwrap(RI))->getOffset(ret))
report_fatal_error(ec.message());
return ret;
}
@@ -213,7 +215,7 @@ LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
uint64_t ret;
- if (error_code ec = (*unwrap(RI))->getType(ret))
+ if (std::error_code ec = (*unwrap(RI))->getType(ret))
report_fatal_error(ec.message());
return ret;
}
@@ -221,7 +223,7 @@ uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
// NOTE: Caller takes ownership of returned string.
const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
SmallVector<char, 0> ret;
- if (error_code ec = (*unwrap(RI))->getTypeName(ret))
+ if (std::error_code ec = (*unwrap(RI))->getTypeName(ret))
report_fatal_error(ec.message());
char *str = static_cast<char*>(malloc(ret.size()));
@@ -232,7 +234,7 @@ const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
// NOTE: Caller takes ownership of returned string.
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
SmallVector<char, 0> ret;
- if (error_code ec = (*unwrap(RI))->getValueString(ret))
+ if (std::error_code ec = (*unwrap(RI))->getValueString(ret))
report_fatal_error(ec.message());
char *str = static_cast<char*>(malloc(ret.size()));
diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp
index d30f0cc..f5488c6 100644
--- a/lib/Object/ObjectFile.cpp
+++ b/lib/Object/ObjectFile.cpp
@@ -16,28 +16,27 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
using namespace llvm;
using namespace object;
void ObjectFile::anchor() { }
-ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *Source,
- bool BufferOwned)
- : SymbolicFile(Type, Source, BufferOwned) {}
+ObjectFile::ObjectFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source)
+ : SymbolicFile(Type, std::move(Source)) {}
-error_code ObjectFile::printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const {
+std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const {
StringRef Name;
- if (error_code EC = getSymbolName(Symb, Name))
+ if (std::error_code EC = getSymbolName(Symb, Name))
return EC;
OS << Name;
return object_error::success;
}
-error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI,
- uint32_t &Result) const {
+std::error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI,
+ uint32_t &Result) const {
Result = 0;
return object_error::success;
}
@@ -46,9 +45,9 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
return section_iterator(SectionRef(Sec, this));
}
-ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
- bool BufferOwned,
- sys::fs::file_magic Type) {
+ErrorOr<ObjectFile *>
+ObjectFile::createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
+ sys::fs::file_magic Type) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
@@ -58,14 +57,12 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
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:
- return createELFObjectFile(Object, BufferOwned);
+ return createELFObjectFile(Object);
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,18 +73,19 @@ ErrorOr<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, BufferOwned);
+ return createMachOObjectFile(Object);
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, BufferOwned);
+ return createCOFFObjectFile(std::move(Object));
}
llvm_unreachable("Unexpected Object File Type");
}
ErrorOr<ObjectFile *> ObjectFile::createObjectFile(StringRef ObjectPath) {
- std::unique_ptr<MemoryBuffer> File;
- if (error_code EC = MemoryBuffer::getFile(ObjectPath, File))
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFile(ObjectPath);
+ if (std::error_code EC = FileOrErr.getError())
return EC;
- return createObjectFile(File.release());
+ return createObjectFile(FileOrErr.get());
}
diff --git a/lib/Object/RecordStreamer.cpp b/lib/Object/RecordStreamer.cpp
new file mode 100644
index 0000000..081fadd
--- /dev/null
+++ b/lib/Object/RecordStreamer.cpp
@@ -0,0 +1,100 @@
+//===-- RecordStreamer.cpp - Record asm definde and used symbols ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RecordStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+using namespace llvm;
+
+void RecordStreamer::markDefined(const MCSymbol &Symbol) {
+ State &S = Symbols[Symbol.getName()];
+ switch (S) {
+ case DefinedGlobal:
+ case Global:
+ S = DefinedGlobal;
+ break;
+ case NeverSeen:
+ case Defined:
+ case Used:
+ S = Defined;
+ break;
+ }
+}
+
+void RecordStreamer::markGlobal(const MCSymbol &Symbol) {
+ State &S = Symbols[Symbol.getName()];
+ switch (S) {
+ case DefinedGlobal:
+ case Defined:
+ S = DefinedGlobal;
+ break;
+
+ case NeverSeen:
+ case Global:
+ case Used:
+ S = Global;
+ break;
+ }
+}
+
+void RecordStreamer::markUsed(const MCSymbol &Symbol) {
+ State &S = Symbols[Symbol.getName()];
+ switch (S) {
+ case DefinedGlobal:
+ case Defined:
+ case Global:
+ break;
+
+ case NeverSeen:
+ case Used:
+ S = Used;
+ break;
+ }
+}
+
+void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
+
+RecordStreamer::const_iterator RecordStreamer::begin() {
+ return Symbols.begin();
+}
+
+RecordStreamer::const_iterator RecordStreamer::end() { return Symbols.end(); }
+
+RecordStreamer::RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
+
+void RecordStreamer::EmitInstruction(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ MCStreamer::EmitInstruction(Inst, STI);
+}
+
+void RecordStreamer::EmitLabel(MCSymbol *Symbol) {
+ MCStreamer::EmitLabel(Symbol);
+ markDefined(*Symbol);
+}
+
+void RecordStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+ markDefined(*Symbol);
+ MCStreamer::EmitAssignment(Symbol, Value);
+}
+
+bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+ MCSymbolAttr Attribute) {
+ if (Attribute == MCSA_Global)
+ markGlobal(*Symbol);
+ return true;
+}
+
+void RecordStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {
+ markDefined(*Symbol);
+}
+
+void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
+ markDefined(*Symbol);
+}
diff --git a/lib/Object/RecordStreamer.h b/lib/Object/RecordStreamer.h
new file mode 100644
index 0000000..10e70ef
--- /dev/null
+++ b/lib/Object/RecordStreamer.h
@@ -0,0 +1,42 @@
+//===-- RecordStreamer.h - Record asm defined and used symbols ---*- C++ -*===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_RECORD_STREAMER
+#define LLVM_OBJECT_RECORD_STREAMER
+
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+class RecordStreamer : public MCStreamer {
+public:
+ enum State { NeverSeen, Global, Defined, DefinedGlobal, Used };
+
+private:
+ StringMap<State> Symbols;
+ void markDefined(const MCSymbol &Symbol);
+ void markGlobal(const MCSymbol &Symbol);
+ void markUsed(const MCSymbol &Symbol);
+ void visitUsedSymbol(const MCSymbol &Sym) override;
+
+public:
+ typedef StringMap<State>::const_iterator const_iterator;
+ const_iterator begin();
+ const_iterator end();
+ RecordStreamer(MCContext &Context);
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+};
+}
+#endif
diff --git a/lib/Object/StringTableBuilder.cpp b/lib/Object/StringTableBuilder.cpp
deleted file mode 100644
index 9152834..0000000
--- a/lib/Object/StringTableBuilder.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//===-- StringTableBuilder.cpp - String table building utility ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Object/StringTableBuilder.h"
-
-using namespace llvm;
-
-static bool compareBySuffix(StringRef a, StringRef b) {
- size_t sizeA = a.size();
- size_t sizeB = b.size();
- size_t len = std::min(sizeA, sizeB);
- for (size_t i = 0; i < len; ++i) {
- char ca = a[sizeA - i - 1];
- char cb = b[sizeB - i - 1];
- if (ca != cb)
- return ca > cb;
- }
- return sizeA > sizeB;
-}
-
-void StringTableBuilder::finalize() {
- SmallVector<StringRef, 8> Strings;
- for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
- Strings.push_back(i->getKey());
-
- std::sort(Strings.begin(), Strings.end(), compareBySuffix);
-
- // FIXME: Starting with a null byte is ELF specific. Generalize this so we
- // can use the class with other object formats.
- StringTable += '\x00';
-
- StringRef Previous;
- for (StringRef s : Strings) {
- if (Previous.endswith(s)) {
- StringIndexMap[s] = StringTable.size() - 1 - s.size();
- continue;
- }
-
- StringIndexMap[s] = StringTable.size();
- StringTable += s;
- StringTable += '\x00';
- Previous = s;
- }
-}
diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp
index 495f0b6..30cf1a0 100644
--- a/lib/Object/SymbolicFile.cpp
+++ b/lib/Object/SymbolicFile.cpp
@@ -19,14 +19,14 @@
using namespace llvm;
using namespace object;
-SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source,
- bool BufferOwned)
- : Binary(Type, Source, BufferOwned) {}
+SymbolicFile::SymbolicFile(unsigned int Type,
+ std::unique_ptr<MemoryBuffer> Source)
+ : Binary(Type, std::move(Source)) {}
SymbolicFile::~SymbolicFile() {}
ErrorOr<SymbolicFile *>
-SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
+SymbolicFile::createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
sys::fs::file_magic Type,
LLVMContext *Context) {
if (Type == sys::fs::file_magic::unknown)
@@ -35,14 +35,12 @@ SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
switch (Type) {
case sys::fs::file_magic::bitcode:
if (Context)
- return IRObjectFile::createIRObjectFile(Object, *Context, BufferOwned);
+ return IRObjectFile::createIRObjectFile(std::move(Object), *Context);
// 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:
@@ -61,7 +59,7 @@ SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
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);
+ return ObjectFile::createObjectFile(Object, Type);
}
llvm_unreachable("Unexpected Binary File Type");
}
diff --git a/lib/Object/YAML.cpp b/lib/Object/YAML.cpp
deleted file mode 100644
index 61e9da3..0000000
--- a/lib/Object/YAML.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines utility classes for handling the YAML representation of
-// object files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/YAML.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cctype>
-
-using namespace llvm;
-using namespace object::yaml;
-
-void yaml::ScalarTraits<object::yaml::BinaryRef>::output(
- const object::yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) {
- Val.writeAsHex(Out);
-}
-
-StringRef yaml::ScalarTraits<object::yaml::BinaryRef>::input(
- StringRef Scalar, void *, object::yaml::BinaryRef &Val) {
- if (Scalar.size() % 2 != 0)
- return "BinaryRef hex string must contain an even number of nybbles.";
- // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
- // (e.g. a caret pointing to the offending character).
- for (unsigned I = 0, N = Scalar.size(); I != N; ++I)
- if (!isxdigit(Scalar[I]))
- return "BinaryRef hex string must contain only hex digits.";
- Val = object::yaml::BinaryRef(Scalar);
- return StringRef();
-}
-
-void BinaryRef::writeAsBinary(raw_ostream &OS) const {
- if (!DataIsHexString) {
- OS.write((const char *)Data.data(), Data.size());
- return;
- }
- for (unsigned I = 0, N = Data.size(); I != N; I += 2) {
- uint8_t Byte;
- StringRef((const char *)&Data[I], 2).getAsInteger(16, Byte);
- OS.write(Byte);
- }
-}
-
-void BinaryRef::writeAsHex(raw_ostream &OS) const {
- if (binary_size() == 0)
- return;
- if (DataIsHexString) {
- OS.write((const char *)Data.data(), Data.size());
- return;
- }
- for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
- ++I) {
- uint8_t Byte = *I;
- OS << hexdigit(Byte >> 4);
- OS << hexdigit(Byte & 0xf);
- }
-}