mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
Convert the Archive API to use ErrorOr.
Now that we have c++11, even things like ErrorOr<std::unique_ptr<...>> are easy to use. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211033 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d492c19894
commit
0659928fec
@ -72,7 +72,7 @@ public:
|
||||
|
||||
Child getNext() const;
|
||||
|
||||
std::error_code getName(StringRef &Result) const;
|
||||
ErrorOr<StringRef> getName() const;
|
||||
StringRef getRawName() const { return getHeader()->getName(); }
|
||||
sys::TimeValue getLastModified() const {
|
||||
return getHeader()->getLastModified();
|
||||
@ -89,11 +89,11 @@ public:
|
||||
return StringRef(Data.data() + StartOfFile, getSize());
|
||||
}
|
||||
|
||||
std::error_code getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
|
||||
bool FullPath = false) const;
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||
getMemoryBuffer(bool FullPath = false) const;
|
||||
|
||||
std::error_code getAsBinary(std::unique_ptr<Binary> &Result,
|
||||
LLVMContext *Context = nullptr) const;
|
||||
ErrorOr<std::unique_ptr<Binary>>
|
||||
getAsBinary(LLVMContext *Context = nullptr) const;
|
||||
};
|
||||
|
||||
class child_iterator {
|
||||
@ -137,8 +137,8 @@ public:
|
||||
: Parent(p)
|
||||
, SymbolIndex(symi)
|
||||
, StringIndex(stri) {}
|
||||
std::error_code getName(StringRef &Result) const;
|
||||
std::error_code getMember(child_iterator &Result) const;
|
||||
StringRef getName() const;
|
||||
ErrorOr<child_iterator> getMember() const;
|
||||
Symbol getNext() const;
|
||||
};
|
||||
|
||||
|
@ -305,9 +305,13 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
|
||||
// Look for our symbols in each Archive
|
||||
object::Archive::child_iterator ChildIt = A->findSym(Name);
|
||||
if (ChildIt != A->child_end()) {
|
||||
std::unique_ptr<object::Binary> ChildBin;
|
||||
// FIXME: Support nested archives?
|
||||
if (!ChildIt->getAsBinary(ChildBin) && ChildBin->isObject()) {
|
||||
ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
|
||||
ChildIt->getAsBinary();
|
||||
if (ChildBinOrErr.getError())
|
||||
continue;
|
||||
std::unique_ptr<object::Binary> ChildBin = std::move(ChildBinOrErr.get());
|
||||
if (ChildBin->isObject()) {
|
||||
std::unique_ptr<object::ObjectFile> OF(
|
||||
static_cast<object::ObjectFile *>(ChildBin.release()));
|
||||
// This causes the object file to be loaded.
|
||||
|
@ -115,18 +115,14 @@ Archive::Child Archive::Child::getNext() const {
|
||||
return Child(Parent, NextLoc);
|
||||
}
|
||||
|
||||
std::error_code Archive::Child::getName(StringRef &Result) const {
|
||||
ErrorOr<StringRef> Archive::Child::getName() const {
|
||||
StringRef name = getRawName();
|
||||
// Check if it's a special name.
|
||||
if (name[0] == '/') {
|
||||
if (name.size() == 1) { // Linker member.
|
||||
Result = name;
|
||||
return object_error::success;
|
||||
}
|
||||
if (name.size() == 2 && name[1] == '/') { // String table.
|
||||
Result = name;
|
||||
return object_error::success;
|
||||
}
|
||||
if (name.size() == 1) // Linker member.
|
||||
return name;
|
||||
if (name.size() == 2 && name[1] == '/') // String table.
|
||||
return name;
|
||||
// It's a long name.
|
||||
// Get the offset.
|
||||
std::size_t offset;
|
||||
@ -147,53 +143,45 @@ std::error_code Archive::Child::getName(StringRef &Result) const {
|
||||
// GNU long file names end with a /.
|
||||
if (Parent->kind() == K_GNU) {
|
||||
StringRef::size_type End = StringRef(addr).find('/');
|
||||
Result = StringRef(addr, End);
|
||||
} else {
|
||||
Result = addr;
|
||||
return StringRef(addr, End);
|
||||
}
|
||||
return object_error::success;
|
||||
return StringRef(addr);
|
||||
} else if (name.startswith("#1/")) {
|
||||
uint64_t name_size;
|
||||
if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
|
||||
llvm_unreachable("Long name length is not an ingeter");
|
||||
Result = Data.substr(sizeof(ArchiveMemberHeader), name_size)
|
||||
return Data.substr(sizeof(ArchiveMemberHeader), name_size)
|
||||
.rtrim(StringRef("\0", 1));
|
||||
return object_error::success;
|
||||
}
|
||||
// It's a simple name.
|
||||
if (name[name.size() - 1] == '/')
|
||||
Result = name.substr(0, name.size() - 1);
|
||||
else
|
||||
Result = name;
|
||||
return object_error::success;
|
||||
return name.substr(0, name.size() - 1);
|
||||
return name;
|
||||
}
|
||||
|
||||
std::error_code
|
||||
Archive::Child::getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
|
||||
bool FullPath) const {
|
||||
StringRef Name;
|
||||
if (std::error_code ec = getName(Name))
|
||||
return ec;
|
||||
SmallString<128> Path;
|
||||
Result.reset(MemoryBuffer::getMemBuffer(
|
||||
getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name + ")")
|
||||
.toStringRef(Path)
|
||||
: Name,
|
||||
false));
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code Archive::Child::getAsBinary(std::unique_ptr<Binary> &Result,
|
||||
LLVMContext *Context) const {
|
||||
std::unique_ptr<Binary> ret;
|
||||
std::unique_ptr<MemoryBuffer> Buff;
|
||||
if (std::error_code ec = getMemoryBuffer(Buff))
|
||||
return ec;
|
||||
ErrorOr<Binary *> BinaryOrErr = createBinary(Buff.release(), Context);
|
||||
if (std::error_code EC = BinaryOrErr.getError())
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>>
|
||||
Archive::Child::getMemoryBuffer(bool FullPath) const {
|
||||
ErrorOr<StringRef> NameOrErr = getName();
|
||||
if (std::error_code EC = NameOrErr.getError())
|
||||
return EC;
|
||||
Result.reset(BinaryOrErr.get());
|
||||
return object_error::success;
|
||||
StringRef Name = NameOrErr.get();
|
||||
SmallString<128> Path;
|
||||
std::unique_ptr<MemoryBuffer> Ret(MemoryBuffer::getMemBuffer(
|
||||
getBuffer(),
|
||||
FullPath
|
||||
? (Twine(Parent->getFileName()) + "(" + Name + ")").toStringRef(Path)
|
||||
: Name,
|
||||
false));
|
||||
return std::move(Ret);
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<Binary>>
|
||||
Archive::Child::getAsBinary(LLVMContext *Context) const {
|
||||
std::unique_ptr<Binary> ret;
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = getMemoryBuffer();
|
||||
if (std::error_code EC = BuffOrErr.getError())
|
||||
return EC;
|
||||
return createBinary(BuffOrErr.get().release(), Context);
|
||||
}
|
||||
|
||||
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
|
||||
@ -256,9 +244,11 @@ Archive::Archive(MemoryBuffer *source, std::error_code &ec)
|
||||
if (Name.startswith("#1/")) {
|
||||
Format = K_BSD;
|
||||
// We know this is BSD, so getName will work since there is no string table.
|
||||
ec = i->getName(Name);
|
||||
ErrorOr<StringRef> NameOrErr = i->getName();
|
||||
ec = NameOrErr.getError();
|
||||
if (ec)
|
||||
return;
|
||||
Name = NameOrErr.get();
|
||||
if (Name == "__.SYMDEF SORTED") {
|
||||
SymbolTable = i;
|
||||
++i;
|
||||
@ -336,12 +326,11 @@ Archive::child_iterator Archive::child_end() const {
|
||||
return Child(this, nullptr);
|
||||
}
|
||||
|
||||
std::error_code Archive::Symbol::getName(StringRef &Result) const {
|
||||
Result = StringRef(Parent->SymbolTable->getBuffer().begin() + StringIndex);
|
||||
return object_error::success;
|
||||
StringRef Archive::Symbol::getName() const {
|
||||
return Parent->SymbolTable->getBuffer().begin() + StringIndex;
|
||||
}
|
||||
|
||||
std::error_code Archive::Symbol::getMember(child_iterator &Result) const {
|
||||
ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const {
|
||||
const char *Buf = Parent->SymbolTable->getBuffer().begin();
|
||||
const char *Offsets = Buf + 4;
|
||||
uint32_t Offset = 0;
|
||||
@ -381,9 +370,8 @@ std::error_code Archive::Symbol::getMember(child_iterator &Result) const {
|
||||
}
|
||||
|
||||
const char *Loc = Parent->getData().begin() + Offset;
|
||||
Result = Child(Parent, Loc);
|
||||
|
||||
return object_error::success;
|
||||
child_iterator Iter(Child(Parent, Loc));
|
||||
return Iter;
|
||||
}
|
||||
|
||||
Archive::Symbol Archive::Symbol::getNext() const {
|
||||
@ -441,16 +429,15 @@ Archive::symbol_iterator Archive::symbol_end() const {
|
||||
Archive::child_iterator Archive::findSym(StringRef name) const {
|
||||
Archive::symbol_iterator bs = symbol_begin();
|
||||
Archive::symbol_iterator es = symbol_end();
|
||||
Archive::child_iterator result;
|
||||
|
||||
StringRef symname;
|
||||
|
||||
for (; bs != es; ++bs) {
|
||||
if (bs->getName(symname))
|
||||
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();
|
||||
if (symname == name) {
|
||||
if (bs->getMember(result))
|
||||
return child_end();
|
||||
return result;
|
||||
return ResultOrErr.get();
|
||||
}
|
||||
}
|
||||
return child_end();
|
||||
|
@ -369,8 +369,9 @@ static void performReadOperation(ArchiveOperation Operation,
|
||||
for (object::Archive::child_iterator I = OldArchive->child_begin(),
|
||||
E = OldArchive->child_end();
|
||||
I != E; ++I) {
|
||||
StringRef Name;
|
||||
failIfError(I->getName(Name));
|
||||
ErrorOr<StringRef> NameOrErr = I->getName();
|
||||
failIfError(NameOrErr.getError());
|
||||
StringRef Name = NameOrErr.get();
|
||||
|
||||
if (!Members.empty() &&
|
||||
std::find(Members.begin(), Members.end(), Name) == Members.end())
|
||||
@ -544,8 +545,9 @@ computeNewArchiveMembers(ArchiveOperation Operation,
|
||||
E = OldArchive->child_end();
|
||||
I != E; ++I) {
|
||||
int Pos = Ret.size();
|
||||
StringRef Name;
|
||||
failIfError(I->getName(Name));
|
||||
ErrorOr<StringRef> NameOrErr = I->getName();
|
||||
failIfError(NameOrErr.getError());
|
||||
StringRef Name = NameOrErr.get();
|
||||
if (Name == PosName) {
|
||||
assert(AddAfter || AddBefore);
|
||||
if (AddBefore)
|
||||
@ -783,7 +785,10 @@ static void performWriteOperation(ArchiveOperation Operation,
|
||||
|
||||
} else {
|
||||
object::Archive::child_iterator OldMember = Member.getOld();
|
||||
failIfError(OldMember->getMemoryBuffer(MemberBuffer));
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
|
||||
OldMember->getMemoryBuffer();
|
||||
failIfError(MemberBufferOrErr.getError());
|
||||
MemberBuffer = std::move(MemberBufferOrErr.get());
|
||||
}
|
||||
MemberBuffers[I] = MemberBuffer.release();
|
||||
}
|
||||
|
@ -733,16 +733,14 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
|
||||
if (I != E) {
|
||||
outs() << "Archive map\n";
|
||||
for (; I != E; ++I) {
|
||||
Archive::child_iterator C;
|
||||
StringRef SymName;
|
||||
StringRef FileName;
|
||||
if (error(I->getMember(C)))
|
||||
ErrorOr<Archive::child_iterator> C = I->getMember();
|
||||
if (error(C.getError()))
|
||||
return;
|
||||
if (error(I->getName(SymName)))
|
||||
ErrorOr<StringRef> FileNameOrErr = C.get()->getName();
|
||||
if (error(FileNameOrErr.getError()))
|
||||
return;
|
||||
if (error(C->getName(FileName)))
|
||||
return;
|
||||
outs() << SymName << " in " << FileName << "\n";
|
||||
StringRef SymName = I->getName();
|
||||
outs() << SymName << " in " << FileNameOrErr.get() << "\n";
|
||||
}
|
||||
outs() << "\n";
|
||||
}
|
||||
@ -750,10 +748,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
|
||||
|
||||
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
|
||||
I != E; ++I) {
|
||||
std::unique_ptr<Binary> Child;
|
||||
if (I->getAsBinary(Child, &Context))
|
||||
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context);
|
||||
if (ChildOrErr.getError())
|
||||
continue;
|
||||
if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
|
||||
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
|
||||
outs() << O->getFileName() << ":\n";
|
||||
dumpSymbolNamesFromObject(O);
|
||||
}
|
||||
@ -773,10 +771,11 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
|
||||
else if (!I->getAsArchive(A)) {
|
||||
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
|
||||
AI != AE; ++AI) {
|
||||
std::unique_ptr<Binary> Child;
|
||||
if (AI->getAsBinary(Child, &Context))
|
||||
ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
|
||||
AI->getAsBinary(&Context);
|
||||
if (ChildOrErr.getError())
|
||||
continue;
|
||||
if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
|
||||
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
|
||||
outs() << A->getFileName() << ":";
|
||||
outs() << O->getFileName() << ":\n";
|
||||
dumpSymbolNamesFromObject(O);
|
||||
|
@ -850,15 +850,15 @@ static void DumpObject(const ObjectFile *o) {
|
||||
static void DumpArchive(const Archive *a) {
|
||||
for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e;
|
||||
++i) {
|
||||
std::unique_ptr<Binary> child;
|
||||
if (std::error_code EC = i->getAsBinary(child)) {
|
||||
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
|
||||
if (std::error_code EC = ChildOrErr.getError()) {
|
||||
// Ignore non-object files.
|
||||
if (EC != object_error::invalid_file_type)
|
||||
errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message()
|
||||
<< ".\n";
|
||||
continue;
|
||||
}
|
||||
if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
|
||||
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
|
||||
DumpObject(o);
|
||||
else
|
||||
errs() << ToolName << ": '" << a->getFileName() << "': "
|
||||
|
@ -242,15 +242,15 @@ static void dumpArchive(const Archive *Arc) {
|
||||
for (Archive::child_iterator ArcI = Arc->child_begin(),
|
||||
ArcE = Arc->child_end();
|
||||
ArcI != ArcE; ++ArcI) {
|
||||
std::unique_ptr<Binary> child;
|
||||
if (std::error_code EC = ArcI->getAsBinary(child)) {
|
||||
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = ArcI->getAsBinary();
|
||||
if (std::error_code EC = ChildOrErr.getError()) {
|
||||
// Ignore non-object files.
|
||||
if (EC != object_error::invalid_file_type)
|
||||
reportError(Arc->getFileName(), EC.message());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ObjectFile *Obj = dyn_cast<ObjectFile>(child.get()))
|
||||
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
|
||||
dumpObject(Obj);
|
||||
else
|
||||
reportError(Arc->getFileName(), readobj_error::unrecognized_file_format);
|
||||
|
@ -245,12 +245,12 @@ static void PrintFileSectionSizes(StringRef file) {
|
||||
// This is an archive. Iterate over each member and display its sizes.
|
||||
for (object::Archive::child_iterator i = a->child_begin(),
|
||||
e = a->child_end(); i != e; ++i) {
|
||||
std::unique_ptr<Binary> child;
|
||||
if (std::error_code ec = i->getAsBinary(child)) {
|
||||
errs() << ToolName << ": " << file << ": " << ec.message() << ".\n";
|
||||
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
|
||||
if (std::error_code EC = ChildOrErr.getError()) {
|
||||
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
|
||||
continue;
|
||||
}
|
||||
if (ObjectFile *o = dyn_cast<ObjectFile>(child.get())) {
|
||||
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
|
||||
if (OutputFormat == sysv)
|
||||
outs() << o->getFileName() << " (ex " << a->getFileName()
|
||||
<< "):\n";
|
||||
|
Loading…
Reference in New Issue
Block a user