1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00

Finish cleaning up most of the error handling in libObject’s MachOUniversalBinary

and its clients to use the new llvm::Error model for error handling.

Changed getAsArchive() from ErrorOr<...> to Expected<...> so now all
interfaces there use the new llvm::Error model for return values.

In the two places it had if (!Parent) this is actually a program error so changed
from returning errorCodeToError(object_error::parse_failed) to calling
report_fatal_error() with a message.

In getObjectForArch() added error messages to its two llvm::Error return values
instead of returning errorCodeToError(object_error::arch_not_found) with no
error message.

For the llvm-obdump, llvm-nm and llvm-size clients since the only binary files in
Mach-O Universal Binaries that are supported are Mach-O files or archives with
Mach-O objects, updated their logic to generate an error when a slice contains
something like an ELF binary instead of ignoring it. And added a test case for
that.

The last error stuff to be cleaned up for libObject’s MachOUniversalBinary is
the use of errorOrToExpected(Archive::create(ObjBuffer)) which needs
Archive::create() to be changed from ErrorOr<...> to Expected<...> first,
which I’ll work on next. 

llvm-svn: 274079
This commit is contained in:
Kevin Enderby 2016-06-28 23:16:13 +00:00
parent 4642e9d1a6
commit 6e0594e553
10 changed files with 90 additions and 18 deletions

View File

@ -19,7 +19,6 @@
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
namespace llvm {
@ -105,7 +104,7 @@ public:
Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
ErrorOr<std::unique_ptr<Archive>> getAsArchive() const;
Expected<std::unique_ptr<Archive>> getAsArchive() const;
};
class object_iterator {

View File

@ -68,7 +68,8 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch(
Expected<std::unique_ptr<MachOObjectFile>>
MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
if (!Parent)
return errorCodeToError(object_error::parse_failed);
report_fatal_error("MachOUniversalBinary::ObjectForArch::getAsObjectFile() "
"called when Parent is a nullptr");
StringRef ParentData = Parent->getData();
StringRef ObjectData;
@ -81,10 +82,11 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
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;
@ -94,7 +96,7 @@ MachOUniversalBinary::ObjectForArch::getAsArchive() const {
ObjectData = ParentData.substr(Header64.offset, Header64.size);
StringRef ObjectName = Parent->getFileName();
MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
return Archive::create(ObjBuffer);
return errorOrToExpected(Archive::create(ObjBuffer));
}
void MachOUniversalBinary::anchor() { }
@ -145,11 +147,15 @@ MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, Error &Err)
Expected<std::unique_ptr<MachOObjectFile>>
MachOUniversalBinary::getObjectForArch(StringRef ArchName) const {
if (Triple(ArchName).getArch() == Triple::ArchType::UnknownArch)
return errorCodeToError(object_error::arch_not_found);
return make_error<GenericBinaryError>(std::move("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 errorCodeToError(object_error::arch_not_found);
return make_error<GenericBinaryError>(std::move("fat file does not "
"contain " + ArchName),
object_error::arch_not_found);
}

Binary file not shown.

View File

@ -97,3 +97,6 @@ INCOMPLETE-SEGMENT-LOADC-FAT-ARCHIVE: macho-universal-archive-bad2.x86_64.i386(m
RUN: not llvm-objdump -macho -universal-headers %p/Inputs/macho-invalid-fat 2>&1 | FileCheck -check-prefix INVALID-FAT %s
INVALID-FAT: truncated or malformed fat file (fat_arch_64 structs would extend past the end of the file)
RUN: not llvm-objdump -macho -private-headers -arch all %p/Inputs/macho-invalid-fat.obj.elf-x86_64 2>&1 | FileCheck -check-prefix INVALID-FAT-ELF %s
INVALID-FAT-ELF: Mach-O universal file: {{.*}}/macho-invalid-fat.obj.elf-x86_64 for architecture x86_64 is not a Mach-O file or an archive file

View File

@ -1171,7 +1171,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
error(std::move(E), Filename, ArchFlags.size() > 1 ?
StringRef(I->getArchTypeName()) : StringRef());
continue;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(),
@ -1209,6 +1209,12 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
ArchitectureName);
}
}
} else {
consumeError(AOrErr.takeError());
error(Filename + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file",
"Mach-O universal file");
}
}
}
@ -1238,7 +1244,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
ObjOrErr.takeError())) {
error(std::move(E), Filename);
return;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(),
@ -1266,6 +1272,12 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
dumpSymbolNamesFromObject(*O, false, ArchiveName);
}
}
} else {
consumeError(AOrErr.takeError());
error(Filename + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file",
"Mach-O universal file");
}
return;
}
@ -1301,7 +1313,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
error(std::move(E), Filename, moreThanOneArch ?
StringRef(I->getArchTypeName()) : StringRef());
continue;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
@ -1336,6 +1349,12 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName);
}
}
} else {
consumeError(AOrErr.takeError());
error(Filename + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file",
"Mach-O universal file");
}
}
return;

View File

@ -1621,7 +1621,7 @@ void llvm::ParseInputMachO(StringRef Filename) {
report_error(Filename, StringRef(), std::move(E),
ArchitectureName);
continue;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
outs() << "Archive : " << Filename;
@ -1646,6 +1646,11 @@ void llvm::ParseInputMachO(StringRef Filename) {
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
}
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + Filename + " for " +
"architecture " + StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file");
}
}
}
@ -1676,7 +1681,7 @@ void llvm::ParseInputMachO(StringRef Filename) {
ObjOrErr.takeError())) {
report_error(Filename, std::move(E));
continue;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
outs() << "Archive : " << Filename << "\n";
@ -1698,6 +1703,11 @@ void llvm::ParseInputMachO(StringRef Filename) {
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
ProcessMachO(Filename, O, O->getFileName());
}
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + Filename + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file");
}
return;
}
@ -1721,7 +1731,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
ObjOrErr.takeError())) {
report_error(StringRef(), Filename, std::move(E), ArchitectureName);
continue;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
outs() << "Archive : " << Filename;
if (!ArchitectureName.empty())
@ -1747,6 +1758,11 @@ void llvm::ParseInputMachO(StringRef Filename) {
ArchitectureName);
}
}
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + Filename + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file");
}
}
return;

View File

@ -264,6 +264,12 @@ void llvm::error(std::error_code EC) {
exit(1);
}
LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
errs() << ToolName << ": " << Message << ".\n";
errs().flush();
exit(1);
}
LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
std::error_code EC) {
assert(EC);

View File

@ -88,6 +88,7 @@ void PrintSectionHeaders(const object::ObjectFile *o);
void PrintSectionContents(const object::ObjectFile *o);
void PrintSymbolTable(const object::ObjectFile *o, StringRef ArchiveName,
StringRef ArchitectureName = StringRef());
LLVM_ATTRIBUTE_NORETURN void error(Twine Message);
LLVM_ATTRIBUTE_NORETURN void report_error(StringRef File, std::error_code EC);
LLVM_ATTRIBUTE_NORETURN void report_error(StringRef File, llvm::Error E);
LLVM_ATTRIBUTE_NORETURN void report_error(StringRef FileName,

View File

@ -459,7 +459,7 @@ static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) {
OS.flush();
reportError(UBinary->getFileName(), Buf);
}
else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
dumpArchive(&*AOrErr.get());
}
}

View File

@ -99,6 +99,13 @@ static bool error(std::error_code ec) {
return true;
}
static bool error(Twine Message) {
HadError = true;
errs() << ToolName << ": " << Message << ".\n";
errs().flush();
return true;
}
// This version of error() prints the archive name and member name, for example:
// "libx.a(foo.o)" after the ToolName before the error message. It sets
// HadError but returns allowing the code to move on to other archive members.
@ -585,7 +592,7 @@ static void printFileSectionSizes(StringRef file) {
error(std::move(E), file, ArchFlags.size() > 1 ?
StringRef(I->getArchTypeName()) : StringRef());
return;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its
@ -630,6 +637,11 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + file + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file");
}
}
}
@ -671,7 +683,7 @@ static void printFileSectionSizes(StringRef file) {
} else if (auto E = isNotObjectErrorInvalidFileType(UO.takeError())) {
error(std::move(E), file);
return;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its
@ -709,6 +721,11 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + file + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file");
}
return;
}
@ -744,7 +761,7 @@ static void printFileSectionSizes(StringRef file) {
error(std::move(E), file, MoreThanOneArch ?
StringRef(I->getArchTypeName()) : StringRef());
return;
} else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its sizes.
@ -781,6 +798,11 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + file + " for architecture " +
StringRef(I->getArchTypeName()) +
" is not a Mach-O file or an archive file");
}
}
} else if (ObjectFile *o = dyn_cast<ObjectFile>(&Bin)) {