diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index f5bcaf6ccc6..bbc33383f4c 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -63,7 +63,7 @@ public: return T.getArchName(); } - ErrorOr> getAsObjectFile() const; + Expected> getAsObjectFile() const; ErrorOr> getAsArchive() const; }; @@ -110,7 +110,7 @@ public: return V->isMachOUniversalBinary(); } - ErrorOr> + Expected> getObjectForArch(StringRef ArchName) const; }; diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp index dbb17a82fd6..9c12169fb67 100644 --- a/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -319,9 +319,10 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, return EC; return I->second->get(); } - ErrorOr> ObjOrErr = + Expected> ObjOrErr = UB->getObjectForArch(ArchName); - if (auto EC = ObjOrErr.getError()) { + if (!ObjOrErr) { + auto EC = errorToErrorCode(ObjOrErr.takeError()); ObjectForUBPathAndArch.insert( std::make_pair(std::make_pair(Path, ArchName), EC)); return EC; diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp index df25f7416b3..2d0ddd93f0b 100644 --- a/lib/Object/MachOUniversal.cpp +++ b/lib/Object/MachOUniversal.cpp @@ -67,16 +67,16 @@ MachOUniversalBinary::ObjectForArch::ObjectForArch( } } -ErrorOr> +Expected> MachOUniversalBinary::ObjectForArch::getAsObjectFile() const { if (!Parent) - return object_error::parse_failed; + return errorCodeToError(object_error::parse_failed); StringRef ParentData = Parent->getData(); StringRef ObjectData = ParentData.substr(Header.offset, Header.size); StringRef ObjectName = Parent->getFileName(); MemoryBufferRef ObjBuffer(ObjectData, ObjectName); - return expectedToErrorOr(ObjectFile::createMachOObjectFile(ObjBuffer)); + return ObjectFile::createMachOObjectFile(ObjBuffer); } ErrorOr> @@ -123,14 +123,14 @@ MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, ec = std::error_code(); } -ErrorOr> +Expected> MachOUniversalBinary::getObjectForArch(StringRef ArchName) const { if (Triple(ArchName).getArch() == Triple::ArchType::UnknownArch) - return object_error::arch_not_found; + return errorCodeToError(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 errorCodeToError(object_error::arch_not_found); } diff --git a/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/lib/ProfileData/Coverage/CoverageMappingReader.cpp index 72a9702f42a..c4d41b999b8 100644 --- a/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -597,8 +597,8 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer, // If we have a universal binary, try to look up the object for the // appropriate architecture. auto ObjectFileOrErr = Universal->getObjectForArch(Arch); - if (auto EC = ObjectFileOrErr.getError()) - return errorCodeToError(EC); + if (!ObjectFileOrErr) + return ObjectFileOrErr.takeError(); OF = std::move(ObjectFileOrErr.get()); } else if (isa(Bin.get())) { // For any other object file, upcast and take ownership. diff --git a/test/Object/Inputs/macho-universal-archive-bad1.x86_64.i386 b/test/Object/Inputs/macho-universal-archive-bad1.x86_64.i386 new file mode 100644 index 00000000000..30ab297b090 Binary files /dev/null and b/test/Object/Inputs/macho-universal-archive-bad1.x86_64.i386 differ diff --git a/test/Object/Inputs/macho-universal-archive-bad2.x86_64.i386 b/test/Object/Inputs/macho-universal-archive-bad2.x86_64.i386 new file mode 100644 index 00000000000..763dbbc01ca Binary files /dev/null and b/test/Object/Inputs/macho-universal-archive-bad2.x86_64.i386 differ diff --git a/test/Object/Inputs/macho-universal-bad1.x86_64.i386 b/test/Object/Inputs/macho-universal-bad1.x86_64.i386 new file mode 100644 index 00000000000..7fe21dc324a Binary files /dev/null and b/test/Object/Inputs/macho-universal-bad1.x86_64.i386 differ diff --git a/test/Object/Inputs/macho-universal-bad2.x86_64.i386 b/test/Object/Inputs/macho-universal-bad2.x86_64.i386 new file mode 100644 index 00000000000..ec83c38fe60 Binary files /dev/null and b/test/Object/Inputs/macho-universal-bad2.x86_64.i386 differ diff --git a/test/Object/macho-invalid.test b/test/Object/macho-invalid.test index 55d9d25ab72..3fe6296645b 100644 --- a/test/Object/macho-invalid.test +++ b/test/Object/macho-invalid.test @@ -60,6 +60,13 @@ RUN: not llvm-objdump -t %p/Inputs/macho-bad-archive1.a 2>&1 \ RUN: | FileCheck -check-prefix NAME-PAST-EOF-ARCHIVE %s NAME-PAST-EOF-ARCHIVE: macho-bad-archive1.a(macho-invalid-symbol-name-past-eof) truncated or malformed object (bad string index: 4261412866 for symbol at index 0) +RUN: not llvm-objdump -macho -arch all -t %p/Inputs/macho-universal-bad1.x86_64.i386 2>&1 \ +RUN: | FileCheck -check-prefix NAME-PAST-EOF-FAT %s +NAME-PAST-EOF-FAT: macho-universal-bad1.x86_64.i386 (for architecture x86_64) truncated or malformed object (bad string index: 4261412866 for symbol at index 0) +RUN: not llvm-objdump -macho -arch all -t %p/Inputs/macho-universal-archive-bad1.x86_64.i386 2>&1 \ +RUN: | FileCheck -check-prefix NAME-PAST-EOF-FAT-ARCHIVE %s +NAME-PAST-EOF-FAT-ARCHIVE: macho-universal-archive-bad1.x86_64.i386(macho-invalid-symbol-name-past-eof) (for architecture x86_64) truncated or malformed object (bad string index: 4261412866 for symbol at index 0) + RUN: llvm-nm %p/Inputs/macho-invalid-section-index-getSectionRawName 2>&1 \ RUN: | FileCheck -check-prefix INVALID-SECTION-IDX-SYMBOL-SEC %s INVALID-SECTION-IDX-SYMBOL-SEC: 0000000100000000 S __mh_execute_header @@ -81,3 +88,9 @@ INCOMPLETE-SEGMENT-LOADC: truncated or malformed object (load commands extend pa RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho-bad-archive2.a 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC-ARCHIVE %s INCOMPLETE-SEGMENT-LOADC-ARCHIVE: macho-bad-archive2.a(macho64-invalid-incomplete-segment-load-command) truncated or malformed object (load commands extend past the end of the file) + +RUN: not llvm-objdump -macho -private-headers -arch all %p/Inputs/macho-universal-bad2.x86_64.i386 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC-FAT %s +INCOMPLETE-SEGMENT-LOADC-FAT: macho-universal-bad2.x86_64.i386 (for architecture x86_64) truncated or malformed object (load commands extend past the end of the file) + +RUN: not llvm-objdump -macho -private-headers -arch all %p/Inputs/macho-universal-archive-bad2.x86_64.i386 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC-FAT-ARCHIVE %s +INCOMPLETE-SEGMENT-LOADC-FAT-ARCHIVE: macho-universal-archive-bad2.x86_64.i386(macho64-invalid-incomplete-segment-load-command) (for architecture x86_64) truncated or malformed object (load commands extend past the end of the file) diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index fb6c7f4ffe8..b0facfb294d 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -105,7 +105,7 @@ static void DumpInput(StringRef Filename) { else if (auto *Fat = dyn_cast(BinOrErr->get())) for (auto &ObjForArch : Fat->objects()) { auto MachOOrErr = ObjForArch.getAsObjectFile(); - error(Filename, MachOOrErr.getError()); + error(Filename, errorToErrorCode(MachOOrErr.takeError())); DumpObjectFile(**MachOOrErr, Filename + " (" + ObjForArch.getArchTypeName() + ")"); } diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index a9234229062..d838ad870ba 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -193,7 +193,8 @@ static bool error(std::error_code EC, Twine Path = Twine()) { // 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. -static void error(llvm::Error E, StringRef FileName, const Archive::Child &C) { +static void error(llvm::Error E, StringRef FileName, const Archive::Child &C, + StringRef ArchitectureName = StringRef()) { HadError = true; errs() << ToolName << ": " << FileName; @@ -206,6 +207,28 @@ static void error(llvm::Error E, StringRef FileName, const Archive::Child &C) { else errs() << "(" << NameOrErr.get() << ")"; + if (!ArchitectureName.empty()) + errs() << " (for architecture " << ArchitectureName << ") "; + + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(E), OS, ""); + OS.flush(); + errs() << " " << Buf << "\n"; +} + +// This version of error() prints the file name and which architecture slice it +// is from, for example: "foo.o (for architecture i386)" after the ToolName +// before the error message. It sets HadError but returns allowing the code to +// move on to other architecture slices. +static void error(llvm::Error E, StringRef FileName, + StringRef ArchitectureName = StringRef()) { + HadError = true; + errs() << ToolName << ": " << FileName; + + if (!ArchitectureName.empty()) + errs() << " (for architecture " << ArchitectureName << ") "; + std::string Buf; raw_string_ostream OS(Buf); logAllUnhandledErrors(std::move(E), OS, ""); @@ -1123,7 +1146,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { I != E; ++I) { if (ArchFlags[i] == I->getArchTypeName()) { ArchFound = true; - ErrorOr> ObjOrErr = + Expected> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; std::string ArchitectureName; @@ -1141,6 +1164,11 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { } dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); + } else if (auto E = isNotObjectErrorInvalidFileType( + ObjOrErr.takeError())) { + error(std::move(E), Filename, ArchFlags.size() > 1 ? + StringRef(I->getArchTypeName()) : StringRef()); + continue; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; @@ -1154,8 +1182,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { C.getAsBinary(&Context); if (!ChildOrErr) { if (auto E = isNotObjectErrorInvalidFileType( - ChildOrErr.takeError())) - error(std::move(E), Filename, C); + ChildOrErr.takeError())) { + error(std::move(E), Filename, C, ArchFlags.size() > 1 ? + StringRef(I->getArchTypeName()) : StringRef()); + } continue; } if (SymbolicFile *O = @@ -1196,12 +1226,16 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { E = UB->end_objects(); I != E; ++I) { if (HostArchName == I->getArchTypeName()) { - ErrorOr> ObjOrErr = I->getAsObjectFile(); + Expected> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; ArchiveName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); dumpSymbolNamesFromObject(Obj, false); + } else if (auto E = isNotObjectErrorInvalidFileType( + ObjOrErr.takeError())) { + error(std::move(E), Filename); + return; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; @@ -1241,7 +1275,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { - ErrorOr> ObjOrErr = I->getAsObjectFile(); + Expected> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; std::string ArchitectureName; ArchiveName.clear(); @@ -1260,6 +1294,11 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { outs() << ":\n"; } dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); + } else if (auto E = isNotObjectErrorInvalidFileType( + ObjOrErr.takeError())) { + error(std::move(E), Filename, moreThanOneArch ? + StringRef(I->getArchTypeName()) : StringRef()); + continue; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); @@ -1267,11 +1306,13 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { if (error(AI->getError())) return; auto &C = AI->get(); - Expected> ChildOrErr = C.getAsBinary(&Context); + Expected> ChildOrErr = + C.getAsBinary(&Context); if (!ChildOrErr) { if (auto E = isNotObjectErrorInvalidFileType( ChildOrErr.takeError())) - error(std::move(E), Filename, C); + error(std::move(E), Filename, C, moreThanOneArch ? + StringRef(ArchitectureName) : StringRef()); continue; } if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) { diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b97cdca9d6a..fe7cf0dd335 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -1266,7 +1266,7 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, PrintDylibs(MachOOF, true); if (SymbolTable) { StringRef ArchiveName = ArchiveMemberName == StringRef() ? "" : Filename; - PrintSymbolTable(MachOOF, ArchiveName); + PrintSymbolTable(MachOOF, ArchiveName, ArchitectureName); } if (UnwindInfo) printMachOUnwindInfo(MachOOF); @@ -1604,7 +1604,7 @@ void llvm::ParseInputMachO(StringRef Filename) { I != E; ++I) { if (ArchFlags[i] == I->getArchTypeName()) { ArchFound = true; - ErrorOr> ObjOrErr = + Expected> ObjOrErr = I->getAsObjectFile(); std::string ArchitectureName = ""; if (ArchFlags.size() > 1) @@ -1613,6 +1613,11 @@ void llvm::ParseInputMachO(StringRef Filename) { ObjectFile &O = *ObjOrErr.get(); if (MachOObjectFile *MachOOF = dyn_cast(&O)) ProcessMachO(Filename, MachOOF, "", ArchitectureName); + } else if (auto E = isNotObjectErrorInvalidFileType( + ObjOrErr.takeError())) { + report_error(Filename, StringRef(), std::move(E), + ArchitectureName); + continue; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; @@ -1631,7 +1636,7 @@ void llvm::ParseInputMachO(StringRef Filename) { Expected> ChildOrErr = C.getAsBinary(); if (!ChildOrErr) { if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) - report_error(Filename, C, std::move(E)); + report_error(Filename, C, std::move(E), ArchitectureName); continue; } if (MachOObjectFile *O = @@ -1657,13 +1662,17 @@ void llvm::ParseInputMachO(StringRef Filename) { I != E; ++I) { if (MachOObjectFile::getHostArch().getArchName() == I->getArchTypeName()) { - ErrorOr> ObjOrErr = I->getAsObjectFile(); + Expected> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; ArchiveName.clear(); if (ObjOrErr) { ObjectFile &O = *ObjOrErr.get(); if (MachOObjectFile *MachOOF = dyn_cast(&O)) ProcessMachO(Filename, MachOOF); + } else if (auto E = isNotObjectErrorInvalidFileType( + ObjOrErr.takeError())) { + report_error(Filename, std::move(E)); + continue; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; @@ -1697,7 +1706,7 @@ void llvm::ParseInputMachO(StringRef Filename) { for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { - ErrorOr> ObjOrErr = I->getAsObjectFile(); + Expected> ObjOrErr = I->getAsObjectFile(); std::string ArchitectureName = ""; if (moreThanOneArch) ArchitectureName = I->getArchTypeName(); @@ -1705,6 +1714,10 @@ void llvm::ParseInputMachO(StringRef Filename) { ObjectFile &Obj = *ObjOrErr.get(); if (MachOObjectFile *MachOOF = dyn_cast(&Obj)) ProcessMachO(Filename, MachOOF, "", ArchitectureName); + } else if (auto E = isNotObjectErrorInvalidFileType( + ObjOrErr.takeError())) { + report_error(StringRef(), Filename, std::move(E), ArchitectureName); + continue; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; outs() << "Archive : " << Filename; @@ -1721,7 +1734,7 @@ void llvm::ParseInputMachO(StringRef Filename) { Expected> ChildOrErr = C.getAsBinary(); if (!ChildOrErr) { if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) - report_error(Filename, C, std::move(E)); + report_error(Filename, C, std::move(E), ArchitectureName); continue; } if (MachOObjectFile *O = diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 3089ff75303..2ee34e48e41 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -284,13 +284,16 @@ LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File, LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName, StringRef FileName, - llvm::Error E) { + llvm::Error E, + StringRef ArchitectureName) { assert(E); errs() << ToolName << ": "; if (ArchiveName != "") errs() << ArchiveName << "(" << FileName << ")"; else errs() << FileName; + if (!ArchitectureName.empty()) + errs() << " (for architecture " << ArchitectureName << ")"; std::string Buf; raw_string_ostream OS(Buf); logAllUnhandledErrors(std::move(E), OS, ""); @@ -301,15 +304,17 @@ LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName, LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName, const object::Archive::Child &C, - llvm::Error E) { + llvm::Error E, + StringRef ArchitectureName) { ErrorOr NameOrErr = C.getName(); // TODO: if we have a error getting the name then it would be nice to print // the index of which archive member this is and or its offset in the // archive instead of "???" as the name. if (NameOrErr.getError()) - llvm::report_error(ArchiveName, "???", std::move(E)); + llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName); else - llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E)); + llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E), + ArchitectureName); } static const Target *getTarget(const ObjectFile *Obj = nullptr) { @@ -1377,7 +1382,8 @@ void llvm::PrintSectionContents(const ObjectFile *Obj) { } } -void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName) { +void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName, + StringRef ArchitectureName) { outs() << "SYMBOL TABLE:\n"; if (const COFFObjectFile *coff = dyn_cast(o)) { @@ -1402,7 +1408,8 @@ void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName) { } else { Expected NameOrErr = Symbol.getName(); if (!NameOrErr) - report_error(ArchiveName, o->getFileName(), NameOrErr.takeError()); + report_error(ArchiveName, o->getFileName(), NameOrErr.takeError(), + ArchitectureName); Name = *NameOrErr; } diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 51a600d9a04..439018963cb 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -86,15 +86,20 @@ void printRawClangAST(const object::ObjectFile *o); void PrintRelocations(const object::ObjectFile *o); void PrintSectionHeaders(const object::ObjectFile *o); void PrintSectionContents(const object::ObjectFile *o); -void PrintSymbolTable(const object::ObjectFile *o, StringRef ArchiveName); +void PrintSymbolTable(const object::ObjectFile *o, StringRef ArchiveName, + StringRef ArchitectureName = StringRef()); 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, StringRef ArchiveName, - llvm::Error E); + llvm::Error E, + StringRef ArchitectureName + = StringRef()); LLVM_ATTRIBUTE_NORETURN void report_error(StringRef ArchiveName, const object::Archive::Child &C, - llvm::Error E); + llvm::Error E, + StringRef ArchitectureName + = StringRef()); } // end namespace llvm diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 1181a67dbcb..386b32b6cc7 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -442,13 +442,18 @@ static void dumpArchive(const Archive *Arc) { /// @brief Dumps each object file in \a MachO Universal Binary; static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) { for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) { - ErrorOr> ObjOrErr = Obj.getAsObjectFile(); + Expected> ObjOrErr = Obj.getAsObjectFile(); if (ObjOrErr) dumpObject(&*ObjOrErr.get()); + else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(ObjOrErr.takeError(), OS, ""); + OS.flush(); + reportError(UBinary->getFileName(), Buf); + } else if (ErrorOr> AOrErr = Obj.getAsArchive()) dumpArchive(&*AOrErr.get()); - else - reportError(UBinary->getFileName(), ObjOrErr.getError().message()); } } diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp index 351a6b1bfbd..48370136e8a 100644 --- a/tools/llvm-size/llvm-size.cpp +++ b/tools/llvm-size/llvm-size.cpp @@ -102,7 +102,8 @@ static bool error(std::error_code ec) { // 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. -static void error(llvm::Error E, StringRef FileName, const Archive::Child &C) { +static void error(llvm::Error E, StringRef FileName, const Archive::Child &C, + StringRef ArchitectureName = StringRef()) { HadError = true; errs() << ToolName << ": " << FileName; @@ -115,6 +116,27 @@ static void error(llvm::Error E, StringRef FileName, const Archive::Child &C) { else errs() << "(" << NameOrErr.get() << ")"; + if (!ArchitectureName.empty()) + errs() << " (for architecture " << ArchitectureName << ") "; + + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(E), OS, ""); + OS.flush(); + errs() << " " << Buf << "\n"; +} + +// This version of error() prints the file name and which architecture slice it // is from, for example: "foo.o (for architecture i386)" after the ToolName +// before the error message. It sets HadError but returns allowing the code to +// move on to other architecture slices. +static void error(llvm::Error E, StringRef FileName, + StringRef ArchitectureName = StringRef()) { + HadError = true; + errs() << ToolName << ": " << FileName; + + if (!ArchitectureName.empty()) + errs() << " (for architecture " << ArchitectureName << ") "; + std::string Buf; raw_string_ostream OS(Buf); logAllUnhandledErrors(std::move(E), OS, ""); @@ -539,7 +561,7 @@ static void printFileSectionSizes(StringRef file) { I != E; ++I) { if (ArchFlags[i] == I->getArchTypeName()) { ArchFound = true; - ErrorOr> UO = I->getAsObjectFile(); + Expected> UO = I->getAsObjectFile(); if (UO) { if (ObjectFile *o = dyn_cast(&*UO.get())) { MachOObjectFile *MachO = dyn_cast(o); @@ -558,6 +580,11 @@ static void printFileSectionSizes(StringRef file) { outs() << "\n"; } } + } else if (auto E = isNotObjectErrorInvalidFileType( + UO.takeError())) { + error(std::move(E), file, ArchFlags.size() > 1 ? + StringRef(I->getArchTypeName()) : StringRef()); + return; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &UA = *AOrErr; @@ -571,8 +598,11 @@ static void printFileSectionSizes(StringRef file) { Expected> ChildOrErr = i->get().getAsBinary(); if (!ChildOrErr) { - if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) - error(std::move(E), a->getFileName(), i->get()); + if (auto E = isNotObjectErrorInvalidFileType( + ChildOrErr.takeError())) + error(std::move(E), UA->getFileName(), i->get(), + ArchFlags.size() > 1 ? + StringRef(I->getArchTypeName()) : StringRef()); continue; } if (ObjectFile *o = dyn_cast(&*ChildOrErr.get())) { @@ -619,7 +649,7 @@ static void printFileSectionSizes(StringRef file) { E = UB->end_objects(); I != E; ++I) { if (HostArchName == I->getArchTypeName()) { - ErrorOr> UO = I->getAsObjectFile(); + Expected> UO = I->getAsObjectFile(); if (UO) { if (ObjectFile *o = dyn_cast(&*UO.get())) { MachOObjectFile *MachO = dyn_cast(o); @@ -638,6 +668,9 @@ static void printFileSectionSizes(StringRef file) { outs() << "\n"; } } + } else if (auto E = isNotObjectErrorInvalidFileType(UO.takeError())) { + error(std::move(E), file); + return; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &UA = *AOrErr; @@ -651,8 +684,9 @@ static void printFileSectionSizes(StringRef file) { Expected> ChildOrErr = i->get().getAsBinary(); if (!ChildOrErr) { - if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) - error(std::move(E), a->getFileName(), i->get()); + if (auto E = isNotObjectErrorInvalidFileType( + ChildOrErr.takeError())) + error(std::move(E), UA->getFileName(), i->get()); continue; } if (ObjectFile *o = dyn_cast(&*ChildOrErr.get())) { @@ -686,7 +720,7 @@ static void printFileSectionSizes(StringRef file) { for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { - ErrorOr> UO = I->getAsObjectFile(); + Expected> UO = I->getAsObjectFile(); if (UO) { if (ObjectFile *o = dyn_cast(&*UO.get())) { MachOObjectFile *MachO = dyn_cast(o); @@ -706,6 +740,10 @@ static void printFileSectionSizes(StringRef file) { outs() << "\n"; } } + } else if (auto E = isNotObjectErrorInvalidFileType(UO.takeError())) { + error(std::move(E), file, MoreThanOneArch ? + StringRef(I->getArchTypeName()) : StringRef()); + return; } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &UA = *AOrErr; @@ -717,8 +755,10 @@ static void printFileSectionSizes(StringRef file) { exit(1); Expected> ChildOrErr = i->get().getAsBinary(); if (!ChildOrErr) { - if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) - error(std::move(E), UA->getFileName(), i->get()); + if (auto E = isNotObjectErrorInvalidFileType( + ChildOrErr.takeError())) + error(std::move(E), UA->getFileName(), i->get(), MoreThanOneArch ? + StringRef(I->getArchTypeName()) : StringRef()); continue; } if (ObjectFile *o = dyn_cast(&*ChildOrErr.get())) {