mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +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:
parent
4642e9d1a6
commit
6e0594e553
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
BIN
test/Object/Inputs/macho-invalid-fat.obj.elf-x86_64
Normal file
BIN
test/Object/Inputs/macho-invalid-fat.obj.elf-x86_64
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user