summaryrefslogtreecommitdiff
path: root/lib/Object
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Object')
-rw-r--r--lib/Object/Archive.cpp189
-rw-r--r--lib/Object/ArchiveWriter.cpp208
-rw-r--r--lib/Object/Binary.cpp14
-rw-r--r--lib/Object/CMakeLists.txt4
-rw-r--r--lib/Object/COFFObjectFile.cpp158
-rw-r--r--lib/Object/COFFYAML.cpp503
-rw-r--r--lib/Object/ELF.cpp20
-rw-r--r--lib/Object/ELFObjectFile.cpp67
-rw-r--r--lib/Object/ELFYAML.cpp809
-rw-r--r--lib/Object/Error.cpp43
-rw-r--r--lib/Object/FunctionIndexObjectFile.cpp143
-rw-r--r--lib/Object/IRObjectFile.cpp41
-rw-r--r--lib/Object/MachOObjectFile.cpp404
-rw-r--r--lib/Object/MachOUniversal.cpp120
-rw-r--r--lib/Object/Makefile14
-rw-r--r--lib/Object/ModuleSummaryIndexObjectFile.cpp126
-rw-r--r--lib/Object/Object.cpp40
-rw-r--r--lib/Object/ObjectFile.cpp38
-rw-r--r--lib/Object/RecordStreamer.cpp16
-rw-r--r--lib/Object/RecordStreamer.h4
-rw-r--r--lib/Object/SymbolicFile.cpp14
21 files changed, 1021 insertions, 1954 deletions
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp
index 99b0650c8b7e2..daf301e2e7e45 100644
--- a/lib/Object/Archive.cpp
+++ b/lib/Object/Archive.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/Archive.h"
-#include "llvm/ADT/APInt.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Endian.h"
@@ -52,14 +51,14 @@ ErrorOr<uint32_t> ArchiveMemberHeader::getSize() const {
sys::fs::perms ArchiveMemberHeader::getAccessMode() const {
unsigned Ret;
- if (StringRef(AccessMode, sizeof(AccessMode)).rtrim(" ").getAsInteger(8, Ret))
+ if (StringRef(AccessMode, sizeof(AccessMode)).rtrim(' ').getAsInteger(8, Ret))
llvm_unreachable("Access mode is not an octal number.");
return static_cast<sys::fs::perms>(Ret);
}
sys::TimeValue ArchiveMemberHeader::getLastModified() const {
unsigned Seconds;
- if (StringRef(LastModified, sizeof(LastModified)).rtrim(" ")
+ if (StringRef(LastModified, sizeof(LastModified)).rtrim(' ')
.getAsInteger(10, Seconds))
llvm_unreachable("Last modified time not a decimal number.");
@@ -70,14 +69,20 @@ sys::TimeValue ArchiveMemberHeader::getLastModified() const {
unsigned ArchiveMemberHeader::getUID() const {
unsigned Ret;
- if (StringRef(UID, sizeof(UID)).rtrim(" ").getAsInteger(10, Ret))
+ StringRef User = StringRef(UID, sizeof(UID)).rtrim(' ');
+ if (User.empty())
+ return 0;
+ if (User.getAsInteger(10, Ret))
llvm_unreachable("UID time not a decimal number.");
return Ret;
}
unsigned ArchiveMemberHeader::getGID() const {
unsigned Ret;
- if (StringRef(GID, sizeof(GID)).rtrim(" ").getAsInteger(10, Ret))
+ StringRef Group = StringRef(GID, sizeof(GID)).rtrim(' ');
+ if (Group.empty())
+ return 0;
+ if (Group.getAsInteger(10, Ret))
llvm_unreachable("GID time not a decimal number.");
return Ret;
}
@@ -108,7 +113,7 @@ Archive::Child::Child(const Archive *Parent, const char *Start,
StringRef Name = getRawName();
if (Name.startswith("#1/")) {
uint64_t NameSize;
- if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize))
+ if (Name.substr(3).rtrim(' ').getAsInteger(10, NameSize))
llvm_unreachable("Long name length is not an integer");
StartOfFile += NameSize;
}
@@ -136,6 +141,21 @@ bool Archive::Child::isThinMember() const {
return Parent->IsThin && Name != "/" && Name != "//";
}
+ErrorOr<std::string> Archive::Child::getFullName() const {
+ assert(isThinMember());
+ ErrorOr<StringRef> NameOrErr = getName();
+ if (std::error_code EC = NameOrErr.getError())
+ return EC;
+ StringRef Name = *NameOrErr;
+ if (sys::path::is_absolute(Name))
+ return Name;
+
+ SmallString<128> FullName = sys::path::parent_path(
+ Parent->getMemoryBufferRef().getBufferIdentifier());
+ sys::path::append(FullName, Name);
+ return StringRef(FullName);
+}
+
ErrorOr<StringRef> Archive::Child::getBuffer() const {
if (!isThinMember()) {
ErrorOr<uint32_t> Size = getSize();
@@ -143,12 +163,10 @@ ErrorOr<StringRef> Archive::Child::getBuffer() const {
return EC;
return StringRef(Data.data() + StartOfFile, Size.get());
}
- ErrorOr<StringRef> Name = getName();
- if (std::error_code EC = Name.getError())
+ ErrorOr<std::string> FullNameOrEr = getFullName();
+ if (std::error_code EC = FullNameOrEr.getError())
return EC;
- SmallString<128> FullName = sys::path::parent_path(
- Parent->getMemoryBufferRef().getBufferIdentifier());
- sys::path::append(FullName, *Name);
+ const std::string &FullName = *FullNameOrEr;
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(FullName);
if (std::error_code EC = Buf.getError())
return EC;
@@ -197,7 +215,7 @@ ErrorOr<StringRef> Archive::Child::getName() const {
// It's a long name.
// Get the offset.
std::size_t offset;
- if (name.substr(1).rtrim(" ").getAsInteger(10, offset))
+ if (name.substr(1).rtrim(' ').getAsInteger(10, offset))
llvm_unreachable("Long name offset is not an integer");
// Verify it.
@@ -213,10 +231,14 @@ ErrorOr<StringRef> Archive::Child::getName() const {
return StringRef(addr);
} else if (name.startswith("#1/")) {
uint64_t name_size;
- if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
+ if (name.substr(3).rtrim(' ').getAsInteger(10, name_size))
llvm_unreachable("Long name length is not an ingeter");
- return Data.substr(sizeof(ArchiveMemberHeader), name_size)
- .rtrim(StringRef("\0", 1));
+ return Data.substr(sizeof(ArchiveMemberHeader), name_size).rtrim('\0');
+ } else {
+ // It is not a long name so trim the blanks at the end of the name.
+ if (name[name.size() - 1] != '/') {
+ return name.rtrim(' ');
+ }
}
// It's a simple name.
if (name[name.size() - 1] == '/')
@@ -235,20 +257,23 @@ ErrorOr<MemoryBufferRef> Archive::Child::getMemoryBufferRef() const {
return MemoryBufferRef(*Buf, Name);
}
-ErrorOr<std::unique_ptr<Binary>>
+Expected<std::unique_ptr<Binary>>
Archive::Child::getAsBinary(LLVMContext *Context) const {
ErrorOr<MemoryBufferRef> BuffOrErr = getMemoryBufferRef();
if (std::error_code EC = BuffOrErr.getError())
- return EC;
+ return errorCodeToError(EC);
- return createBinary(BuffOrErr.get(), Context);
+ auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
+ if (BinaryOrErr)
+ return std::move(*BinaryOrErr);
+ return BinaryOrErr.takeError();
}
-ErrorOr<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
- std::error_code EC;
- std::unique_ptr<Archive> Ret(new Archive(Source, EC));
- if (EC)
- return EC;
+Expected<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
+ Error Err;
+ std::unique_ptr<Archive> Ret(new Archive(Source, Err));
+ if (Err)
+ return std::move(Err);
return std::move(Ret);
}
@@ -257,8 +282,9 @@ void Archive::setFirstRegular(const Child &C) {
FirstRegularStartOfFile = C.StartOfFile;
}
-Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
+Archive::Archive(MemoryBufferRef Source, Error &Err)
: Binary(Binary::ID_Archive, Source) {
+ ErrorAsOutParameter ErrAsOutParam(Err);
StringRef Buffer = Data.getBuffer();
// Check for sufficient magic.
if (Buffer.startswith(ThinMagic)) {
@@ -266,27 +292,33 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
} else if (Buffer.startswith(Magic)) {
IsThin = false;
} else {
- ec = object_error::invalid_file_type;
+ Err = make_error<GenericBinaryError>("File too small to be an archive",
+ object_error::invalid_file_type);
return;
}
// Get the special members.
- child_iterator I = child_begin(false);
- if ((ec = I->getError()))
+ child_iterator I = child_begin(Err, false);
+ if (Err)
return;
child_iterator E = child_end();
+ // This is at least a valid empty archive. Since an empty archive is the
+ // same in all formats, just claim it to be gnu to make sure Format is
+ // initialized.
+ Format = K_GNU;
+
if (I == E) {
- ec = std::error_code();
+ Err = Error::success();
return;
}
- const Child *C = &**I;
+ const Child *C = &*I;
auto Increment = [&]() {
++I;
- if ((ec = I->getError()))
+ if (Err)
return true;
- C = &**I;
+ C = &*I;
return false;
};
@@ -311,8 +343,11 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
// seem to create the third member if there's no member whose filename
// exceeds 15 characters. So the third member is optional.
- if (Name == "__.SYMDEF") {
- Format = K_BSD;
+ if (Name == "__.SYMDEF" || Name == "__.SYMDEF_64") {
+ if (Name == "__.SYMDEF")
+ Format = K_BSD;
+ else // Name == "__.SYMDEF_64"
+ Format = K_DARWIN64;
// We know that the symbol table is not an external file, so we just assert
// there is no error.
SymbolTable = *C->getBuffer();
@@ -320,7 +355,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
return;
setFirstRegular(*C);
- ec = std::error_code();
+ Err = Error::success();
return;
}
@@ -328,9 +363,10 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
Format = K_BSD;
// We know this is BSD, so getName will work since there is no string table.
ErrorOr<StringRef> NameOrErr = C->getName();
- ec = NameOrErr.getError();
- if (ec)
+ if (auto ec = NameOrErr.getError()) {
+ Err = errorCodeToError(ec);
return;
+ }
Name = NameOrErr.get();
if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
// We know that the symbol table is not an external file, so we just
@@ -339,6 +375,14 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
if (Increment())
return;
}
+ else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
+ Format = K_DARWIN64;
+ // We know that the symbol table is not an external file, so we just
+ // assert there is no error.
+ SymbolTable = *C->getBuffer();
+ if (Increment())
+ return;
+ }
setFirstRegular(*C);
return;
}
@@ -359,7 +403,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
if (Increment())
return;
if (I == E) {
- ec = std::error_code();
+ Err = Error::success();
return;
}
Name = C->getRawName();
@@ -373,19 +417,19 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
if (Increment())
return;
setFirstRegular(*C);
- ec = std::error_code();
+ Err = Error::success();
return;
}
if (Name[0] != '/') {
Format = has64SymTable ? K_MIPS64 : K_GNU;
setFirstRegular(*C);
- ec = std::error_code();
+ Err = Error::success();
return;
}
if (Name != "/") {
- ec = object_error::parse_failed;
+ Err = errorCodeToError(object_error::parse_failed);
return;
}
@@ -399,7 +443,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
if (I == E) {
setFirstRegular(*C);
- ec = std::error_code();
+ Err = Error::success();
return;
}
@@ -414,26 +458,32 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
}
setFirstRegular(*C);
- ec = std::error_code();
+ Err = Error::success();
}
-Archive::child_iterator Archive::child_begin(bool SkipInternal) const {
+Archive::child_iterator Archive::child_begin(Error &Err,
+ bool SkipInternal) const {
if (Data.getBufferSize() == 8) // empty archive.
return child_end();
if (SkipInternal)
- return Child(this, FirstRegularData, FirstRegularStartOfFile);
+ return child_iterator(Child(this, FirstRegularData,
+ FirstRegularStartOfFile),
+ &Err);
const char *Loc = Data.getBufferStart() + strlen(Magic);
std::error_code EC;
- Child c(this, Loc, &EC);
- if (EC)
- return child_iterator(EC);
- return child_iterator(c);
+ Child C(this, Loc, &EC);
+ if (EC) {
+ ErrorAsOutParameter ErrAsOutParam(Err);
+ Err = errorCodeToError(EC);
+ return child_end();
+ }
+ return child_iterator(C, &Err);
}
Archive::child_iterator Archive::child_end() const {
- return Child(this, nullptr, nullptr);
+ return child_iterator(Child(this, nullptr, nullptr), nullptr);
}
StringRef Archive::Symbol::getName() const {
@@ -443,7 +493,7 @@ StringRef Archive::Symbol::getName() const {
ErrorOr<Archive::Child> Archive::Symbol::getMember() const {
const char *Buf = Parent->getSymbolTable().begin();
const char *Offsets = Buf;
- if (Parent->kind() == K_MIPS64)
+ if (Parent->kind() == K_MIPS64 || Parent->kind() == K_DARWIN64)
Offsets += sizeof(uint64_t);
else
Offsets += sizeof(uint32_t);
@@ -460,6 +510,14 @@ ErrorOr<Archive::Child> Archive::Symbol::getMember() const {
// the archive of the member that defines the symbol. Which is what
// is needed here.
Offset = read32le(Offsets + SymbolIndex * 8 + 4);
+ } else if (Parent->kind() == K_DARWIN64) {
+ // The SymbolIndex is an index into the ranlib_64 structs that start at
+ // Offsets (the first uint64_t is the number of bytes of the ranlib_64
+ // structs). The ranlib_64 structs are a pair of uint64_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 = read64le(Offsets + SymbolIndex * 16 + 8);
} else {
// Skip offsets.
uint32_t MemberCount = read32le(Buf);
@@ -559,6 +617,22 @@ Archive::symbol_iterator Archive::symbol_begin() const {
// Skip the byte count of the string table.
buf += sizeof(uint32_t);
buf += ran_strx;
+ } else if (kind() == K_DARWIN64) {
+ // The __.SYMDEF_64 or "__.SYMDEF_64 SORTED" member starts with a uint64_t
+ // which is the number of bytes of ranlib_64 structs that follow. The
+ // ranlib_64 structs are a pair of uint64_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 uint64_t is the byte
+ // count of the string table followed by the string table.
+ uint64_t ranlib_count = 0;
+ ranlib_count = read64le(buf) / 16;
+ const char *ranlibs = buf + 8;
+ uint64_t ran_strx = 0;
+ ran_strx = read64le(ranlibs);
+ buf += sizeof(uint64_t) + (ranlib_count * (2 * (sizeof(uint64_t))));
+ // Skip the byte count of the string table.
+ buf += sizeof(uint64_t);
+ buf += ran_strx;
} else {
uint32_t member_count = 0;
uint32_t symbol_count = 0;
@@ -585,27 +659,28 @@ uint32_t Archive::getNumberOfSymbols() const {
return read64be(buf);
if (kind() == K_BSD)
return read32le(buf) / 8;
+ if (kind() == K_DARWIN64)
+ return read64le(buf) / 16;
uint32_t member_count = 0;
member_count = read32le(buf);
buf += 4 + (member_count * 4); // Skip offsets.
return read32le(buf);
}
-Archive::child_iterator Archive::findSym(StringRef name) const {
+Expected<Optional<Archive::Child>> Archive::findSym(StringRef name) const {
Archive::symbol_iterator bs = symbol_begin();
Archive::symbol_iterator es = symbol_end();
for (; bs != es; ++bs) {
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 ResultOrErr.get();
+ if (auto MemberOrErr = bs->getMember())
+ return Child(*MemberOrErr);
+ else
+ return errorCodeToError(MemberOrErr.getError());
}
}
- return child_end();
+ return Optional<Child>();
}
bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); }
diff --git a/lib/Object/ArchiveWriter.cpp b/lib/Object/ArchiveWriter.cpp
index c7343fdc171d8..53573262104c3 100644
--- a/lib/Object/ArchiveWriter.cpp
+++ b/lib/Object/ArchiveWriter.cpp
@@ -34,45 +34,61 @@
using namespace llvm;
-NewArchiveIterator::NewArchiveIterator(const object::Archive::Child &OldMember,
- StringRef Name)
- : IsNewMember(false), Name(Name), OldMember(OldMember) {}
-
-NewArchiveIterator::NewArchiveIterator(StringRef FileName)
- : IsNewMember(true), Name(FileName), OldMember(nullptr, nullptr, nullptr) {}
-
-StringRef NewArchiveIterator::getName() const { return Name; }
-
-bool NewArchiveIterator::isNewMember() const { return IsNewMember; }
-
-const object::Archive::Child &NewArchiveIterator::getOld() const {
- assert(!IsNewMember);
- return OldMember;
-}
-
-StringRef NewArchiveIterator::getNew() const {
- assert(IsNewMember);
- return Name;
+NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
+ : Buf(MemoryBuffer::getMemBuffer(BufRef, false)) {}
+
+Expected<NewArchiveMember>
+NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
+ bool Deterministic) {
+ ErrorOr<llvm::MemoryBufferRef> BufOrErr = OldMember.getMemoryBufferRef();
+ if (!BufOrErr)
+ return errorCodeToError(BufOrErr.getError());
+
+ NewArchiveMember M;
+ M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
+ if (!Deterministic) {
+ M.ModTime = OldMember.getLastModified();
+ M.UID = OldMember.getUID();
+ M.GID = OldMember.getGID();
+ M.Perms = OldMember.getAccessMode();
+ }
+ return std::move(M);
}
-llvm::ErrorOr<int>
-NewArchiveIterator::getFD(sys::fs::file_status &NewStatus) const {
- assert(IsNewMember);
- int NewFD;
- if (auto EC = sys::fs::openFileForRead(Name, NewFD))
- return EC;
- assert(NewFD != -1);
+Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName,
+ bool Deterministic) {
+ sys::fs::file_status Status;
+ int FD;
+ if (auto EC = sys::fs::openFileForRead(FileName, FD))
+ return errorCodeToError(EC);
+ assert(FD != -1);
- if (auto EC = sys::fs::status(NewFD, NewStatus))
- return EC;
+ if (auto EC = sys::fs::status(FD, Status))
+ return errorCodeToError(EC);
// Opening a directory doesn't make sense. Let it fail.
// Linux cannot open directories with open(2), although
// cygwin and *bsd can.
- if (NewStatus.type() == sys::fs::file_type::directory_file)
- return make_error_code(errc::is_a_directory);
-
- return NewFD;
+ if (Status.type() == sys::fs::file_type::directory_file)
+ return errorCodeToError(make_error_code(errc::is_a_directory));
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
+ MemoryBuffer::getOpenFile(FD, FileName, Status.getSize(), false);
+ if (!MemberBufferOrErr)
+ return errorCodeToError(MemberBufferOrErr.getError());
+
+ if (close(FD) != 0)
+ return errorCodeToError(std::error_code(errno, std::generic_category()));
+
+ NewArchiveMember M;
+ M.Buf = std::move(*MemberBufferOrErr);
+ if (!Deterministic) {
+ M.ModTime = Status.getLastModificationTime();
+ M.UID = Status.getUser();
+ M.GID = Status.getGroup();
+ M.Perms = Status.permissions();
+ }
+ return std::move(M);
}
template <typename T>
@@ -178,12 +194,13 @@ static std::string computeRelativePath(StringRef From, StringRef To) {
}
static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName,
- ArrayRef<NewArchiveIterator> Members,
+ ArrayRef<NewArchiveMember> Members,
std::vector<unsigned> &StringMapIndexes,
bool Thin) {
unsigned StartOffset = 0;
- for (const NewArchiveIterator &I : Members) {
- StringRef Name = sys::path::filename(I.getName());
+ for (const NewArchiveMember &M : Members) {
+ StringRef Path = M.Buf->getBufferIdentifier();
+ StringRef Name = sys::path::filename(Path);
if (!useStringTable(Thin, Name))
continue;
if (StartOffset == 0) {
@@ -194,7 +211,7 @@ static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName,
StringMapIndexes.push_back(Out.tell() - StartOffset);
if (Thin)
- Out << computeRelativePath(ArcName, I.getName());
+ Out << computeRelativePath(ArcName, Path);
else
Out << Name;
@@ -221,8 +238,7 @@ static sys::TimeValue now(bool Deterministic) {
// Returns the offset of the first reference to a member offset.
static ErrorOr<unsigned>
writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
- ArrayRef<NewArchiveIterator> Members,
- ArrayRef<MemoryBufferRef> Buffers,
+ ArrayRef<NewArchiveMember> Members,
std::vector<unsigned> &MemberOffsetRefs, bool Deterministic) {
unsigned HeaderStartOffset = 0;
unsigned BodyStartOffset = 0;
@@ -230,12 +246,15 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
raw_svector_ostream NameOS(NameBuf);
LLVMContext Context;
for (unsigned MemberNum = 0, N = Members.size(); MemberNum < N; ++MemberNum) {
- MemoryBufferRef MemberBuffer = Buffers[MemberNum];
- ErrorOr<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
+ MemoryBufferRef MemberBuffer = Members[MemberNum].Buf->getMemBufferRef();
+ Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
object::SymbolicFile::createSymbolicFile(
MemberBuffer, sys::fs::file_magic::unknown, &Context);
- if (!ObjOrErr)
- continue; // FIXME: check only for "not an object file" errors.
+ if (!ObjOrErr) {
+ // FIXME: check only for "not an object file" errors.
+ consumeError(ObjOrErr.takeError());
+ continue;
+ }
object::SymbolicFile &Obj = *ObjOrErr.get();
if (!HeaderStartOffset) {
@@ -302,9 +321,12 @@ writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind,
std::pair<StringRef, std::error_code>
llvm::writeArchive(StringRef ArcName,
- std::vector<NewArchiveIterator> &NewMembers,
+ std::vector<NewArchiveMember> &NewMembers,
bool WriteSymtab, object::Archive::Kind Kind,
- bool Deterministic, bool Thin) {
+ bool Deterministic, bool Thin,
+ std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
+ assert((!Thin || Kind == object::Archive::K_GNU) &&
+ "Only the gnu format has a thin mode");
SmallString<128> TmpArchive;
int TmpArchiveFD;
if (auto EC = sys::fs::createUniqueFile(ArcName + ".temp-archive-%%%%%%%.a",
@@ -324,44 +346,10 @@ llvm::writeArchive(StringRef ArcName,
std::vector<MemoryBufferRef> Members;
std::vector<sys::fs::file_status> NewMemberStatus;
- for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) {
- NewArchiveIterator &Member = NewMembers[I];
- MemoryBufferRef MemberRef;
-
- if (Member.isNewMember()) {
- StringRef Filename = Member.getNew();
- NewMemberStatus.resize(NewMemberStatus.size() + 1);
- sys::fs::file_status &Status = NewMemberStatus.back();
- ErrorOr<int> FD = Member.getFD(Status);
- if (auto EC = FD.getError())
- return std::make_pair(Filename, EC);
- ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
- MemoryBuffer::getOpenFile(FD.get(), Filename, Status.getSize(),
- false);
- if (auto EC = MemberBufferOrErr.getError())
- return std::make_pair(Filename, EC);
- if (close(FD.get()) != 0)
- return std::make_pair(Filename,
- std::error_code(errno, std::generic_category()));
- Buffers.push_back(std::move(MemberBufferOrErr.get()));
- MemberRef = Buffers.back()->getMemBufferRef();
- } else {
- const object::Archive::Child &OldMember = Member.getOld();
- assert((!Thin || OldMember.getParent()->isThin()) &&
- "Thin archives cannot refers to member of other archives");
- ErrorOr<MemoryBufferRef> MemberBufferOrErr =
- OldMember.getMemoryBufferRef();
- if (auto EC = MemberBufferOrErr.getError())
- return std::make_pair("", EC);
- MemberRef = MemberBufferOrErr.get();
- }
- Members.push_back(MemberRef);
- }
-
unsigned MemberReferenceOffset = 0;
if (WriteSymtab) {
ErrorOr<unsigned> MemberReferenceOffsetOrErr = writeSymbolTable(
- Out, Kind, NewMembers, Members, MemberOffsetRefs, Deterministic);
+ Out, Kind, NewMembers, MemberOffsetRefs, Deterministic);
if (auto EC = MemberReferenceOffsetOrErr.getError())
return std::make_pair(ArcName, EC);
MemberReferenceOffset = MemberReferenceOffsetOrErr.get();
@@ -371,55 +359,18 @@ llvm::writeArchive(StringRef ArcName,
if (Kind != object::Archive::K_BSD)
writeStringTable(Out, ArcName, NewMembers, StringMapIndexes, Thin);
- unsigned MemberNum = 0;
- unsigned NewMemberNum = 0;
std::vector<unsigned>::iterator StringMapIndexIter = StringMapIndexes.begin();
std::vector<unsigned> MemberOffset;
- for (const NewArchiveIterator &I : NewMembers) {
- MemoryBufferRef File = Members[MemberNum++];
+ for (const NewArchiveMember &M : NewMembers) {
+ MemoryBufferRef File = M.Buf->getMemBufferRef();
unsigned Pos = Out.tell();
MemberOffset.push_back(Pos);
- sys::TimeValue ModTime;
- unsigned UID;
- unsigned GID;
- unsigned Perms;
- if (Deterministic) {
- ModTime.fromEpochTime(0);
- UID = 0;
- GID = 0;
- Perms = 0644;
- } else if (I.isNewMember()) {
- const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum];
- ModTime = Status.getLastModificationTime();
- UID = Status.getUser();
- GID = Status.getGroup();
- Perms = Status.permissions();
- } else {
- const object::Archive::Child &OldMember = I.getOld();
- ModTime = OldMember.getLastModified();
- UID = OldMember.getUID();
- GID = OldMember.getGID();
- Perms = OldMember.getAccessMode();
- }
-
- if (I.isNewMember()) {
- StringRef FileName = I.getNew();
- const sys::fs::file_status &Status = NewMemberStatus[NewMemberNum++];
- printMemberHeader(Out, Kind, Thin, sys::path::filename(FileName),
- StringMapIndexIter, ModTime, UID, GID, Perms,
- Status.getSize());
- } else {
- const object::Archive::Child &OldMember = I.getOld();
- ErrorOr<uint32_t> Size = OldMember.getSize();
- if (std::error_code EC = Size.getError())
- return std::make_pair("", EC);
- StringRef FileName = I.getName();
- printMemberHeader(Out, Kind, Thin, sys::path::filename(FileName),
- StringMapIndexIter, ModTime, UID, GID, Perms,
- Size.get());
- }
+ printMemberHeader(Out, Kind, Thin,
+ sys::path::filename(M.Buf->getBufferIdentifier()),
+ StringMapIndexIter, M.ModTime, M.UID, M.GID, M.Perms,
+ M.Buf->getBufferSize());
if (!Thin)
Out << File.getBuffer();
@@ -439,6 +390,19 @@ llvm::writeArchive(StringRef ArcName,
Output.keep();
Out.close();
+
+ // At this point, we no longer need whatever backing memory
+ // was used to generate the NewMembers. On Windows, this buffer
+ // could be a mapped view of the file we want to replace (if
+ // we're updating an existing archive, say). In that case, the
+ // rename would still succeed, but it would leave behind a
+ // temporary file (actually the original file renamed) because
+ // a file cannot be deleted while there's a handle open on it,
+ // only renamed. So by freeing this buffer, this ensures that
+ // the last open handle on the destination file, if any, is
+ // closed before we attempt to rename.
+ OldArchiveBuf.reset();
+
sys::fs::rename(TmpArchive, ArcName);
return std::make_pair("", std::error_code());
}
diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp
index a2b167a665c56..ec051fec375bd 100644
--- a/lib/Object/Binary.cpp
+++ b/lib/Object/Binary.cpp
@@ -36,7 +36,7 @@ StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
-ErrorOr<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
+Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
LLVMContext *Context) {
sys::fs::file_magic Type = sys::fs::identify_magic(Buffer.getBuffer());
@@ -69,22 +69,22 @@ ErrorOr<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::windows_resource:
// Unrecognized object file format.
- return object_error::invalid_file_type;
+ return errorCodeToError(object_error::invalid_file_type);
}
llvm_unreachable("Unexpected Binary File Type");
}
-ErrorOr<OwningBinary<Binary>> object::createBinary(StringRef Path) {
+Expected<OwningBinary<Binary>> object::createBinary(StringRef Path) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Path);
if (std::error_code EC = FileOrErr.getError())
- return EC;
+ return errorCodeToError(EC);
std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
- ErrorOr<std::unique_ptr<Binary>> BinOrErr =
+ Expected<std::unique_ptr<Binary>> BinOrErr =
createBinary(Buffer->getMemBufferRef());
- if (std::error_code EC = BinOrErr.getError())
- return EC;
+ if (!BinOrErr)
+ return BinOrErr.takeError();
std::unique_ptr<Binary> &Bin = BinOrErr.get();
return OwningBinary<Binary>(std::move(Bin), std::move(Buffer));
diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt
index 2ac2ee51dc232..0a37cc360fe9d 100644
--- a/lib/Object/CMakeLists.txt
+++ b/lib/Object/CMakeLists.txt
@@ -3,20 +3,18 @@ add_llvm_library(LLVMObject
ArchiveWriter.cpp
Binary.cpp
COFFObjectFile.cpp
- COFFYAML.cpp
ELF.cpp
ELFObjectFile.cpp
- ELFYAML.cpp
Error.cpp
IRObjectFile.cpp
MachOObjectFile.cpp
MachOUniversal.cpp
+ ModuleSummaryIndexObjectFile.cpp
Object.cpp
ObjectFile.cpp
RecordStreamer.cpp
SymbolicFile.cpp
SymbolSize.cpp
- FunctionIndexObjectFile.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/Object
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp
index 4cd6aff5f17cb..0f790086cfc58 100644
--- a/lib/Object/COFFObjectFile.cpp
+++ b/lib/Object/COFFObjectFile.cpp
@@ -13,7 +13,6 @@
#include "llvm/Object/COFF.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
@@ -145,12 +144,12 @@ void COFFObjectFile::moveSymbolNext(DataRefImpl &Ref) const {
}
}
-ErrorOr<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
+Expected<StringRef> COFFObjectFile::getSymbolName(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
StringRef Result;
std::error_code EC = getSymbolName(Symb, Result);
if (EC)
- return EC;
+ return errorCodeToError(EC);
return Result;
}
@@ -158,7 +157,7 @@ uint64_t COFFObjectFile::getSymbolValueImpl(DataRefImpl Ref) const {
return getCOFFSymbol(Ref).getValue();
}
-ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
+Expected<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
uint64_t Result = getSymbolValue(Ref);
COFFSymbolRef Symb = getCOFFSymbol(Ref);
int32_t SectionNumber = Symb.getSectionNumber();
@@ -169,7 +168,7 @@ ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
const coff_section *Section = nullptr;
if (std::error_code EC = getSection(SectionNumber, Section))
- return EC;
+ return errorCodeToError(EC);
Result += Section->VirtualAddress;
// The section VirtualAddress does not include ImageBase, and we want to
@@ -179,7 +178,7 @@ ErrorOr<uint64_t> COFFObjectFile::getSymbolAddress(DataRefImpl Ref) const {
return Result;
}
-SymbolRef::Type COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
+Expected<SymbolRef::Type> COFFObjectFile::getSymbolType(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
int32_t SectionNumber = Symb.getSectionNumber();
@@ -235,14 +234,14 @@ uint64_t COFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Ref) const {
return Symb.getValue();
}
-ErrorOr<section_iterator>
+Expected<section_iterator>
COFFObjectFile::getSymbolSection(DataRefImpl Ref) const {
COFFSymbolRef Symb = getCOFFSymbol(Ref);
if (COFF::isReservedSectionNumber(Symb.getSectionNumber()))
return section_end();
const coff_section *Sec = nullptr;
if (std::error_code EC = getSection(Symb.getSectionNumber(), Sec))
- return EC;
+ return errorCodeToError(EC);
DataRefImpl Ret;
Ret.p = reinterpret_cast<uintptr_t>(Sec);
return section_iterator(SectionRef(Ret, this));
@@ -290,7 +289,11 @@ std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const {
const coff_section *Sec = toSec(Ref);
- return uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1);
+ return Sec->getAlignment();
+}
+
+bool COFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
+ return false;
}
bool COFFObjectFile::isSectionText(DataRefImpl Ref) const {
@@ -450,6 +453,27 @@ std::error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
return object_error::parse_failed;
}
+std::error_code
+COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const {
+ for (const SectionRef &S : sections()) {
+ const coff_section *Section = getCOFFSection(S);
+ uint32_t SectionStart = Section->VirtualAddress;
+ // Check if this RVA is within the section bounds. Be careful about integer
+ // overflow.
+ uint32_t OffsetIntoSection = RVA - SectionStart;
+ if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&
+ Size <= Section->VirtualSize - OffsetIntoSection) {
+ uintptr_t Begin =
+ uintptr_t(base()) + Section->PointerToRawData + OffsetIntoSection;
+ Contents =
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Begin), Size);
+ return std::error_code();
+ }
+ }
+ return object_error::parse_failed;
+}
+
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
// table entry.
std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
@@ -463,6 +487,35 @@ std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint,
return std::error_code();
}
+std::error_code COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
+ const debug_pdb_info *&PDBInfo,
+ StringRef &PDBFileName) const {
+ ArrayRef<uint8_t> InfoBytes;
+ if (std::error_code EC = getRvaAndSizeAsBytes(
+ DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes))
+ return EC;
+ if (InfoBytes.size() < sizeof(debug_pdb_info) + 1)
+ return object_error::parse_failed;
+ PDBInfo = reinterpret_cast<const debug_pdb_info *>(InfoBytes.data());
+ InfoBytes = InfoBytes.drop_front(sizeof(debug_pdb_info));
+ PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),
+ InfoBytes.size());
+ // Truncate the name at the first null byte. Ignore any padding.
+ PDBFileName = PDBFileName.split('\0').first;
+ return std::error_code();
+}
+
+std::error_code COFFObjectFile::getDebugPDBInfo(const debug_pdb_info *&PDBInfo,
+ StringRef &PDBFileName) const {
+ for (const debug_directory &D : debug_directories())
+ if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW)
+ return getDebugPDBInfo(&D, PDBInfo, PDBFileName);
+ // If we get here, there is no PDB info to return.
+ PDBInfo = nullptr;
+ PDBFileName = StringRef();
+ return std::error_code();
+}
+
// Find the import table.
std::error_code COFFObjectFile::initImportTablePtr() {
// First, we get the RVA of the import table. If the file lacks a pointer to
@@ -476,15 +529,14 @@ std::error_code COFFObjectFile::initImportTablePtr() {
return std::error_code();
uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
- // -1 because the last entry is the null entry.
- NumberOfImportDirectory = DataEntry->Size /
- sizeof(import_directory_table_entry) - 1;
// 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 (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
return EC;
+ if (std::error_code EC = checkOffset(Data, IntPtr, DataEntry->Size))
+ return EC;
ImportDirectory = reinterpret_cast<
const import_directory_table_entry *>(IntPtr);
return std::error_code();
@@ -548,15 +600,40 @@ std::error_code COFFObjectFile::initBaseRelocPtr() {
return std::error_code();
}
+std::error_code COFFObjectFile::initDebugDirectoryPtr() {
+ // Get the RVA of the debug directory. Do nothing if it does not exist.
+ const data_directory *DataEntry;
+ if (getDataDirectory(COFF::DEBUG_DIRECTORY, DataEntry))
+ return std::error_code();
+
+ // Do nothing if the RVA is NULL.
+ if (DataEntry->RelativeVirtualAddress == 0)
+ return std::error_code();
+
+ // Check that the size is a multiple of the entry size.
+ if (DataEntry->Size % sizeof(debug_directory) != 0)
+ return object_error::parse_failed;
+
+ uintptr_t IntPtr = 0;
+ if (std::error_code EC = getRvaPtr(DataEntry->RelativeVirtualAddress, IntPtr))
+ return EC;
+ DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);
+ if (std::error_code EC = getRvaPtr(
+ DataEntry->RelativeVirtualAddress + DataEntry->Size, IntPtr))
+ return EC;
+ DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(IntPtr);
+ return std::error_code();
+}
+
COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
: ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
- ImportDirectory(nullptr), NumberOfImportDirectory(0),
+ ImportDirectory(nullptr),
DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
- ExportDirectory(nullptr), BaseRelocHeader(nullptr),
- BaseRelocEnd(nullptr) {
+ ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
+ DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
// Check that we at least have enough room for a header.
if (!checkSize(Data, EC, sizeof(coff_file_header)))
return;
@@ -672,6 +749,10 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
if ((EC = initBaseRelocPtr()))
return;
+ // Initialize the pointer to the export table.
+ if ((EC = initDebugDirectoryPtr()))
+ return;
+
EC = std::error_code();
}
@@ -689,13 +770,17 @@ basic_symbol_iterator COFFObjectFile::symbol_end_impl() const {
}
import_directory_iterator COFFObjectFile::import_directory_begin() const {
+ if (!ImportDirectory)
+ return import_directory_end();
+ if (ImportDirectory[0].ImportLookupTableRVA == 0)
+ return import_directory_end();
return import_directory_iterator(
ImportDirectoryEntryRef(ImportDirectory, 0, this));
}
import_directory_iterator COFFObjectFile::import_directory_end() const {
return import_directory_iterator(
- ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this));
+ ImportDirectoryEntryRef(nullptr, -1, this));
}
delay_import_directory_iterator
@@ -947,10 +1032,10 @@ uint64_t COFFObjectFile::getSectionSize(const coff_section *Sec) const {
std::error_code
COFFObjectFile::getSectionContents(const coff_section *Sec,
ArrayRef<uint8_t> &Res) const {
- // PointerToRawData and SizeOfRawData won't make sense for BSS sections,
- // don't do anything interesting for them.
- assert((Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0 &&
- "BSS sections don't have contents!");
+ // In COFF, a virtual section won't have any in-file
+ // content, so the file pointer to the content will be zero.
+ if (Sec->PointerToRawData == 0)
+ return object_error::parse_failed;
// 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.
@@ -1116,12 +1201,15 @@ operator==(const ImportDirectoryEntryRef &Other) const {
void ImportDirectoryEntryRef::moveNext() {
++Index;
+ if (ImportTable[Index].ImportLookupTableRVA == 0) {
+ Index = -1;
+ ImportTable = nullptr;
+ }
}
std::error_code ImportDirectoryEntryRef::getImportTableEntry(
const import_directory_table_entry *&Result) const {
- Result = ImportTable + Index;
- return std::error_code();
+ return getObject(Result, OwningObject->Data, ImportTable + Index);
}
static imported_symbol_iterator
@@ -1198,16 +1286,6 @@ ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
return std::error_code();
}
-std::error_code ImportDirectoryEntryRef::getImportLookupEntry(
- const import_lookup_table_entry32 *&Result) const {
- uintptr_t IntPtr = 0;
- uint32_t RVA = ImportTable[Index].ImportLookupTableRVA;
- if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
- return EC;
- Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
- return std::error_code();
-}
-
bool DelayImportDirectoryEntryRef::
operator==(const DelayImportDirectoryEntryRef &Other) const {
return Table == Other.Table && Index == Other.Index;
@@ -1391,6 +1469,22 @@ ImportedSymbolRef::getSymbolName(StringRef &Result) const {
return std::error_code();
}
+std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
+ if (Entry32)
+ Result = Entry32[Index].isOrdinal();
+ else
+ Result = Entry64[Index].isOrdinal();
+ return std::error_code();
+}
+
+std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
+ if (Entry32)
+ Result = Entry32[Index].getHintNameRVA();
+ else
+ Result = Entry64[Index].getHintNameRVA();
+ return std::error_code();
+}
+
std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
uint32_t RVA;
if (Entry32) {
diff --git a/lib/Object/COFFYAML.cpp b/lib/Object/COFFYAML.cpp
deleted file mode 100644
index 4c1fca19bf1b9..0000000000000
--- a/lib/Object/COFFYAML.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-//===- COFFYAML.cpp - COFF YAMLIO implementation --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines classes for handling the YAML representation of COFF.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/COFFYAML.h"
-
-#define ECase(X) IO.enumCase(Value, #X, COFF::X);
-namespace llvm {
-
-namespace COFFYAML {
-Section::Section() { memset(&Header, 0, sizeof(COFF::section)); }
-Symbol::Symbol() { memset(&Header, 0, sizeof(COFF::symbol)); }
-Object::Object() { memset(&Header, 0, sizeof(COFF::header)); }
-}
-
-namespace yaml {
-void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration(
- IO &IO, COFFYAML::COMDATType &Value) {
- IO.enumCase(Value, "0", 0);
- ECase(IMAGE_COMDAT_SELECT_NODUPLICATES);
- ECase(IMAGE_COMDAT_SELECT_ANY);
- ECase(IMAGE_COMDAT_SELECT_SAME_SIZE);
- ECase(IMAGE_COMDAT_SELECT_EXACT_MATCH);
- ECase(IMAGE_COMDAT_SELECT_ASSOCIATIVE);
- ECase(IMAGE_COMDAT_SELECT_LARGEST);
- ECase(IMAGE_COMDAT_SELECT_NEWEST);
-}
-
-void
-ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics>::enumeration(
- IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
- IO.enumCase(Value, "0", 0);
- ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
- ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
- ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
-}
-
-void ScalarEnumerationTraits<COFFYAML::AuxSymbolType>::enumeration(
- IO &IO, COFFYAML::AuxSymbolType &Value) {
- ECase(IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF);
-}
-
-void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
- IO &IO, COFF::MachineTypes &Value) {
- ECase(IMAGE_FILE_MACHINE_UNKNOWN);
- ECase(IMAGE_FILE_MACHINE_AM33);
- ECase(IMAGE_FILE_MACHINE_AMD64);
- ECase(IMAGE_FILE_MACHINE_ARM);
- ECase(IMAGE_FILE_MACHINE_ARMNT);
- ECase(IMAGE_FILE_MACHINE_ARM64);
- ECase(IMAGE_FILE_MACHINE_EBC);
- ECase(IMAGE_FILE_MACHINE_I386);
- ECase(IMAGE_FILE_MACHINE_IA64);
- ECase(IMAGE_FILE_MACHINE_M32R);
- ECase(IMAGE_FILE_MACHINE_MIPS16);
- ECase(IMAGE_FILE_MACHINE_MIPSFPU);
- ECase(IMAGE_FILE_MACHINE_MIPSFPU16);
- ECase(IMAGE_FILE_MACHINE_POWERPC);
- ECase(IMAGE_FILE_MACHINE_POWERPCFP);
- ECase(IMAGE_FILE_MACHINE_R4000);
- ECase(IMAGE_FILE_MACHINE_SH3);
- ECase(IMAGE_FILE_MACHINE_SH3DSP);
- ECase(IMAGE_FILE_MACHINE_SH4);
- ECase(IMAGE_FILE_MACHINE_SH5);
- ECase(IMAGE_FILE_MACHINE_THUMB);
- ECase(IMAGE_FILE_MACHINE_WCEMIPSV2);
-}
-
-void ScalarEnumerationTraits<COFF::SymbolBaseType>::enumeration(
- IO &IO, COFF::SymbolBaseType &Value) {
- ECase(IMAGE_SYM_TYPE_NULL);
- ECase(IMAGE_SYM_TYPE_VOID);
- ECase(IMAGE_SYM_TYPE_CHAR);
- ECase(IMAGE_SYM_TYPE_SHORT);
- ECase(IMAGE_SYM_TYPE_INT);
- ECase(IMAGE_SYM_TYPE_LONG);
- ECase(IMAGE_SYM_TYPE_FLOAT);
- ECase(IMAGE_SYM_TYPE_DOUBLE);
- ECase(IMAGE_SYM_TYPE_STRUCT);
- ECase(IMAGE_SYM_TYPE_UNION);
- ECase(IMAGE_SYM_TYPE_ENUM);
- ECase(IMAGE_SYM_TYPE_MOE);
- ECase(IMAGE_SYM_TYPE_BYTE);
- ECase(IMAGE_SYM_TYPE_WORD);
- ECase(IMAGE_SYM_TYPE_UINT);
- ECase(IMAGE_SYM_TYPE_DWORD);
-}
-
-void ScalarEnumerationTraits<COFF::SymbolStorageClass>::enumeration(
- IO &IO, COFF::SymbolStorageClass &Value) {
- ECase(IMAGE_SYM_CLASS_END_OF_FUNCTION);
- ECase(IMAGE_SYM_CLASS_NULL);
- ECase(IMAGE_SYM_CLASS_AUTOMATIC);
- ECase(IMAGE_SYM_CLASS_EXTERNAL);
- ECase(IMAGE_SYM_CLASS_STATIC);
- ECase(IMAGE_SYM_CLASS_REGISTER);
- ECase(IMAGE_SYM_CLASS_EXTERNAL_DEF);
- ECase(IMAGE_SYM_CLASS_LABEL);
- ECase(IMAGE_SYM_CLASS_UNDEFINED_LABEL);
- ECase(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT);
- ECase(IMAGE_SYM_CLASS_ARGUMENT);
- ECase(IMAGE_SYM_CLASS_STRUCT_TAG);
- ECase(IMAGE_SYM_CLASS_MEMBER_OF_UNION);
- ECase(IMAGE_SYM_CLASS_UNION_TAG);
- ECase(IMAGE_SYM_CLASS_TYPE_DEFINITION);
- ECase(IMAGE_SYM_CLASS_UNDEFINED_STATIC);
- ECase(IMAGE_SYM_CLASS_ENUM_TAG);
- ECase(IMAGE_SYM_CLASS_MEMBER_OF_ENUM);
- ECase(IMAGE_SYM_CLASS_REGISTER_PARAM);
- ECase(IMAGE_SYM_CLASS_BIT_FIELD);
- ECase(IMAGE_SYM_CLASS_BLOCK);
- ECase(IMAGE_SYM_CLASS_FUNCTION);
- ECase(IMAGE_SYM_CLASS_END_OF_STRUCT);
- ECase(IMAGE_SYM_CLASS_FILE);
- ECase(IMAGE_SYM_CLASS_SECTION);
- ECase(IMAGE_SYM_CLASS_WEAK_EXTERNAL);
- ECase(IMAGE_SYM_CLASS_CLR_TOKEN);
-}
-
-void ScalarEnumerationTraits<COFF::SymbolComplexType>::enumeration(
- IO &IO, COFF::SymbolComplexType &Value) {
- ECase(IMAGE_SYM_DTYPE_NULL);
- ECase(IMAGE_SYM_DTYPE_POINTER);
- ECase(IMAGE_SYM_DTYPE_FUNCTION);
- ECase(IMAGE_SYM_DTYPE_ARRAY);
-}
-
-void ScalarEnumerationTraits<COFF::RelocationTypeI386>::enumeration(
- IO &IO, COFF::RelocationTypeI386 &Value) {
- ECase(IMAGE_REL_I386_ABSOLUTE);
- ECase(IMAGE_REL_I386_DIR16);
- ECase(IMAGE_REL_I386_REL16);
- ECase(IMAGE_REL_I386_DIR32);
- ECase(IMAGE_REL_I386_DIR32NB);
- ECase(IMAGE_REL_I386_SEG12);
- ECase(IMAGE_REL_I386_SECTION);
- ECase(IMAGE_REL_I386_SECREL);
- ECase(IMAGE_REL_I386_TOKEN);
- ECase(IMAGE_REL_I386_SECREL7);
- ECase(IMAGE_REL_I386_REL32);
-}
-
-void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration(
- IO &IO, COFF::RelocationTypeAMD64 &Value) {
- ECase(IMAGE_REL_AMD64_ABSOLUTE);
- ECase(IMAGE_REL_AMD64_ADDR64);
- ECase(IMAGE_REL_AMD64_ADDR32);
- ECase(IMAGE_REL_AMD64_ADDR32NB);
- ECase(IMAGE_REL_AMD64_REL32);
- ECase(IMAGE_REL_AMD64_REL32_1);
- ECase(IMAGE_REL_AMD64_REL32_2);
- ECase(IMAGE_REL_AMD64_REL32_3);
- ECase(IMAGE_REL_AMD64_REL32_4);
- ECase(IMAGE_REL_AMD64_REL32_5);
- ECase(IMAGE_REL_AMD64_SECTION);
- ECase(IMAGE_REL_AMD64_SECREL);
- ECase(IMAGE_REL_AMD64_SECREL7);
- ECase(IMAGE_REL_AMD64_TOKEN);
- ECase(IMAGE_REL_AMD64_SREL32);
- ECase(IMAGE_REL_AMD64_PAIR);
- ECase(IMAGE_REL_AMD64_SSPAN32);
-}
-
-void ScalarEnumerationTraits<COFF::WindowsSubsystem>::enumeration(
- IO &IO, COFF::WindowsSubsystem &Value) {
- ECase(IMAGE_SUBSYSTEM_UNKNOWN);
- ECase(IMAGE_SUBSYSTEM_NATIVE);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_GUI);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_CUI);
- ECase(IMAGE_SUBSYSTEM_OS2_CUI);
- ECase(IMAGE_SUBSYSTEM_POSIX_CUI);
- ECase(IMAGE_SUBSYSTEM_NATIVE_WINDOWS);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI);
- ECase(IMAGE_SUBSYSTEM_EFI_APPLICATION);
- ECase(IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER);
- ECase(IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER);
- ECase(IMAGE_SUBSYSTEM_EFI_ROM);
- ECase(IMAGE_SUBSYSTEM_XBOX);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION);
-}
-#undef ECase
-
-#define BCase(X) IO.bitSetCase(Value, #X, COFF::X);
-void ScalarBitSetTraits<COFF::Characteristics>::bitset(
- IO &IO, COFF::Characteristics &Value) {
- BCase(IMAGE_FILE_RELOCS_STRIPPED);
- BCase(IMAGE_FILE_EXECUTABLE_IMAGE);
- BCase(IMAGE_FILE_LINE_NUMS_STRIPPED);
- BCase(IMAGE_FILE_LOCAL_SYMS_STRIPPED);
- BCase(IMAGE_FILE_AGGRESSIVE_WS_TRIM);
- BCase(IMAGE_FILE_LARGE_ADDRESS_AWARE);
- BCase(IMAGE_FILE_BYTES_REVERSED_LO);
- BCase(IMAGE_FILE_32BIT_MACHINE);
- BCase(IMAGE_FILE_DEBUG_STRIPPED);
- BCase(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP);
- BCase(IMAGE_FILE_NET_RUN_FROM_SWAP);
- BCase(IMAGE_FILE_SYSTEM);
- BCase(IMAGE_FILE_DLL);
- BCase(IMAGE_FILE_UP_SYSTEM_ONLY);
- BCase(IMAGE_FILE_BYTES_REVERSED_HI);
-}
-
-void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset(
- IO &IO, COFF::SectionCharacteristics &Value) {
- BCase(IMAGE_SCN_TYPE_NOLOAD);
- BCase(IMAGE_SCN_TYPE_NO_PAD);
- BCase(IMAGE_SCN_CNT_CODE);
- BCase(IMAGE_SCN_CNT_INITIALIZED_DATA);
- BCase(IMAGE_SCN_CNT_UNINITIALIZED_DATA);
- BCase(IMAGE_SCN_LNK_OTHER);
- BCase(IMAGE_SCN_LNK_INFO);
- BCase(IMAGE_SCN_LNK_REMOVE);
- BCase(IMAGE_SCN_LNK_COMDAT);
- BCase(IMAGE_SCN_GPREL);
- BCase(IMAGE_SCN_MEM_PURGEABLE);
- BCase(IMAGE_SCN_MEM_16BIT);
- BCase(IMAGE_SCN_MEM_LOCKED);
- BCase(IMAGE_SCN_MEM_PRELOAD);
- BCase(IMAGE_SCN_LNK_NRELOC_OVFL);
- BCase(IMAGE_SCN_MEM_DISCARDABLE);
- BCase(IMAGE_SCN_MEM_NOT_CACHED);
- BCase(IMAGE_SCN_MEM_NOT_PAGED);
- BCase(IMAGE_SCN_MEM_SHARED);
- BCase(IMAGE_SCN_MEM_EXECUTE);
- BCase(IMAGE_SCN_MEM_READ);
- BCase(IMAGE_SCN_MEM_WRITE);
-}
-
-void ScalarBitSetTraits<COFF::DLLCharacteristics>::bitset(
- IO &IO, COFF::DLLCharacteristics &Value) {
- BCase(IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA);
- BCase(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE);
- BCase(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY);
- BCase(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT);
- BCase(IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION);
- BCase(IMAGE_DLL_CHARACTERISTICS_NO_SEH);
- BCase(IMAGE_DLL_CHARACTERISTICS_NO_BIND);
- BCase(IMAGE_DLL_CHARACTERISTICS_APPCONTAINER);
- BCase(IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER);
- BCase(IMAGE_DLL_CHARACTERISTICS_GUARD_CF);
- BCase(IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE);
-}
-#undef BCase
-
-namespace {
-struct NSectionSelectionType {
- NSectionSelectionType(IO &)
- : SelectionType(COFFYAML::COMDATType(0)) {}
- NSectionSelectionType(IO &, uint8_t C)
- : SelectionType(COFFYAML::COMDATType(C)) {}
- uint8_t denormalize(IO &) { return SelectionType; }
- COFFYAML::COMDATType SelectionType;
-};
-
-struct NWeakExternalCharacteristics {
- NWeakExternalCharacteristics(IO &)
- : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {}
- NWeakExternalCharacteristics(IO &, uint32_t C)
- : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {}
- uint32_t denormalize(IO &) { return Characteristics; }
- COFFYAML::WeakExternalCharacteristics Characteristics;
-};
-
-struct NSectionCharacteristics {
- NSectionCharacteristics(IO &)
- : Characteristics(COFF::SectionCharacteristics(0)) {}
- NSectionCharacteristics(IO &, uint32_t C)
- : Characteristics(COFF::SectionCharacteristics(C)) {}
- uint32_t denormalize(IO &) { return Characteristics; }
- COFF::SectionCharacteristics Characteristics;
-};
-
-struct NAuxTokenType {
- NAuxTokenType(IO &)
- : AuxType(COFFYAML::AuxSymbolType(0)) {}
- NAuxTokenType(IO &, uint8_t C)
- : AuxType(COFFYAML::AuxSymbolType(C)) {}
- uint32_t denormalize(IO &) { return AuxType; }
- COFFYAML::AuxSymbolType AuxType;
-};
-
-struct NStorageClass {
- NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {}
- NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {}
- uint8_t denormalize(IO &) { return StorageClass; }
-
- COFF::SymbolStorageClass StorageClass;
-};
-
-struct NMachine {
- NMachine(IO &) : Machine(COFF::MachineTypes(0)) {}
- NMachine(IO &, uint16_t M) : Machine(COFF::MachineTypes(M)) {}
- uint16_t denormalize(IO &) { return Machine; }
- COFF::MachineTypes Machine;
-};
-
-struct NHeaderCharacteristics {
- NHeaderCharacteristics(IO &) : Characteristics(COFF::Characteristics(0)) {}
- NHeaderCharacteristics(IO &, uint16_t C)
- : Characteristics(COFF::Characteristics(C)) {}
- uint16_t denormalize(IO &) { return Characteristics; }
-
- COFF::Characteristics Characteristics;
-};
-
-template <typename RelocType>
-struct NType {
- NType(IO &) : Type(RelocType(0)) {}
- NType(IO &, uint16_t T) : Type(RelocType(T)) {}
- uint16_t denormalize(IO &) { return Type; }
- RelocType Type;
-};
-
-struct NWindowsSubsystem {
- NWindowsSubsystem(IO &) : Subsystem(COFF::WindowsSubsystem(0)) {}
- NWindowsSubsystem(IO &, uint16_t C) : Subsystem(COFF::WindowsSubsystem(C)) {}
- uint16_t denormalize(IO &) { return Subsystem; }
-
- COFF::WindowsSubsystem Subsystem;
-};
-
-struct NDLLCharacteristics {
- NDLLCharacteristics(IO &) : Characteristics(COFF::DLLCharacteristics(0)) {}
- NDLLCharacteristics(IO &, uint16_t C)
- : Characteristics(COFF::DLLCharacteristics(C)) {}
- uint16_t denormalize(IO &) { return Characteristics; }
-
- COFF::DLLCharacteristics Characteristics;
-};
-
-}
-
-void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO,
- COFFYAML::Relocation &Rel) {
- IO.mapRequired("VirtualAddress", Rel.VirtualAddress);
- IO.mapRequired("SymbolName", Rel.SymbolName);
-
- COFF::header &H = *static_cast<COFF::header *>(IO.getContext());
- if (H.Machine == COFF::IMAGE_FILE_MACHINE_I386) {
- MappingNormalization<NType<COFF::RelocationTypeI386>, uint16_t> NT(
- IO, Rel.Type);
- IO.mapRequired("Type", NT->Type);
- } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) {
- MappingNormalization<NType<COFF::RelocationTypeAMD64>, uint16_t> NT(
- IO, Rel.Type);
- IO.mapRequired("Type", NT->Type);
- } else {
- IO.mapRequired("Type", Rel.Type);
- }
-}
-
-void MappingTraits<COFF::DataDirectory>::mapping(IO &IO,
- COFF::DataDirectory &DD) {
- IO.mapRequired("RelativeVirtualAddress", DD.RelativeVirtualAddress);
- IO.mapRequired("Size", DD.Size);
-}
-
-void MappingTraits<COFFYAML::PEHeader>::mapping(IO &IO,
- COFFYAML::PEHeader &PH) {
- MappingNormalization<NWindowsSubsystem, uint16_t> NWS(IO,
- PH.Header.Subsystem);
- MappingNormalization<NDLLCharacteristics, uint16_t> NDC(
- IO, PH.Header.DLLCharacteristics);
-
- IO.mapRequired("AddressOfEntryPoint", PH.Header.AddressOfEntryPoint);
- IO.mapRequired("ImageBase", PH.Header.ImageBase);
- IO.mapRequired("SectionAlignment", PH.Header.SectionAlignment);
- IO.mapRequired("FileAlignment", PH.Header.FileAlignment);
- IO.mapRequired("MajorOperatingSystemVersion",
- PH.Header.MajorOperatingSystemVersion);
- IO.mapRequired("MinorOperatingSystemVersion",
- PH.Header.MinorOperatingSystemVersion);
- IO.mapRequired("MajorImageVersion", PH.Header.MajorImageVersion);
- IO.mapRequired("MinorImageVersion", PH.Header.MinorImageVersion);
- IO.mapRequired("MajorSubsystemVersion", PH.Header.MajorSubsystemVersion);
- IO.mapRequired("MinorSubsystemVersion", PH.Header.MinorSubsystemVersion);
- IO.mapRequired("Subsystem", NWS->Subsystem);
- IO.mapRequired("DLLCharacteristics", NDC->Characteristics);
- IO.mapRequired("SizeOfStackReserve", PH.Header.SizeOfStackReserve);
- IO.mapRequired("SizeOfStackCommit", PH.Header.SizeOfStackCommit);
- IO.mapRequired("SizeOfHeapReserve", PH.Header.SizeOfHeapReserve);
- IO.mapRequired("SizeOfHeapCommit", PH.Header.SizeOfHeapCommit);
-
- IO.mapOptional("ExportTable", PH.DataDirectories[COFF::EXPORT_TABLE]);
- IO.mapOptional("ImportTable", PH.DataDirectories[COFF::IMPORT_TABLE]);
- IO.mapOptional("ResourceTable", PH.DataDirectories[COFF::RESOURCE_TABLE]);
- IO.mapOptional("ExceptionTable", PH.DataDirectories[COFF::EXCEPTION_TABLE]);
- IO.mapOptional("CertificateTable", PH.DataDirectories[COFF::CERTIFICATE_TABLE]);
- IO.mapOptional("BaseRelocationTable",
- PH.DataDirectories[COFF::BASE_RELOCATION_TABLE]);
- IO.mapOptional("Debug", PH.DataDirectories[COFF::DEBUG]);
- IO.mapOptional("Architecture", PH.DataDirectories[COFF::ARCHITECTURE]);
- IO.mapOptional("GlobalPtr", PH.DataDirectories[COFF::GLOBAL_PTR]);
- IO.mapOptional("TlsTable", PH.DataDirectories[COFF::TLS_TABLE]);
- IO.mapOptional("LoadConfigTable",
- PH.DataDirectories[COFF::LOAD_CONFIG_TABLE]);
- IO.mapOptional("BoundImport", PH.DataDirectories[COFF::BOUND_IMPORT]);
- IO.mapOptional("IAT", PH.DataDirectories[COFF::IAT]);
- IO.mapOptional("DelayImportDescriptor",
- PH.DataDirectories[COFF::DELAY_IMPORT_DESCRIPTOR]);
- IO.mapOptional("ClrRuntimeHeader",
- PH.DataDirectories[COFF::CLR_RUNTIME_HEADER]);
-}
-
-void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
- MappingNormalization<NMachine, uint16_t> NM(IO, H.Machine);
- MappingNormalization<NHeaderCharacteristics, uint16_t> NC(IO,
- H.Characteristics);
-
- IO.mapRequired("Machine", NM->Machine);
- IO.mapOptional("Characteristics", NC->Characteristics);
- IO.setContext(static_cast<void *>(&H));
-}
-
-void MappingTraits<COFF::AuxiliaryFunctionDefinition>::mapping(
- IO &IO, COFF::AuxiliaryFunctionDefinition &AFD) {
- IO.mapRequired("TagIndex", AFD.TagIndex);
- IO.mapRequired("TotalSize", AFD.TotalSize);
- IO.mapRequired("PointerToLinenumber", AFD.PointerToLinenumber);
- IO.mapRequired("PointerToNextFunction", AFD.PointerToNextFunction);
-}
-
-void MappingTraits<COFF::AuxiliarybfAndefSymbol>::mapping(
- IO &IO, COFF::AuxiliarybfAndefSymbol &AAS) {
- IO.mapRequired("Linenumber", AAS.Linenumber);
- IO.mapRequired("PointerToNextFunction", AAS.PointerToNextFunction);
-}
-
-void MappingTraits<COFF::AuxiliaryWeakExternal>::mapping(
- IO &IO, COFF::AuxiliaryWeakExternal &AWE) {
- MappingNormalization<NWeakExternalCharacteristics, uint32_t> NWEC(
- IO, AWE.Characteristics);
- IO.mapRequired("TagIndex", AWE.TagIndex);
- IO.mapRequired("Characteristics", NWEC->Characteristics);
-}
-
-void MappingTraits<COFF::AuxiliarySectionDefinition>::mapping(
- IO &IO, COFF::AuxiliarySectionDefinition &ASD) {
- MappingNormalization<NSectionSelectionType, uint8_t> NSST(
- IO, ASD.Selection);
-
- IO.mapRequired("Length", ASD.Length);
- IO.mapRequired("NumberOfRelocations", ASD.NumberOfRelocations);
- IO.mapRequired("NumberOfLinenumbers", ASD.NumberOfLinenumbers);
- IO.mapRequired("CheckSum", ASD.CheckSum);
- IO.mapRequired("Number", ASD.Number);
- IO.mapOptional("Selection", NSST->SelectionType, COFFYAML::COMDATType(0));
-}
-
-void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
- IO &IO, COFF::AuxiliaryCLRToken &ACT) {
- MappingNormalization<NAuxTokenType, uint8_t> NATT(IO, ACT.AuxType);
- IO.mapRequired("AuxType", NATT->AuxType);
- IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
-}
-
-void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
- MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass);
-
- IO.mapRequired("Name", S.Name);
- IO.mapRequired("Value", S.Header.Value);
- IO.mapRequired("SectionNumber", S.Header.SectionNumber);
- IO.mapRequired("SimpleType", S.SimpleType);
- IO.mapRequired("ComplexType", S.ComplexType);
- IO.mapRequired("StorageClass", NS->StorageClass);
- IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
- IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
- IO.mapOptional("WeakExternal", S.WeakExternal);
- IO.mapOptional("File", S.File, StringRef());
- IO.mapOptional("SectionDefinition", S.SectionDefinition);
- IO.mapOptional("CLRToken", S.CLRToken);
-}
-
-void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
- MappingNormalization<NSectionCharacteristics, uint32_t> NC(
- IO, Sec.Header.Characteristics);
- IO.mapRequired("Name", Sec.Name);
- IO.mapRequired("Characteristics", NC->Characteristics);
- IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U);
- IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U);
- IO.mapOptional("Alignment", Sec.Alignment);
- IO.mapRequired("SectionData", Sec.SectionData);
- IO.mapOptional("Relocations", Sec.Relocations);
-}
-
-void MappingTraits<COFFYAML::Object>::mapping(IO &IO, COFFYAML::Object &Obj) {
- IO.mapOptional("OptionalHeader", Obj.OptionalHeader);
- IO.mapRequired("header", Obj.Header);
- IO.mapRequired("sections", Obj.Sections);
- IO.mapRequired("symbols", Obj.Symbols);
-}
-
-}
-}
diff --git a/lib/Object/ELF.cpp b/lib/Object/ELF.cpp
index 12b772d930bac..2dde18a242805 100644
--- a/lib/Object/ELF.cpp
+++ b/lib/Object/ELF.cpp
@@ -61,6 +61,13 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
break;
}
break;
+ case ELF::EM_LANAI:
+ switch (Type) {
+#include "llvm/Support/ELFRelocs/Lanai.def"
+ default:
+ break;
+ }
+ break;
case ELF::EM_PPC:
switch (Type) {
#include "llvm/Support/ELFRelocs/PowerPC.def"
@@ -98,6 +105,19 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
break;
}
break;
+ case ELF::EM_AMDGPU:
+ switch (Type) {
+#include "llvm/Support/ELFRelocs/AMDGPU.def"
+ default:
+ break;
+ }
+ case ELF::EM_BPF:
+ switch (Type) {
+#include "llvm/Support/ELFRelocs/BPF.def"
+ default:
+ break;
+ }
+ break;
default:
break;
}
diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp
index c7df30a590351..4bd69e34e3c3b 100644
--- a/lib/Object/ELFObjectFile.cpp
+++ b/lib/Object/ELFObjectFile.cpp
@@ -55,4 +55,71 @@ ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
return std::move(R);
}
+SubtargetFeatures ELFObjectFileBase::getFeatures() const {
+ switch (getEMachine()) {
+ case ELF::EM_MIPS: {
+ SubtargetFeatures Features;
+ unsigned PlatformFlags;
+ getPlatformFlags(PlatformFlags);
+
+ switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
+ case ELF::EF_MIPS_ARCH_1:
+ break;
+ case ELF::EF_MIPS_ARCH_2:
+ Features.AddFeature("mips2");
+ break;
+ case ELF::EF_MIPS_ARCH_3:
+ Features.AddFeature("mips3");
+ break;
+ case ELF::EF_MIPS_ARCH_4:
+ Features.AddFeature("mips4");
+ break;
+ case ELF::EF_MIPS_ARCH_5:
+ Features.AddFeature("mips5");
+ break;
+ case ELF::EF_MIPS_ARCH_32:
+ Features.AddFeature("mips32");
+ break;
+ case ELF::EF_MIPS_ARCH_64:
+ Features.AddFeature("mips64");
+ break;
+ case ELF::EF_MIPS_ARCH_32R2:
+ Features.AddFeature("mips32r2");
+ break;
+ case ELF::EF_MIPS_ARCH_64R2:
+ Features.AddFeature("mips64r2");
+ break;
+ case ELF::EF_MIPS_ARCH_32R6:
+ Features.AddFeature("mips32r6");
+ break;
+ case ELF::EF_MIPS_ARCH_64R6:
+ Features.AddFeature("mips64r6");
+ break;
+ default:
+ llvm_unreachable("Unknown EF_MIPS_ARCH value");
+ }
+
+ switch (PlatformFlags & ELF::EF_MIPS_MACH) {
+ case ELF::EF_MIPS_MACH_NONE:
+ // No feature associated with this value.
+ break;
+ case ELF::EF_MIPS_MACH_OCTEON:
+ Features.AddFeature("cnmips");
+ break;
+ default:
+ llvm_unreachable("Unknown EF_MIPS_ARCH value");
+ }
+
+ if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
+ Features.AddFeature("mips16");
+ if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
+ Features.AddFeature("micromips");
+
+ return Features;
+ }
+ default:
+ return SubtargetFeatures();
+ }
+}
+
} // end namespace llvm
diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp
deleted file mode 100644
index 4a4b2276f46b5..0000000000000
--- a/lib/Object/ELFYAML.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-//===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines classes for handling the YAML representation of ELF.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/ELFYAML.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/MipsABIFlags.h"
-
-namespace llvm {
-
-ELFYAML::Section::~Section() {}
-
-namespace yaml {
-
-void
-ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(IO &IO,
- ELFYAML::ELF_ET &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(ET_NONE)
- ECase(ET_REL)
- ECase(ET_EXEC)
- ECase(ET_DYN)
- ECase(ET_CORE)
-#undef ECase
- IO.enumFallback<Hex16>(Value);
-}
-
-void
-ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO,
- ELFYAML::ELF_EM &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(EM_NONE)
- ECase(EM_M32)
- ECase(EM_SPARC)
- ECase(EM_386)
- ECase(EM_68K)
- ECase(EM_88K)
- ECase(EM_IAMCU)
- ECase(EM_860)
- ECase(EM_MIPS)
- ECase(EM_S370)
- ECase(EM_MIPS_RS3_LE)
- ECase(EM_PARISC)
- ECase(EM_VPP500)
- ECase(EM_SPARC32PLUS)
- ECase(EM_960)
- ECase(EM_PPC)
- ECase(EM_PPC64)
- ECase(EM_S390)
- ECase(EM_SPU)
- ECase(EM_V800)
- ECase(EM_FR20)
- ECase(EM_RH32)
- ECase(EM_RCE)
- ECase(EM_ARM)
- ECase(EM_ALPHA)
- ECase(EM_SH)
- ECase(EM_SPARCV9)
- ECase(EM_TRICORE)
- ECase(EM_ARC)
- ECase(EM_H8_300)
- ECase(EM_H8_300H)
- ECase(EM_H8S)
- ECase(EM_H8_500)
- ECase(EM_IA_64)
- ECase(EM_MIPS_X)
- ECase(EM_COLDFIRE)
- ECase(EM_68HC12)
- ECase(EM_MMA)
- ECase(EM_PCP)
- ECase(EM_NCPU)
- ECase(EM_NDR1)
- ECase(EM_STARCORE)
- ECase(EM_ME16)
- ECase(EM_ST100)
- ECase(EM_TINYJ)
- ECase(EM_X86_64)
- ECase(EM_PDSP)
- ECase(EM_PDP10)
- ECase(EM_PDP11)
- ECase(EM_FX66)
- ECase(EM_ST9PLUS)
- ECase(EM_ST7)
- ECase(EM_68HC16)
- ECase(EM_68HC11)
- ECase(EM_68HC08)
- ECase(EM_68HC05)
- ECase(EM_SVX)
- ECase(EM_ST19)
- ECase(EM_VAX)
- ECase(EM_CRIS)
- ECase(EM_JAVELIN)
- ECase(EM_FIREPATH)
- ECase(EM_ZSP)
- ECase(EM_MMIX)
- ECase(EM_HUANY)
- ECase(EM_PRISM)
- ECase(EM_AVR)
- ECase(EM_FR30)
- ECase(EM_D10V)
- ECase(EM_D30V)
- ECase(EM_V850)
- ECase(EM_M32R)
- ECase(EM_MN10300)
- ECase(EM_MN10200)
- ECase(EM_PJ)
- ECase(EM_OPENRISC)
- ECase(EM_ARC_COMPACT)
- ECase(EM_XTENSA)
- ECase(EM_VIDEOCORE)
- ECase(EM_TMM_GPP)
- ECase(EM_NS32K)
- ECase(EM_TPC)
- ECase(EM_SNP1K)
- ECase(EM_ST200)
- ECase(EM_IP2K)
- ECase(EM_MAX)
- ECase(EM_CR)
- ECase(EM_F2MC16)
- ECase(EM_MSP430)
- ECase(EM_BLACKFIN)
- ECase(EM_SE_C33)
- ECase(EM_SEP)
- ECase(EM_ARCA)
- ECase(EM_UNICORE)
- ECase(EM_EXCESS)
- ECase(EM_DXP)
- ECase(EM_ALTERA_NIOS2)
- ECase(EM_CRX)
- ECase(EM_XGATE)
- ECase(EM_C166)
- ECase(EM_M16C)
- ECase(EM_DSPIC30F)
- ECase(EM_CE)
- ECase(EM_M32C)
- ECase(EM_TSK3000)
- ECase(EM_RS08)
- ECase(EM_SHARC)
- ECase(EM_ECOG2)
- ECase(EM_SCORE7)
- ECase(EM_DSP24)
- ECase(EM_VIDEOCORE3)
- ECase(EM_LATTICEMICO32)
- ECase(EM_SE_C17)
- ECase(EM_TI_C6000)
- ECase(EM_TI_C2000)
- ECase(EM_TI_C5500)
- ECase(EM_MMDSP_PLUS)
- ECase(EM_CYPRESS_M8C)
- ECase(EM_R32C)
- ECase(EM_TRIMEDIA)
- ECase(EM_HEXAGON)
- ECase(EM_8051)
- ECase(EM_STXP7X)
- ECase(EM_NDS32)
- ECase(EM_ECOG1)
- ECase(EM_ECOG1X)
- ECase(EM_MAXQ30)
- ECase(EM_XIMO16)
- ECase(EM_MANIK)
- ECase(EM_CRAYNV2)
- ECase(EM_RX)
- ECase(EM_METAG)
- ECase(EM_MCST_ELBRUS)
- ECase(EM_ECOG16)
- ECase(EM_CR16)
- ECase(EM_ETPU)
- ECase(EM_SLE9X)
- ECase(EM_L10M)
- ECase(EM_K10M)
- ECase(EM_AARCH64)
- ECase(EM_AVR32)
- ECase(EM_STM8)
- ECase(EM_TILE64)
- ECase(EM_TILEPRO)
- ECase(EM_CUDA)
- ECase(EM_TILEGX)
- ECase(EM_CLOUDSHIELD)
- ECase(EM_COREA_1ST)
- ECase(EM_COREA_2ND)
- ECase(EM_ARC_COMPACT2)
- ECase(EM_OPEN8)
- ECase(EM_RL78)
- ECase(EM_VIDEOCORE5)
- ECase(EM_78KOR)
- ECase(EM_56800EX)
- ECase(EM_AMDGPU)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
- IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it
- // here.
- ECase(ELFCLASS32)
- ECase(ELFCLASS64)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
- IO &IO, ELFYAML::ELF_ELFDATA &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- // Since the semantics of ELFDATANONE is "invalid", just don't accept it
- // here.
- ECase(ELFDATA2LSB)
- ECase(ELFDATA2MSB)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
- IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(ELFOSABI_NONE)
- ECase(ELFOSABI_HPUX)
- ECase(ELFOSABI_NETBSD)
- ECase(ELFOSABI_GNU)
- ECase(ELFOSABI_GNU)
- ECase(ELFOSABI_HURD)
- ECase(ELFOSABI_SOLARIS)
- ECase(ELFOSABI_AIX)
- ECase(ELFOSABI_IRIX)
- ECase(ELFOSABI_FREEBSD)
- ECase(ELFOSABI_TRU64)
- ECase(ELFOSABI_MODESTO)
- ECase(ELFOSABI_OPENBSD)
- ECase(ELFOSABI_OPENVMS)
- ECase(ELFOSABI_NSK)
- ECase(ELFOSABI_AROS)
- ECase(ELFOSABI_FENIXOS)
- ECase(ELFOSABI_CLOUDABI)
- ECase(ELFOSABI_C6000_ELFABI)
- ECase(ELFOSABI_C6000_LINUX)
- ECase(ELFOSABI_ARM)
- ECase(ELFOSABI_STANDALONE)
-#undef ECase
-}
-
-void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
- ELFYAML::ELF_EF &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
-#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M);
- switch (Object->Header.Machine) {
- case ELF::EM_ARM:
- BCase(EF_ARM_SOFT_FLOAT)
- BCase(EF_ARM_VFP_FLOAT)
- BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK)
- break;
- case ELF::EM_MIPS:
- BCase(EF_MIPS_NOREORDER)
- BCase(EF_MIPS_PIC)
- BCase(EF_MIPS_CPIC)
- BCase(EF_MIPS_ABI2)
- BCase(EF_MIPS_32BITMODE)
- BCase(EF_MIPS_FP64)
- BCase(EF_MIPS_NAN2008)
- BCase(EF_MIPS_MICROMIPS)
- BCase(EF_MIPS_ARCH_ASE_M16)
- BCase(EF_MIPS_ARCH_ASE_MDMX)
- BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH)
- break;
- case ELF::EM_HEXAGON:
- BCase(EF_HEXAGON_MACH_V2)
- BCase(EF_HEXAGON_MACH_V3)
- BCase(EF_HEXAGON_MACH_V4)
- BCase(EF_HEXAGON_MACH_V5)
- BCase(EF_HEXAGON_ISA_V2)
- BCase(EF_HEXAGON_ISA_V3)
- BCase(EF_HEXAGON_ISA_V4)
- BCase(EF_HEXAGON_ISA_V5)
- break;
- case ELF::EM_AVR:
- BCase(EF_AVR_ARCH_AVR1)
- BCase(EF_AVR_ARCH_AVR2)
- BCase(EF_AVR_ARCH_AVR25)
- BCase(EF_AVR_ARCH_AVR3)
- BCase(EF_AVR_ARCH_AVR31)
- BCase(EF_AVR_ARCH_AVR35)
- BCase(EF_AVR_ARCH_AVR4)
- BCase(EF_AVR_ARCH_AVR51)
- BCase(EF_AVR_ARCH_AVR6)
- BCase(EF_AVR_ARCH_AVRTINY)
- BCase(EF_AVR_ARCH_XMEGA1)
- BCase(EF_AVR_ARCH_XMEGA2)
- BCase(EF_AVR_ARCH_XMEGA3)
- BCase(EF_AVR_ARCH_XMEGA4)
- BCase(EF_AVR_ARCH_XMEGA5)
- BCase(EF_AVR_ARCH_XMEGA6)
- BCase(EF_AVR_ARCH_XMEGA7)
- break;
- default:
- llvm_unreachable("Unsupported architecture");
- }
-#undef BCase
-#undef BCaseMask
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
- IO &IO, ELFYAML::ELF_SHT &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(SHT_NULL)
- ECase(SHT_PROGBITS)
- // No SHT_SYMTAB. Use the top-level `Symbols` key instead.
- // FIXME: Issue a diagnostic with this information.
- ECase(SHT_STRTAB)
- ECase(SHT_RELA)
- ECase(SHT_HASH)
- ECase(SHT_DYNAMIC)
- ECase(SHT_NOTE)
- ECase(SHT_NOBITS)
- ECase(SHT_REL)
- ECase(SHT_SHLIB)
- ECase(SHT_DYNSYM)
- ECase(SHT_INIT_ARRAY)
- ECase(SHT_FINI_ARRAY)
- ECase(SHT_PREINIT_ARRAY)
- ECase(SHT_GROUP)
- ECase(SHT_SYMTAB_SHNDX)
- ECase(SHT_LOOS)
- ECase(SHT_GNU_ATTRIBUTES)
- ECase(SHT_GNU_HASH)
- ECase(SHT_GNU_verdef)
- ECase(SHT_GNU_verneed)
- ECase(SHT_GNU_versym)
- ECase(SHT_HIOS)
- ECase(SHT_LOPROC)
- switch (Object->Header.Machine) {
- case ELF::EM_ARM:
- ECase(SHT_ARM_EXIDX)
- ECase(SHT_ARM_PREEMPTMAP)
- ECase(SHT_ARM_ATTRIBUTES)
- ECase(SHT_ARM_DEBUGOVERLAY)
- ECase(SHT_ARM_OVERLAYSECTION)
- break;
- case ELF::EM_HEXAGON:
- ECase(SHT_HEX_ORDERED)
- break;
- case ELF::EM_X86_64:
- ECase(SHT_X86_64_UNWIND)
- break;
- case ELF::EM_MIPS:
- ECase(SHT_MIPS_REGINFO)
- ECase(SHT_MIPS_OPTIONS)
- ECase(SHT_MIPS_ABIFLAGS)
- break;
- default:
- // Nothing to do.
- break;
- }
-#undef ECase
-}
-
-void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
- ELFYAML::ELF_SHF &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
-#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
- BCase(SHF_WRITE)
- BCase(SHF_ALLOC)
- BCase(SHF_EXCLUDE)
- BCase(SHF_EXECINSTR)
- BCase(SHF_MERGE)
- BCase(SHF_STRINGS)
- BCase(SHF_INFO_LINK)
- BCase(SHF_LINK_ORDER)
- BCase(SHF_OS_NONCONFORMING)
- BCase(SHF_GROUP)
- BCase(SHF_TLS)
- switch(Object->Header.Machine) {
- case ELF::EM_AMDGPU:
- BCase(SHF_AMDGPU_HSA_GLOBAL)
- BCase(SHF_AMDGPU_HSA_READONLY)
- BCase(SHF_AMDGPU_HSA_CODE)
- BCase(SHF_AMDGPU_HSA_AGENT)
- break;
- default:
- // Nothing to do.
- break;
- }
-#undef BCase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
- IO &IO, ELFYAML::ELF_STT &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(STT_NOTYPE)
- ECase(STT_OBJECT)
- ECase(STT_FUNC)
- ECase(STT_SECTION)
- ECase(STT_FILE)
- ECase(STT_COMMON)
- ECase(STT_TLS)
- ECase(STT_GNU_IFUNC)
-#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 ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
- ELFYAML::ELF_STO &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
- switch (Object->Header.Machine) {
- case ELF::EM_MIPS:
- BCase(STO_MIPS_OPTIONAL)
- BCase(STO_MIPS_PLT)
- BCase(STO_MIPS_PIC)
- BCase(STO_MIPS_MICROMIPS)
- break;
- default:
- break; // Nothing to do
- }
-#undef BCase
-#undef BCaseMask
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
- IO &IO, ELFYAML::ELF_RSS &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(RSS_UNDEF)
- ECase(RSS_GP)
- ECase(RSS_GP0)
- ECase(RSS_LOC)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
- IO &IO, ELFYAML::ELF_REL &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
- switch (Object->Header.Machine) {
- case ELF::EM_X86_64:
-#include "llvm/Support/ELFRelocs/x86_64.def"
- break;
- case ELF::EM_MIPS:
-#include "llvm/Support/ELFRelocs/Mips.def"
- break;
- case ELF::EM_HEXAGON:
-#include "llvm/Support/ELFRelocs/Hexagon.def"
- break;
- case ELF::EM_386:
- case ELF::EM_IAMCU:
-#include "llvm/Support/ELFRelocs/i386.def"
- break;
- case ELF::EM_AARCH64:
-#include "llvm/Support/ELFRelocs/AArch64.def"
- break;
- case ELF::EM_ARM:
-#include "llvm/Support/ELFRelocs/ARM.def"
- break;
- default:
- llvm_unreachable("Unsupported architecture");
- }
-#undef ELF_RELOC
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
- IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
-#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X);
- ECase(REG_NONE)
- ECase(REG_32)
- ECase(REG_64)
- ECase(REG_128)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
- IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
-#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X);
- ECase(FP_ANY)
- ECase(FP_DOUBLE)
- ECase(FP_SINGLE)
- ECase(FP_SOFT)
- ECase(FP_OLD_64)
- ECase(FP_XX)
- ECase(FP_64)
- ECase(FP_64A)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
- IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
-#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X);
- ECase(EXT_NONE)
- ECase(EXT_XLR)
- ECase(EXT_OCTEON2)
- ECase(EXT_OCTEONP)
- ECase(EXT_LOONGSON_3A)
- ECase(EXT_OCTEON)
- ECase(EXT_5900)
- ECase(EXT_4650)
- ECase(EXT_4010)
- ECase(EXT_4100)
- ECase(EXT_3900)
- ECase(EXT_10000)
- ECase(EXT_SB1)
- ECase(EXT_4111)
- ECase(EXT_4120)
- ECase(EXT_5400)
- ECase(EXT_5500)
- ECase(EXT_LOONGSON_2E)
- ECase(EXT_LOONGSON_2F)
- ECase(EXT_OCTEON3)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
- IO &IO, ELFYAML::MIPS_ISA &Value) {
- IO.enumCase(Value, "MIPS1", 1);
- IO.enumCase(Value, "MIPS2", 2);
- IO.enumCase(Value, "MIPS3", 3);
- IO.enumCase(Value, "MIPS4", 4);
- IO.enumCase(Value, "MIPS5", 5);
- IO.enumCase(Value, "MIPS32", 32);
- IO.enumCase(Value, "MIPS64", 64);
-}
-
-void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
- IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
-#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X);
- BCase(DSP)
- BCase(DSPR2)
- BCase(EVA)
- BCase(MCU)
- BCase(MDMX)
- BCase(MIPS3D)
- BCase(MT)
- BCase(SMARTMIPS)
- BCase(VIRT)
- BCase(MSA)
- BCase(MIPS16)
- BCase(MICROMIPS)
- BCase(XPA)
-#undef BCase
-}
-
-void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
- IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
-#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X);
- BCase(ODDSPREG)
-#undef BCase
-}
-
-void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
- ELFYAML::FileHeader &FileHdr) {
- IO.mapRequired("Class", FileHdr.Class);
- IO.mapRequired("Data", FileHdr.Data);
- IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
- IO.mapRequired("Type", FileHdr.Type);
- IO.mapRequired("Machine", FileHdr.Machine);
- IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
- IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
-}
-
-namespace {
-struct NormalizedOther {
- NormalizedOther(IO &)
- : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {}
- NormalizedOther(IO &, uint8_t Original)
- : Visibility(Original & 0x3), Other(Original & ~0x3) {}
-
- uint8_t denormalize(IO &) { return Visibility | Other; }
-
- ELFYAML::ELF_STV Visibility;
- ELFYAML::ELF_STO Other;
-};
-}
-
-void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
- IO.mapOptional("Name", Symbol.Name, StringRef());
- IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
- IO.mapOptional("Section", Symbol.Section, StringRef());
- IO.mapOptional("Value", Symbol.Value, Hex64(0));
- IO.mapOptional("Size", Symbol.Size, Hex64(0));
-
- MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
- IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
- IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
-}
-
-void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
- IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
- IO.mapOptional("Local", Symbols.Local);
- IO.mapOptional("Global", Symbols.Global);
- IO.mapOptional("Weak", Symbols.Weak);
-}
-
-static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
- IO.mapOptional("Name", Section.Name, StringRef());
- IO.mapRequired("Type", Section.Type);
- IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
- IO.mapOptional("Address", Section.Address, Hex64(0));
- IO.mapOptional("Link", Section.Link, StringRef());
- IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
- IO.mapOptional("Info", Section.Info, StringRef());
-}
-
-static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size()));
-}
-
-static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Size", Section.Size, Hex64(0));
-}
-
-static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Relocations", Section.Relocations);
-}
-
-static void groupSectionMapping(IO &IO, ELFYAML::Group &group) {
- commonSectionMapping(IO, group);
- IO.mapRequired("Members", group.Members);
-}
-
-void MappingTraits<ELFYAML::SectionOrType>::mapping(
- IO &IO, ELFYAML::SectionOrType &sectionOrType) {
- IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
-}
-
-static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Version", Section.Version, Hex16(0));
- IO.mapRequired("ISA", Section.ISALevel);
- IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
- IO.mapOptional("ISAExtension", Section.ISAExtension,
- ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
- IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
- IO.mapOptional("FpABI", Section.FpABI,
- ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
- IO.mapOptional("GPRSize", Section.GPRSize,
- ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
- IO.mapOptional("CPR1Size", Section.CPR1Size,
- ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
- IO.mapOptional("CPR2Size", Section.CPR2Size,
- ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
- IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
- IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
-}
-
-void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
- IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
- ELFYAML::ELF_SHT sectionType;
- if (IO.outputting())
- sectionType = Section->Type;
- else
- IO.mapRequired("Type", sectionType);
-
- switch (sectionType) {
- case ELF::SHT_REL:
- case ELF::SHT_RELA:
- if (!IO.outputting())
- Section.reset(new ELFYAML::RelocationSection());
- sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
- break;
- case ELF::SHT_GROUP:
- if (!IO.outputting())
- Section.reset(new ELFYAML::Group());
- groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
- break;
- case ELF::SHT_NOBITS:
- if (!IO.outputting())
- Section.reset(new ELFYAML::NoBitsSection());
- sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
- break;
- case ELF::SHT_MIPS_ABIFLAGS:
- if (!IO.outputting())
- Section.reset(new ELFYAML::MipsABIFlags());
- sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
- break;
- default:
- if (!IO.outputting())
- Section.reset(new ELFYAML::RawContentSection());
- sectionMapping(IO, *cast<ELFYAML::RawContentSection>(Section.get()));
- }
-}
-
-StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
- IO &io, std::unique_ptr<ELFYAML::Section> &Section) {
- const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(Section.get());
- if (!RawSection || RawSection->Size >= RawSection->Content.binary_size())
- return StringRef();
- return "Section size must be greater or equal to the content size";
-}
-
-namespace {
-struct NormalizedMips64RelType {
- NormalizedMips64RelType(IO &)
- : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
- Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
- Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
- SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
- NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
- : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
- Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
-
- ELFYAML::ELF_REL denormalize(IO &) {
- ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
- return Res;
- }
-
- ELFYAML::ELF_REL Type;
- ELFYAML::ELF_REL Type2;
- ELFYAML::ELF_REL Type3;
- ELFYAML::ELF_RSS SpecSym;
-};
-}
-
-void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
- ELFYAML::Relocation &Rel) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-
- IO.mapRequired("Offset", Rel.Offset);
- IO.mapRequired("Symbol", Rel.Symbol);
-
- if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
- Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
- MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
- IO, Rel.Type);
- IO.mapRequired("Type", Key->Type);
- IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
- IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
- IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
- } else
- IO.mapRequired("Type", Rel.Type);
-
- IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
-}
-
-void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
- assert(!IO.getContext() && "The IO context is initialized already");
- IO.setContext(&Object);
- IO.mapRequired("FileHeader", Object.Header);
- IO.mapOptional("Sections", Object.Sections);
- IO.mapOptional("Symbols", Object.Symbols);
- IO.setContext(nullptr);
-}
-
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
-
-} // end namespace yaml
-} // end namespace llvm
diff --git a/lib/Object/Error.cpp b/lib/Object/Error.cpp
index 7ecc3a19af9d9..2357526b7894d 100644
--- a/lib/Object/Error.cpp
+++ b/lib/Object/Error.cpp
@@ -19,6 +19,9 @@ using namespace llvm;
using namespace object;
namespace {
+// FIXME: This class is only here to support the transition to llvm::Error. It
+// will be removed once this transition is complete. Clients should prefer to
+// deal with the Error value directly, rather than converting to error_code.
class _object_error_category : public std::error_category {
public:
const char* name() const LLVM_NOEXCEPT override;
@@ -47,21 +50,45 @@ std::string _object_error_category::message(int EV) const {
return "Invalid section index";
case object_error::bitcode_section_not_found:
return "Bitcode section not found in object file";
- case object_error::elf_invalid_dynamic_table_size:
- return "Invalid dynamic table size";
- case object_error::macho_small_load_command:
- return "Mach-O load command with size < 8 bytes";
- case object_error::macho_load_segment_too_many_sections:
- return "Mach-O segment load command contains too many sections";
- case object_error::macho_load_segment_too_small:
- return "Mach-O segment load command size is too small";
}
llvm_unreachable("An enumerator of object_error does not have a message "
"defined.");
}
+char BinaryError::ID = 0;
+char GenericBinaryError::ID = 0;
+
+GenericBinaryError::GenericBinaryError(Twine Msg) : Msg(Msg.str()) {}
+
+GenericBinaryError::GenericBinaryError(Twine Msg, object_error ECOverride)
+ : Msg(Msg.str()) {
+ setErrorCode(make_error_code(ECOverride));
+}
+
+void GenericBinaryError::log(raw_ostream &OS) const {
+ OS << Msg;
+}
+
static ManagedStatic<_object_error_category> error_category;
const std::error_category &object::object_category() {
return *error_category;
}
+
+llvm::Error llvm::object::isNotObjectErrorInvalidFileType(llvm::Error Err) {
+ if (auto Err2 =
+ handleErrors(std::move(Err),
+ [](std::unique_ptr<ECError> M) {
+ // Try to handle 'M'. If successful, return a success value from
+ // the handler.
+ if (M->convertToErrorCode() == object_error::invalid_file_type)
+ return Error::success();
+
+ // We failed to handle 'M' - return it from the handler.
+ // This value will be passed back from catchErrors and
+ // wind up in Err2, where it will be returned from this function.
+ return Error(std::move(M));
+ }))
+ return Err2;
+ return Err;
+}
diff --git a/lib/Object/FunctionIndexObjectFile.cpp b/lib/Object/FunctionIndexObjectFile.cpp
deleted file mode 100644
index fe111de1a9c87..0000000000000
--- a/lib/Object/FunctionIndexObjectFile.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Part of the FunctionIndexObjectFile class implementation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/FunctionIndexObjectFile.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/IR/FunctionInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-using namespace object;
-
-FunctionIndexObjectFile::FunctionIndexObjectFile(
- MemoryBufferRef Object, std::unique_ptr<FunctionInfoIndex> I)
- : SymbolicFile(Binary::ID_FunctionIndex, Object), Index(std::move(I)) {}
-
-FunctionIndexObjectFile::~FunctionIndexObjectFile() {}
-
-std::unique_ptr<FunctionInfoIndex> FunctionIndexObjectFile::takeIndex() {
- return std::move(Index);
-}
-
-ErrorOr<MemoryBufferRef>
-FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
- for (const SectionRef &Sec : Obj.sections()) {
- StringRef SecName;
- if (std::error_code EC = Sec.getName(SecName))
- return EC;
- if (SecName == ".llvmbc") {
- StringRef SecContents;
- if (std::error_code EC = Sec.getContents(SecContents))
- return EC;
- return MemoryBufferRef(SecContents, Obj.getFileName());
- }
- }
-
- return object_error::bitcode_section_not_found;
-}
-
-ErrorOr<MemoryBufferRef>
-FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
- sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
- switch (Type) {
- case sys::fs::file_magic::bitcode:
- return Object;
- case sys::fs::file_magic::elf_relocatable:
- case sys::fs::file_magic::macho_object:
- case sys::fs::file_magic::coff_object: {
- ErrorOr<std::unique_ptr<ObjectFile>> ObjFile =
- ObjectFile::createObjectFile(Object, Type);
- if (!ObjFile)
- return ObjFile.getError();
- return findBitcodeInObject(*ObjFile->get());
- }
- default:
- return object_error::invalid_file_type;
- }
-}
-
-// Looks for function index in the given memory buffer.
-// returns true if found, else false.
-bool FunctionIndexObjectFile::hasFunctionSummaryInMemBuffer(
- MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
- ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
- if (!BCOrErr)
- return false;
-
- return hasFunctionSummary(BCOrErr.get(), DiagnosticHandler);
-}
-
-// Parse function index in the given memory buffer.
-// Return new FunctionIndexObjectFile instance containing parsed
-// function summary/index.
-ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
-FunctionIndexObjectFile::create(MemoryBufferRef Object,
- DiagnosticHandlerFunction DiagnosticHandler,
- bool IsLazy) {
- std::unique_ptr<FunctionInfoIndex> Index;
-
- ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
- if (!BCOrErr)
- return BCOrErr.getError();
-
- ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr = getFunctionInfoIndex(
- BCOrErr.get(), DiagnosticHandler, IsLazy);
-
- if (std::error_code EC = IOrErr.getError())
- return EC;
-
- Index = std::move(IOrErr.get());
-
- return llvm::make_unique<FunctionIndexObjectFile>(Object, std::move(Index));
-}
-
-// Parse the function summary information for function with the
-// given name out of the given buffer. Parsed information is
-// stored on the index object saved in this object.
-std::error_code FunctionIndexObjectFile::findFunctionSummaryInMemBuffer(
- MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
- StringRef FunctionName) {
- sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
- switch (Type) {
- case sys::fs::file_magic::bitcode: {
- return readFunctionSummary(Object, DiagnosticHandler, FunctionName,
- std::move(Index));
- }
- default:
- return object_error::invalid_file_type;
- }
-}
-
-// Parse the function index out of an IR file and return the function
-// index object if found, or nullptr if not.
-ErrorOr<std::unique_ptr<FunctionInfoIndex>>
-llvm::getFunctionIndexForFile(StringRef Path,
- DiagnosticHandlerFunction DiagnosticHandler) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFileOrSTDIN(Path);
- std::error_code EC = FileOrErr.getError();
- if (EC)
- return EC;
- MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
- ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
- object::FunctionIndexObjectFile::create(BufferRef, DiagnosticHandler);
- EC = ObjOrErr.getError();
- if (EC)
- return EC;
-
- object::FunctionIndexObjectFile &Obj = **ObjOrErr;
- return Obj.takeIndex();
-}
diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp
index c35c413b3c3b4..42c8ecd62da82 100644
--- a/lib/Object/IRObjectFile.cpp
+++ b/lib/Object/IRObjectFile.cpp
@@ -24,9 +24,9 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
@@ -38,12 +38,20 @@ using namespace object;
IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
: SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
Mang.reset(new Mangler());
+ CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
+ [this](StringRef Name, BasicSymbolRef::Flags Flags) {
+ AsmSymbols.emplace_back(Name, std::move(Flags));
+ });
+}
- const std::string &InlineAsm = M->getModuleInlineAsm();
+// Parse inline ASM and collect the list of symbols that are not defined in
+// the current module. This is inspired from IRObjectFile.
+void IRObjectFile::CollectAsmUndefinedRefs(
+ const Triple &TT, StringRef InlineAsm,
+ function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs) {
if (InlineAsm.empty())
return;
- Triple TT(M->getTargetTriple());
std::string Err;
const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
if (!T)
@@ -68,7 +76,7 @@ IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
MCObjectFileInfo MOFI;
MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
- MOFI.InitMCObjectFileInfo(TT, Reloc::Default, CodeModel::Default, MCCtx);
+ MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx);
std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx));
T->createNullTargetStreamer(*Streamer);
@@ -105,9 +113,12 @@ IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
Res |= BasicSymbolRef::SF_Undefined;
Res |= BasicSymbolRef::SF_Global;
break;
+ case RecordStreamer::GlobalWeak:
+ Res |= BasicSymbolRef::SF_Weak;
+ Res |= BasicSymbolRef::SF_Global;
+ break;
}
- AsmSymbols.push_back(
- std::make_pair<std::string, uint32_t>(Key, std::move(Res)));
+ AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res));
}
}
@@ -231,13 +242,14 @@ uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
Res |= BasicSymbolRef::SF_Global;
if (GV->hasCommonLinkage())
Res |= BasicSymbolRef::SF_Common;
- if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage())
+ if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
+ GV->hasExternalWeakLinkage())
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"))
+ if (Var->getSection() == "llvm.metadata")
Res |= BasicSymbolRef::SF_FormatSpecific;
}
@@ -265,10 +277,7 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
for (const SectionRef &Sec : Obj.sections()) {
- StringRef SecName;
- if (std::error_code EC = Sec.getName(SecName))
- return EC;
- if (SecName == ".llvmbc") {
+ if (Sec.isBitcode()) {
StringRef SecContents;
if (std::error_code EC = Sec.getContents(SecContents))
return EC;
@@ -287,10 +296,10 @@ ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Ob
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::macho_object:
case sys::fs::file_magic::coff_object: {
- ErrorOr<std::unique_ptr<ObjectFile>> ObjFile =
+ Expected<std::unique_ptr<ObjectFile>> ObjFile =
ObjectFile::createObjectFile(Object, Type);
if (!ObjFile)
- return ObjFile.getError();
+ return errorToErrorCode(ObjFile.takeError());
return findBitcodeInObject(*ObjFile->get());
}
default:
@@ -305,8 +314,8 @@ llvm::object::IRObjectFile::create(MemoryBufferRef Object,
if (!BCOrErr)
return BCOrErr.getError();
- std::unique_ptr<MemoryBuffer> Buff(
- MemoryBuffer::getMemBuffer(BCOrErr.get(), false));
+ std::unique_ptr<MemoryBuffer> Buff =
+ MemoryBuffer::getMemBuffer(BCOrErr.get(), false);
ErrorOr<std::unique_ptr<Module>> MOrErr =
getLazyBitcodeModule(std::move(Buff), Context,
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index d1f79b225ee42..563236f95a5b8 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -38,6 +38,13 @@ namespace {
};
}
+static Error
+malformedError(Twine Msg) {
+ std::string StringMsg = "truncated or malformed object (" + Msg.str() + ")";
+ return make_error<GenericBinaryError>(std::move(StringMsg),
+ object_error::parse_failed);
+}
+
// FIXME: Replace all uses of this function with getStructOrErr.
template <typename T>
static T getStruct(const MachOObjectFile *O, const char *P) {
@@ -53,10 +60,10 @@ static T getStruct(const MachOObjectFile *O, const char *P) {
}
template <typename T>
-static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
+static Expected<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
// Don't read before the beginning or past the end of the file
if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
- return object_error::parse_failed;
+ return malformedError("Structure read out-of-range");
T Cmd;
memcpy(&Cmd, P, sizeof(T));
@@ -161,120 +168,180 @@ static uint32_t getSectionFlags(const MachOObjectFile *O,
return Sect.flags;
}
-static ErrorOr<MachOObjectFile::LoadCommandInfo>
-getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr) {
- auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr);
- if (!CmdOrErr)
- return CmdOrErr.getError();
- if (CmdOrErr->cmdsize < 8)
- return object_error::macho_small_load_command;
- MachOObjectFile::LoadCommandInfo Load;
- Load.Ptr = Ptr;
- Load.C = CmdOrErr.get();
- return Load;
+static Expected<MachOObjectFile::LoadCommandInfo>
+getLoadCommandInfo(const MachOObjectFile *Obj, const char *Ptr,
+ uint32_t LoadCommandIndex) {
+ if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
+ if (CmdOrErr->cmdsize < 8)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " with size less than 8 bytes");
+ return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr});
+ } else
+ return CmdOrErr.takeError();
}
-static ErrorOr<MachOObjectFile::LoadCommandInfo>
+static Expected<MachOObjectFile::LoadCommandInfo>
getFirstLoadCommandInfo(const MachOObjectFile *Obj) {
unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
: sizeof(MachO::mach_header);
- return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize));
+ if (sizeof(MachOObjectFile::LoadCommandInfo) > Obj->getHeader().sizeofcmds)
+ return malformedError("load command 0 extends past the end all load "
+ "commands in the file");
+ return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0);
}
-static ErrorOr<MachOObjectFile::LoadCommandInfo>
-getNextLoadCommandInfo(const MachOObjectFile *Obj,
+static Expected<MachOObjectFile::LoadCommandInfo>
+getNextLoadCommandInfo(const MachOObjectFile *Obj, uint32_t LoadCommandIndex,
const MachOObjectFile::LoadCommandInfo &L) {
- return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
+ unsigned HeaderSize = Obj->is64Bit() ? sizeof(MachO::mach_header_64)
+ : sizeof(MachO::mach_header);
+ if (L.Ptr + L.C.cmdsize + sizeof(MachOObjectFile::LoadCommandInfo) >
+ Obj->getData().data() + HeaderSize + Obj->getHeader().sizeofcmds)
+ return malformedError("load command " + Twine(LoadCommandIndex + 1) +
+ " extends past the end all load commands in the file");
+ return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);
}
template <typename T>
static void parseHeader(const MachOObjectFile *Obj, T &Header,
- std::error_code &EC) {
- auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0));
- if (HeaderOrErr)
- Header = HeaderOrErr.get();
+ Error &Err) {
+ if (sizeof(T) > Obj->getData().size()) {
+ Err = malformedError("the mach header extends past the end of the "
+ "file");
+ return;
+ }
+ if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0)))
+ Header = *HeaderOrErr;
else
- EC = HeaderOrErr.getError();
+ Err = HeaderOrErr.takeError();
}
// Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all
// sections to \param Sections, and optionally sets
// \param IsPageZeroSegment to true.
template <typename SegmentCmd>
-static std::error_code parseSegmentLoadCommand(
+static Error parseSegmentLoadCommand(
const MachOObjectFile *Obj, const MachOObjectFile::LoadCommandInfo &Load,
- SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment) {
+ SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment,
+ uint32_t LoadCommandIndex, const char *CmdName) {
const unsigned SegmentLoadSize = sizeof(SegmentCmd);
if (Load.C.cmdsize < SegmentLoadSize)
- return object_error::macho_load_segment_too_small;
- auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr);
- if (!SegOrErr)
- return SegOrErr.getError();
- SegmentCmd S = SegOrErr.get();
- const unsigned SectionSize =
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " " + CmdName + " cmdsize too small");
+ if (auto SegOrErr = getStructOrErr<SegmentCmd>(Obj, Load.Ptr)) {
+ SegmentCmd S = SegOrErr.get();
+ const unsigned SectionSize =
Obj->is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section);
- if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
- S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
- return object_error::macho_load_segment_too_many_sections;
- for (unsigned J = 0; J < S.nsects; ++J) {
- const char *Sec = getSectionPtr(Obj, Load, J);
- Sections.push_back(Sec);
- }
- IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
- return std::error_code();
+ if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize ||
+ S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " inconsistent cmdsize in " + CmdName +
+ " for the number of sections");
+ for (unsigned J = 0; J < S.nsects; ++J) {
+ const char *Sec = getSectionPtr(Obj, Load, J);
+ Sections.push_back(Sec);
+ }
+ IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname);
+ } else
+ return SegOrErr.takeError();
+
+ return Error::success();
+}
+
+Expected<std::unique_ptr<MachOObjectFile>>
+MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian,
+ bool Is64Bits) {
+ Error Err;
+ std::unique_ptr<MachOObjectFile> Obj(
+ new MachOObjectFile(std::move(Object), IsLittleEndian,
+ Is64Bits, Err));
+ if (Err)
+ return std::move(Err);
+ return std::move(Obj);
}
MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
- bool Is64bits, std::error_code &EC)
+ bool Is64bits, Error &Err)
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
HasPageZeroSegment(false) {
- if (is64Bit())
- parseHeader(this, Header64, EC);
- else
- parseHeader(this, Header, EC);
- if (EC)
+ ErrorAsOutParameter ErrAsOutParam(Err);
+ uint64_t BigSize;
+ if (is64Bit()) {
+ parseHeader(this, Header64, Err);
+ BigSize = sizeof(MachO::mach_header_64);
+ } else {
+ parseHeader(this, Header, Err);
+ BigSize = sizeof(MachO::mach_header);
+ }
+ if (Err)
return;
+ BigSize += getHeader().sizeofcmds;
+ if (getData().data() + BigSize > getData().end()) {
+ Err = malformedError("load commands extend past the end of the file");
+ return;
+ }
uint32_t LoadCommandCount = getHeader().ncmds;
if (LoadCommandCount == 0)
return;
- auto LoadOrErr = getFirstLoadCommandInfo(this);
- if (!LoadOrErr) {
- EC = LoadOrErr.getError();
+ LoadCommandInfo Load;
+ if (auto LoadOrErr = getFirstLoadCommandInfo(this))
+ Load = *LoadOrErr;
+ else {
+ Err = LoadOrErr.takeError();
return;
}
- LoadCommandInfo Load = LoadOrErr.get();
+
for (unsigned I = 0; I < LoadCommandCount; ++I) {
+ if (is64Bit()) {
+ if (Load.C.cmdsize % 8 != 0) {
+ // We have a hack here to allow 64-bit Mach-O core files to have
+ // LC_THREAD commands that are only a multiple of 4 and not 8 to be
+ // allowed since the macOS kernel produces them.
+ if (getHeader().filetype != MachO::MH_CORE ||
+ Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) {
+ Err = malformedError("load command " + Twine(I) + " cmdsize not a "
+ "multiple of 8");
+ return;
+ }
+ }
+ } else {
+ if (Load.C.cmdsize % 4 != 0) {
+ Err = malformedError("load command " + Twine(I) + " cmdsize not a "
+ "multiple of 4");
+ return;
+ }
+ }
LoadCommands.push_back(Load);
if (Load.C.cmd == MachO::LC_SYMTAB) {
// Multiple symbol tables
if (SymtabLoadCmd) {
- EC = object_error::parse_failed;
+ Err = malformedError("Multiple symbol tables");
return;
}
SymtabLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_DYSYMTAB) {
// Multiple dynamic symbol tables
if (DysymtabLoadCmd) {
- EC = object_error::parse_failed;
+ Err = malformedError("Multiple dynamic symbol tables");
return;
}
DysymtabLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) {
// Multiple data in code tables
if (DataInCodeLoadCmd) {
- EC = object_error::parse_failed;
+ Err = malformedError("Multiple data-in-code tables");
return;
}
DataInCodeLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
// Multiple linker optimization hint tables
if (LinkOptHintsLoadCmd) {
- EC = object_error::parse_failed;
+ Err = malformedError("Multiple linker optimization hint tables");
return;
}
LinkOptHintsLoadCmd = Load.Ptr;
@@ -282,24 +349,25 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
// Multiple dyldinfo load commands
if (DyldInfoLoadCmd) {
- EC = object_error::parse_failed;
+ Err = malformedError("Multiple dyldinfo load commands");
return;
}
DyldInfoLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_UUID) {
// Multiple UUID load commands
if (UuidLoadCmd) {
- EC = object_error::parse_failed;
+ Err = malformedError("Multiple UUID load commands");
return;
}
UuidLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
- if ((EC = parseSegmentLoadCommand<MachO::segment_command_64>(
- this, Load, Sections, HasPageZeroSegment)))
+ if ((Err = parseSegmentLoadCommand<MachO::segment_command_64>(
+ this, Load, Sections, HasPageZeroSegment, I,
+ "LC_SEGMENT_64")))
return;
} else if (Load.C.cmd == MachO::LC_SEGMENT) {
- if ((EC = parseSegmentLoadCommand<MachO::segment_command>(
- this, Load, Sections, HasPageZeroSegment)))
+ if ((Err = parseSegmentLoadCommand<MachO::segment_command>(
+ this, Load, Sections, HasPageZeroSegment, I, "LC_SEGMENT")))
return;
} else if (Load.C.cmd == MachO::LC_LOAD_DYLIB ||
Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
@@ -309,15 +377,66 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
Libraries.push_back(Load.Ptr);
}
if (I < LoadCommandCount - 1) {
- auto LoadOrErr = getNextLoadCommandInfo(this, Load);
- if (!LoadOrErr) {
- EC = LoadOrErr.getError();
+ if (auto LoadOrErr = getNextLoadCommandInfo(this, I, Load))
+ Load = *LoadOrErr;
+ else {
+ Err = LoadOrErr.takeError();
return;
}
- Load = LoadOrErr.get();
+ }
+ }
+ if (!SymtabLoadCmd) {
+ if (DysymtabLoadCmd) {
+ Err = malformedError("contains LC_DYSYMTAB load command without a "
+ "LC_SYMTAB load command");
+ return;
+ }
+ } else if (DysymtabLoadCmd) {
+ MachO::symtab_command Symtab =
+ getStruct<MachO::symtab_command>(this, SymtabLoadCmd);
+ MachO::dysymtab_command Dysymtab =
+ getStruct<MachO::dysymtab_command>(this, DysymtabLoadCmd);
+ if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
+ Err = malformedError("ilocalsym in LC_DYSYMTAB load command "
+ "extends past the end of the symbol table");
+ return;
+ }
+ uint64_t BigSize = Dysymtab.ilocalsym;
+ BigSize += Dysymtab.nlocalsym;
+ if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) {
+ Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load "
+ "command extends past the end of the symbol table");
+ return;
+ }
+ if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) {
+ Err = malformedError("nextdefsym in LC_DYSYMTAB load command "
+ "extends past the end of the symbol table");
+ return;
+ }
+ BigSize = Dysymtab.iextdefsym;
+ BigSize += Dysymtab.nextdefsym;
+ if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) {
+ Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB "
+ "load command extends past the end of the symbol "
+ "table");
+ return;
+ }
+ if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) {
+ Err = malformedError("nundefsym in LC_DYSYMTAB load command "
+ "extends past the end of the symbol table");
+ return;
+ }
+ BigSize = Dysymtab.iundefsym;
+ BigSize += Dysymtab.nundefsym;
+ if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) {
+ Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load "
+ " command extends past the end of the symbol table");
+ return;
}
}
assert(LoadCommands.size() == LoadCommandCount);
+
+ Err = Error::success();
}
void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
@@ -327,13 +446,14 @@ void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
Symb.p += SymbolTableEntrySize;
}
-ErrorOr<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
+Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const {
StringRef StringTable = getStringTableData();
MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
const char *Start = &StringTable.data()[Entry.n_strx];
- if (Start < getData().begin() || Start >= getData().end())
- report_fatal_error(
- "Symbol name entry points before beginning or past end of file.");
+ if (Start < getData().begin() || Start >= getData().end()) {
+ return malformedError("bad string index: " + Twine(Entry.n_strx) +
+ " for symbol at index " + Twine(getSymbolIndex(Symb)));
+ }
return StringRef(Start);
}
@@ -372,7 +492,7 @@ uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const {
return getNValue(Sym);
}
-ErrorOr<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
+Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const {
return getSymbolValue(Sym);
}
@@ -389,7 +509,8 @@ uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const {
return getNValue(DRI);
}
-SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
+Expected<SymbolRef::Type>
+MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
uint8_t n_type = Entry.n_type;
@@ -401,7 +522,10 @@ SymbolRef::Type MachOObjectFile::getSymbolType(DataRefImpl Symb) const {
case MachO::N_UNDF :
return SymbolRef::ST_Unknown;
case MachO::N_SECT :
- section_iterator Sec = *getSymbolSection(Symb);
+ Expected<section_iterator> SecOrError = getSymbolSection(Symb);
+ if (!SecOrError)
+ return SecOrError.takeError();
+ section_iterator Sec = *SecOrError;
if (Sec->isData() || Sec->isBSS())
return SymbolRef::ST_Data;
return SymbolRef::ST_Function;
@@ -448,7 +572,7 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
return Result;
}
-ErrorOr<section_iterator>
+Expected<section_iterator>
MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
MachO::nlist_base Entry = getSymbolTableEntryBase(this, Symb);
uint8_t index = Entry.n_sect;
@@ -457,8 +581,10 @@ MachOObjectFile::getSymbolSection(DataRefImpl Symb) const {
return section_end();
DataRefImpl DRI;
DRI.d.a = index - 1;
- if (DRI.d.a >= Sections.size())
- report_fatal_error("getSymbolSection: Invalid section index.");
+ if (DRI.d.a >= Sections.size()){
+ return malformedError("bad section index: " + Twine((int)index) +
+ " for symbol at index " + Twine(getSymbolIndex(Symb)));
+ }
return section_iterator(SectionRef(DRI, this));
}
@@ -546,6 +672,10 @@ uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
return uint64_t(1) << Align;
}
+bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
+ return false;
+}
+
bool MachOObjectFile::isSectionText(DataRefImpl Sec) const {
uint32_t Flags = getSectionFlags(this, Sec);
return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
@@ -576,6 +706,14 @@ bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const {
return false;
}
+bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const {
+ StringRef SegmentName = getSectionFinalSegmentName(Sec);
+ StringRef SectName;
+ if (!getSectionName(Sec, SectName))
+ return (SegmentName == "__LLVM" && SectName == "__bitcode");
+ return false;
+}
+
relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
DataRefImpl Ret;
Ret.d.a = Sec.d.a;
@@ -942,15 +1080,20 @@ MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const {
}
basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
+ DataRefImpl DRI;
+ MachO::symtab_command Symtab = getSymtabLoadCommand();
+ if (!SymtabLoadCmd || Symtab.nsyms == 0)
+ return basic_symbol_iterator(SymbolRef(DRI, this));
+
return getSymbolByIndex(0);
}
basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
DataRefImpl DRI;
- if (!SymtabLoadCmd)
+ MachO::symtab_command Symtab = getSymtabLoadCommand();
+ if (!SymtabLoadCmd || Symtab.nsyms == 0)
return basic_symbol_iterator(SymbolRef(DRI, this));
- MachO::symtab_command Symtab = getSymtabLoadCommand();
unsigned SymbolTableEntrySize = is64Bit() ?
sizeof(MachO::nlist_64) :
sizeof(MachO::nlist);
@@ -961,20 +1104,29 @@ basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
}
basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
- DataRefImpl DRI;
- if (!SymtabLoadCmd)
- return basic_symbol_iterator(SymbolRef(DRI, this));
-
MachO::symtab_command Symtab = getSymtabLoadCommand();
- if (Index >= Symtab.nsyms)
+ if (!SymtabLoadCmd || Index >= Symtab.nsyms)
report_fatal_error("Requested symbol index is out of range.");
unsigned SymbolTableEntrySize =
is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
+ DataRefImpl DRI;
DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
DRI.p += Index * SymbolTableEntrySize;
return basic_symbol_iterator(SymbolRef(DRI, this));
}
+uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const {
+ MachO::symtab_command Symtab = getSymtabLoadCommand();
+ if (!SymtabLoadCmd)
+ report_fatal_error("getSymbolIndex() called with no symbol table symbol");
+ unsigned SymbolTableEntrySize =
+ is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
+ DataRefImpl DRIstart;
+ DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
+ uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize;
+ return Index;
+}
+
section_iterator MachOObjectFile::section_begin() const {
DataRefImpl DRI;
return section_iterator(SectionRef(DRI, this));
@@ -1036,8 +1188,8 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) {
}
}
-Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault) {
+Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
+ const char **McpuDefault) {
if (McpuDefault)
*McpuDefault = nullptr;
@@ -1077,13 +1229,13 @@ Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
case MachO::CPU_SUBTYPE_ARM_V7EM:
if (McpuDefault)
*McpuDefault = "cortex-m4";
- return Triple("armv7em-apple-darwin");
+ return Triple("thumbv7em-apple-darwin");
case MachO::CPU_SUBTYPE_ARM_V7K:
return Triple("armv7k-apple-darwin");
case MachO::CPU_SUBTYPE_ARM_V7M:
if (McpuDefault)
*McpuDefault = "cortex-m3";
- return Triple("armv7m-apple-darwin");
+ return Triple("thumbv7m-apple-darwin");
case MachO::CPU_SUBTYPE_ARM_V7S:
return Triple("armv7s-apple-darwin");
default:
@@ -1115,56 +1267,6 @@ Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
}
}
-Triple MachOObjectFile::getThumbArch(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault) {
- if (McpuDefault)
- *McpuDefault = nullptr;
-
- switch (CPUType) {
- case MachO::CPU_TYPE_ARM:
- switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
- case MachO::CPU_SUBTYPE_ARM_V4T:
- return Triple("thumbv4t-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V5TEJ:
- return Triple("thumbv5e-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_XSCALE:
- return Triple("xscale-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V6:
- return Triple("thumbv6-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V6M:
- if (McpuDefault)
- *McpuDefault = "cortex-m0";
- return Triple("thumbv6m-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V7:
- return Triple("thumbv7-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V7EM:
- if (McpuDefault)
- *McpuDefault = "cortex-m4";
- return Triple("thumbv7em-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V7K:
- return Triple("thumbv7k-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V7M:
- if (McpuDefault)
- *McpuDefault = "cortex-m3";
- return Triple("thumbv7m-apple-darwin");
- case MachO::CPU_SUBTYPE_ARM_V7S:
- return Triple("thumbv7s-apple-darwin");
- default:
- return Triple();
- }
- default:
- return Triple();
- }
-}
-
-Triple MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault, Triple *ThumbTriple) {
- Triple T = MachOObjectFile::getArch(CPUType, CPUSubType, McpuDefault);
- *ThumbTriple = MachOObjectFile::getThumbArch(CPUType, CPUSubType,
- McpuDefault);
- return T;
-}
-
Triple MachOObjectFile::getHostArch() {
return Triple(sys::getDefaultTargetTriple());
}
@@ -1194,10 +1296,8 @@ unsigned MachOObjectFile::getArch() const {
return getArch(getCPUType(this));
}
-Triple MachOObjectFile::getArch(const char **McpuDefault,
- Triple *ThumbTriple) const {
- *ThumbTriple = getThumbArch(Header.cputype, Header.cpusubtype, McpuDefault);
- return getArch(Header.cputype, Header.cpusubtype, McpuDefault);
+Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const {
+ return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault);
}
relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const {
@@ -2307,23 +2407,17 @@ bool MachOObjectFile::isRelocatableObject() const {
return getHeader().filetype == MachO::MH_OBJECT;
}
-ErrorOr<std::unique_ptr<MachOObjectFile>>
+Expected<std::unique_ptr<MachOObjectFile>>
ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
StringRef Magic = Buffer.getBuffer().slice(0, 4);
- std::error_code EC;
- std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE")
- Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
- else if (Magic == "\xCE\xFA\xED\xFE")
- Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
- else if (Magic == "\xFE\xED\xFA\xCF")
- Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
- else if (Magic == "\xCF\xFA\xED\xFE")
- Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
- else
- return object_error::parse_failed;
-
- if (EC)
- return EC;
- return std::move(Ret);
+ return MachOObjectFile::create(Buffer, false, false);
+ if (Magic == "\xCE\xFA\xED\xFE")
+ return MachOObjectFile::create(Buffer, true, false);
+ if (Magic == "\xFE\xED\xFA\xCF")
+ return MachOObjectFile::create(Buffer, false, true);
+ if (Magic == "\xCF\xFA\xED\xFE")
+ return MachOObjectFile::create(Buffer, true, true);
+ return make_error<GenericBinaryError>("Unrecognized MachO magic number",
+ object_error::invalid_file_type);
}
diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp
index a1c83b9b7f86a..66c9151eb69cc 100644
--- a/lib/Object/MachOUniversal.cpp
+++ b/lib/Object/MachOUniversal.cpp
@@ -22,22 +22,11 @@
using namespace llvm;
using namespace object;
-template<typename T>
-static void SwapStruct(T &Value);
-
-template<>
-void SwapStruct(MachO::fat_header &H) {
- sys::swapByteOrder(H.magic);
- sys::swapByteOrder(H.nfat_arch);
-}
-
-template<>
-void SwapStruct(MachO::fat_arch &H) {
- sys::swapByteOrder(H.cputype);
- sys::swapByteOrder(H.cpusubtype);
- sys::swapByteOrder(H.offset);
- sys::swapByteOrder(H.size);
- sys::swapByteOrder(H.align);
+static Error
+malformedError(Twine Msg) {
+ std::string StringMsg = "truncated or malformed fat file (" + Msg.str() + ")";
+ return make_error<GenericBinaryError>(std::move(StringMsg),
+ object_error::parse_failed);
}
template<typename T>
@@ -46,7 +35,7 @@ static T getUniversalBinaryStruct(const char *Ptr) {
memcpy(&Res, Ptr, sizeof(T));
// Universal binary headers have big-endian byte order.
if (sys::IsLittleEndianHost)
- SwapStruct(Res);
+ swapStruct(Res);
return Res;
}
@@ -58,34 +47,53 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch(
} else {
// Parse object header.
StringRef ParentData = Parent->getData();
- const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
- Index * sizeof(MachO::fat_arch);
- Header = getUniversalBinaryStruct<MachO::fat_arch>(HeaderPos);
- if (ParentData.size() < Header.offset + Header.size) {
- clear();
+ if (Parent->getMagic() == MachO::FAT_MAGIC) {
+ const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
+ Index * sizeof(MachO::fat_arch);
+ Header = getUniversalBinaryStruct<MachO::fat_arch>(HeaderPos);
+ if (ParentData.size() < Header.offset + Header.size) {
+ clear();
+ }
+ } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
+ const char *HeaderPos = ParentData.begin() + sizeof(MachO::fat_header) +
+ Index * sizeof(MachO::fat_arch_64);
+ Header64 = getUniversalBinaryStruct<MachO::fat_arch_64>(HeaderPos);
+ if (ParentData.size() < Header64.offset + Header64.size) {
+ clear();
+ }
}
}
}
-ErrorOr<std::unique_ptr<MachOObjectFile>>
+Expected<std::unique_ptr<MachOObjectFile>>
MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
if (!Parent)
- return object_error::parse_failed;
+ report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsObjectFile() "
+ "called when Parent is a nullptr");
StringRef ParentData = Parent->getData();
- StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
+ StringRef ObjectData;
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ ObjectData = ParentData.substr(Header.offset, Header.size);
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ ObjectData = ParentData.substr(Header64.offset, Header64.size);
StringRef ObjectName = Parent->getFileName();
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
return ObjectFile::createMachOObjectFile(ObjBuffer);
}
-ErrorOr<std::unique_ptr<Archive>>
+Expected<std::unique_ptr<Archive>>
MachOUniversalBinary::ObjectForArch::getAsArchive() const {
if (!Parent)
- return object_error::parse_failed;
+ report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsArchive() "
+ "called when Parent is a nullptr");
StringRef ParentData = Parent->getData();
- StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
+ StringRef ObjectData;
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ ObjectData = ParentData.substr(Header.offset, Header.size);
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ ObjectData = ParentData.substr(Header64.offset, Header64.size);
StringRef ObjectName = Parent->getFileName();
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
return Archive::create(ObjBuffer);
@@ -93,44 +101,64 @@ MachOUniversalBinary::ObjectForArch::getAsArchive() const {
void MachOUniversalBinary::anchor() { }
-ErrorOr<std::unique_ptr<MachOUniversalBinary>>
+Expected<std::unique_ptr<MachOUniversalBinary>>
MachOUniversalBinary::create(MemoryBufferRef Source) {
- std::error_code EC;
+ Error Err;
std::unique_ptr<MachOUniversalBinary> Ret(
- new MachOUniversalBinary(Source, EC));
- if (EC)
- return EC;
+ new MachOUniversalBinary(Source, Err));
+ if (Err)
+ return std::move(Err);
return std::move(Ret);
}
-MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source,
- std::error_code &ec)
- : Binary(Binary::ID_MachOUniversalBinary, Source), NumberOfObjects(0) {
+MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, Error &Err)
+ : Binary(Binary::ID_MachOUniversalBinary, Source), Magic(0),
+ NumberOfObjects(0) {
+ ErrorAsOutParameter ErrAsOutParam(Err);
if (Data.getBufferSize() < sizeof(MachO::fat_header)) {
- ec = object_error::invalid_file_type;
+ Err = make_error<GenericBinaryError>("File too small to be a Mach-O "
+ "universal file",
+ object_error::invalid_file_type);
return;
}
// Check for magic value and sufficient header size.
StringRef Buf = getData();
- MachO::fat_header H= getUniversalBinaryStruct<MachO::fat_header>(Buf.begin());
+ MachO::fat_header H =
+ getUniversalBinaryStruct<MachO::fat_header>(Buf.begin());
+ Magic = H.magic;
NumberOfObjects = H.nfat_arch;
- uint32_t MinSize = sizeof(MachO::fat_header) +
- sizeof(MachO::fat_arch) * NumberOfObjects;
- if (H.magic != MachO::FAT_MAGIC || Buf.size() < MinSize) {
- ec = object_error::parse_failed;
+ uint32_t MinSize = sizeof(MachO::fat_header);
+ if (Magic == MachO::FAT_MAGIC)
+ MinSize += sizeof(MachO::fat_arch) * NumberOfObjects;
+ else if (Magic == MachO::FAT_MAGIC_64)
+ MinSize += sizeof(MachO::fat_arch_64) * NumberOfObjects;
+ else {
+ Err = malformedError("bad magic number");
+ return;
+ }
+ if (Buf.size() < MinSize) {
+ Err = malformedError("fat_arch" +
+ Twine(Magic == MachO::FAT_MAGIC ? "" : "_64") +
+ " structs would extend past the end of the file");
return;
}
- ec = std::error_code();
+ Err = Error::success();
}
-ErrorOr<std::unique_ptr<MachOObjectFile>>
+Expected<std::unique_ptr<MachOObjectFile>>
MachOUniversalBinary::getObjectForArch(StringRef ArchName) const {
if (Triple(ArchName).getArch() == Triple::ArchType::UnknownArch)
- return object_error::arch_not_found;
+ return make_error<GenericBinaryError>("Unknown architecture "
+ "named: " +
+ ArchName,
+ object_error::arch_not_found);
for (object_iterator I = begin_objects(), E = end_objects(); I != E; ++I) {
if (I->getArchTypeName() == ArchName)
return I->getAsObjectFile();
}
- return object_error::arch_not_found;
+ return make_error<GenericBinaryError>("fat file does not "
+ "contain " +
+ ArchName,
+ object_error::arch_not_found);
}
diff --git a/lib/Object/Makefile b/lib/Object/Makefile
deleted file mode 100644
index 79388dc97f1af..0000000000000
--- a/lib/Object/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Object/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMObject
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/lib/Object/ModuleSummaryIndexObjectFile.cpp b/lib/Object/ModuleSummaryIndexObjectFile.cpp
new file mode 100644
index 0000000000000..e6b1040d8f5dd
--- /dev/null
+++ b/lib/Object/ModuleSummaryIndexObjectFile.cpp
@@ -0,0 +1,126 @@
+//===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Part of the ModuleSummaryIndexObjectFile class implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+using namespace object;
+
+ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
+ MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
+ : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
+}
+
+ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
+
+std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
+ return std::move(Index);
+}
+
+ErrorOr<MemoryBufferRef>
+ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
+ for (const SectionRef &Sec : Obj.sections()) {
+ if (Sec.isBitcode()) {
+ StringRef SecContents;
+ if (std::error_code EC = Sec.getContents(SecContents))
+ return EC;
+ return MemoryBufferRef(SecContents, Obj.getFileName());
+ }
+ }
+
+ return object_error::bitcode_section_not_found;
+}
+
+ErrorOr<MemoryBufferRef>
+ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
+ sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
+ switch (Type) {
+ case sys::fs::file_magic::bitcode:
+ return Object;
+ case sys::fs::file_magic::elf_relocatable:
+ case sys::fs::file_magic::macho_object:
+ case sys::fs::file_magic::coff_object: {
+ Expected<std::unique_ptr<ObjectFile>> ObjFile =
+ ObjectFile::createObjectFile(Object, Type);
+ if (!ObjFile)
+ return errorToErrorCode(ObjFile.takeError());
+ return findBitcodeInObject(*ObjFile->get());
+ }
+ default:
+ return object_error::invalid_file_type;
+ }
+}
+
+// Looks for module summary index in the given memory buffer.
+// returns true if found, else false.
+bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
+ MemoryBufferRef Object,
+ const DiagnosticHandlerFunction &DiagnosticHandler) {
+ ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
+ if (!BCOrErr)
+ return false;
+
+ return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
+}
+
+// Parse module summary index in the given memory buffer.
+// Return new ModuleSummaryIndexObjectFile instance containing parsed
+// module summary/index.
+ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
+ModuleSummaryIndexObjectFile::create(
+ MemoryBufferRef Object,
+ const DiagnosticHandlerFunction &DiagnosticHandler) {
+ std::unique_ptr<ModuleSummaryIndex> Index;
+
+ ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
+ if (!BCOrErr)
+ return BCOrErr.getError();
+
+ ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
+ getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler);
+
+ if (std::error_code EC = IOrErr.getError())
+ return EC;
+
+ Index = std::move(IOrErr.get());
+
+ return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
+ std::move(Index));
+}
+
+// Parse the module summary index out of an IR file and return the summary
+// index object if found, or nullptr if not.
+ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
+ StringRef Path, const DiagnosticHandlerFunction &DiagnosticHandler) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFileOrSTDIN(Path);
+ std::error_code EC = FileOrErr.getError();
+ if (EC)
+ return EC;
+ MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
+ ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
+ object::ModuleSummaryIndexObjectFile::create(BufferRef,
+ DiagnosticHandler);
+ EC = ObjOrErr.getError();
+ if (EC)
+ return EC;
+
+ object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
+ return Obj.takeIndex();
+}
diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp
index b44c1a16fd084..6df481b060e10 100644
--- a/lib/Object/Object.cpp
+++ b/lib/Object/Object.cpp
@@ -61,11 +61,14 @@ wrap(const relocation_iterator *SI) {
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
- ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr(
+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
ObjectFile::createObjectFile(Buf->getMemBufferRef()));
std::unique_ptr<ObjectFile> Obj;
- if (!ObjOrErr)
+ if (!ObjOrErr) {
+ // TODO: Actually report errors helpfully.
+ consumeError(ObjOrErr.takeError());
return nullptr;
+ }
auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
return wrap(Ret);
@@ -98,9 +101,14 @@ void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
LLVMSymbolIteratorRef Sym) {
- ErrorOr<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
- if (std::error_code ec = SecOrErr.getError())
- report_fatal_error(ec.message());
+ Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
+ if (!SecOrErr) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(SecOrErr.takeError(), OS, "");
+ OS.flush();
+ report_fatal_error(Buf);
+ }
*unwrap(Sect) = *SecOrErr;
}
@@ -175,16 +183,26 @@ void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
// SymbolRef accessors
const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
- ErrorOr<StringRef> Ret = (*unwrap(SI))->getName();
- if (std::error_code EC = Ret.getError())
- report_fatal_error(EC.message());
+ Expected<StringRef> Ret = (*unwrap(SI))->getName();
+ if (!Ret) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(Ret.takeError(), OS, "");
+ OS.flush();
+ report_fatal_error(Buf);
+ }
return Ret->data();
}
uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
- ErrorOr<uint64_t> Ret = (*unwrap(SI))->getAddress();
- if (std::error_code EC = Ret.getError())
- report_fatal_error(EC.message());
+ Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
+ if (!Ret) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(Ret.takeError(), OS, "");
+ OS.flush();
+ report_fatal_error(Buf);
+ }
return *Ret;
}
diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp
index d12dc411361c8..92f9c1f4f0a0b 100644
--- a/lib/Object/ObjectFile.cpp
+++ b/lib/Object/ObjectFile.cpp
@@ -29,9 +29,12 @@ ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)
: SymbolicFile(Type, Source) {}
bool SectionRef::containsSymbol(SymbolRef S) const {
- ErrorOr<section_iterator> SymSec = S.getSection();
- if (!SymSec)
+ Expected<section_iterator> SymSec = S.getSection();
+ if (!SymSec) {
+ // TODO: Actually report errors helpfully.
+ consumeError(SymSec.takeError());
return false;
+ }
return *this == **SymSec;
}
@@ -46,20 +49,27 @@ uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const {
std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const {
- ErrorOr<StringRef> Name = getSymbolName(Symb);
- if (std::error_code EC = Name.getError())
- return EC;
+ Expected<StringRef> Name = getSymbolName(Symb);
+ if (!Name)
+ return errorToErrorCode(Name.takeError());
OS << *Name;
return std::error_code();
}
uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }
+bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
+ StringRef SectName;
+ if (!getSectionName(Sec, SectName))
+ return SectName == ".llvmbc";
+ return false;
+}
+
section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
return section_iterator(SectionRef(Sec, this));
}
-ErrorOr<std::unique_ptr<ObjectFile>>
+Expected<std::unique_ptr<ObjectFile>>
ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) {
StringRef Data = Object.getBuffer();
if (Type == sys::fs::file_magic::unknown)
@@ -71,13 +81,13 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) {
case sys::fs::file_magic::archive:
case sys::fs::file_magic::macho_universal_binary:
case sys::fs::file_magic::windows_resource:
- return object_error::invalid_file_type;
+ return errorCodeToError(object_error::invalid_file_type);
case sys::fs::file_magic::elf:
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
case sys::fs::file_magic::elf_core:
- return createELFObjectFile(Object);
+ return errorOrToExpected(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:
@@ -93,23 +103,23 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) {
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
- return createCOFFObjectFile(Object);
+ return errorOrToExpected(createCOFFObjectFile(Object));
}
llvm_unreachable("Unexpected Object File Type");
}
-ErrorOr<OwningBinary<ObjectFile>>
+Expected<OwningBinary<ObjectFile>>
ObjectFile::createObjectFile(StringRef ObjectPath) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFile(ObjectPath);
if (std::error_code EC = FileOrErr.getError())
- return EC;
+ return errorCodeToError(EC);
std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get());
- ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
createObjectFile(Buffer->getMemBufferRef());
- if (std::error_code EC = ObjOrErr.getError())
- return EC;
+ if (!ObjOrErr)
+ ObjOrErr.takeError();
std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));
diff --git a/lib/Object/RecordStreamer.cpp b/lib/Object/RecordStreamer.cpp
index 42dbd3e0c2d88..f03bd5e5fb9f4 100644
--- a/lib/Object/RecordStreamer.cpp
+++ b/lib/Object/RecordStreamer.cpp
@@ -23,21 +23,26 @@ void RecordStreamer::markDefined(const MCSymbol &Symbol) {
case Used:
S = Defined;
break;
+ case GlobalWeak:
+ break;
}
}
-void RecordStreamer::markGlobal(const MCSymbol &Symbol) {
+void RecordStreamer::markGlobal(const MCSymbol &Symbol,
+ MCSymbolAttr Attribute) {
State &S = Symbols[Symbol.getName()];
switch (S) {
case DefinedGlobal:
case Defined:
- S = DefinedGlobal;
+ S = (Attribute == MCSA_Weak) ? GlobalWeak : DefinedGlobal;
break;
case NeverSeen:
case Global:
case Used:
- S = Global;
+ S = (Attribute == MCSA_Weak) ? GlobalWeak : Global;
+ break;
+ case GlobalWeak:
break;
}
}
@@ -48,6 +53,7 @@ void RecordStreamer::markUsed(const MCSymbol &Symbol) {
case DefinedGlobal:
case Defined:
case Global:
+ case GlobalWeak:
break;
case NeverSeen:
@@ -84,8 +90,8 @@ void RecordStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
bool RecordStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
- if (Attribute == MCSA_Global)
- markGlobal(*Symbol);
+ if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
+ markGlobal(*Symbol, Attribute);
return true;
}
diff --git a/lib/Object/RecordStreamer.h b/lib/Object/RecordStreamer.h
index d8610610c332f..71337a60591bd 100644
--- a/lib/Object/RecordStreamer.h
+++ b/lib/Object/RecordStreamer.h
@@ -15,12 +15,12 @@
namespace llvm {
class RecordStreamer : public MCStreamer {
public:
- enum State { NeverSeen, Global, Defined, DefinedGlobal, Used };
+ enum State { NeverSeen, Global, GlobalWeak, Defined, DefinedGlobal, Used };
private:
StringMap<State> Symbols;
void markDefined(const MCSymbol &Symbol);
- void markGlobal(const MCSymbol &Symbol);
+ void markGlobal(const MCSymbol &Symbol, MCSymbolAttr Attribute);
void markUsed(const MCSymbol &Symbol);
void visitUsedSymbol(const MCSymbol &Sym) override;
diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp
index bf79dfb8da62e..1e8e31b6b22d9 100644
--- a/lib/Object/SymbolicFile.cpp
+++ b/lib/Object/SymbolicFile.cpp
@@ -26,7 +26,7 @@ SymbolicFile::SymbolicFile(unsigned int Type, MemoryBufferRef Source)
SymbolicFile::~SymbolicFile() {}
-ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
+Expected<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context) {
StringRef Data = Object.getBuffer();
if (Type == sys::fs::file_magic::unknown)
@@ -35,13 +35,13 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
switch (Type) {
case sys::fs::file_magic::bitcode:
if (Context)
- return IRObjectFile::create(Object, *Context);
+ return errorOrToExpected(IRObjectFile::create(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:
- return object_error::invalid_file_type;
+ return errorCodeToError(object_error::invalid_file_type);
case sys::fs::file_magic::elf:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
@@ -63,7 +63,7 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::macho_object:
case sys::fs::file_magic::coff_object: {
- ErrorOr<std::unique_ptr<ObjectFile>> Obj =
+ Expected<std::unique_ptr<ObjectFile>> Obj =
ObjectFile::createObjectFile(Object, Type);
if (!Obj || !Context)
return std::move(Obj);
@@ -73,9 +73,9 @@ ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
if (!BCData)
return std::move(Obj);
- return IRObjectFile::create(
- MemoryBufferRef(BCData->getBuffer(), Object.getBufferIdentifier()),
- *Context);
+ return errorOrToExpected(IRObjectFile::create(
+ MemoryBufferRef(BCData->getBuffer(),
+ Object.getBufferIdentifier()), *Context));
}
}
llvm_unreachable("Unexpected Binary File Type");