[llvm] r269784 - Change llvm-objdump, llvm-nm and llvm-size when reporting an object file error

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Tue May 17 13:15:17 PDT 2016


On linux I get a link error on ToT that dissappears when I
revert this change:

Scanning dependencies of target IRTests
[ 70%] Building CXX object
unittests/ADT/CMakeFiles/ADTTests.dir/APFloatTest.cpp.o
[ 70%] Building CXX object
unittests/Linker/CMakeFiles/LinkerTests.dir/LinkModulesTest.cpp.o
[ 70%] Building CXX object
unittests/Transforms/Utils/CMakeFiles/UtilsTests.dir/ASanStackFrameLayoutTest.cpp.o
[ 70%] Building CXX object
unittests/Analysis/CMakeFiles/AnalysisTests.dir/AliasAnalysisTest.cpp.o
[ 81%] Built target LLVMCodeGen
[ 81%] Building CXX object
unittests/Analysis/CMakeFiles/AnalysisTests.dir/BlockFrequencyInfoTest.cpp.o
[ 81%] Building CXX object
unittests/IR/CMakeFiles/IRTests.dir/AsmWriterTest.cpp.o
../../lib/libLLVMMCDisassembler.a(MCRelocationInfo.cpp.o): In function
`llvm::object::make_error_code(llvm::object::object_error)':
/local/sanjoy/llvm.git/include/llvm/Object/Error.h:40: undefined
reference to `llvm::object::object_category()'
collect2: error: ld returned 1 exit status


Any idea what's going on?

On Tue, May 17, 2016 at 10:10 AM, Kevin Enderby via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: enderby
> Date: Tue May 17 12:10:12 2016
> New Revision: 269784
>
> URL: http://llvm.org/viewvc/llvm-project?rev=269784&view=rev
> Log:
> Change llvm-objdump, llvm-nm and llvm-size when reporting an object file error
> when the object is in an archive to use something like libx.a(foo.o) as part of
> the error message.
>
> Also changed llvm-objdump and llvm-size to be like llvm-nm and ignore non-object
> files in archives and not produce any error message.
>
> To do this Archive::Child::getAsBinary() was changed from ErrorOr<...> to
> Expected<...> then that was threaded up to its users.
>
> Converting this interface to Expected<> from ErrorOr<> does involve
> touching a number of places. To contain the changes for now the use of
> errorToErrorCode() is still used in one place yet to be fully converted.
>
> Again there some were bugs in the existing code that did not deal with the
> old ErrorOr<> return values.  So now with Expected<> since they must be
> checked and the error handled, I added a TODO and a comments for those.
>
> Added:
>     llvm/trunk/test/Object/Inputs/macho-bad-archive1.a   (with props)
>     llvm/trunk/test/Object/Inputs/macho-bad-archive2.a   (with props)
> Modified:
>     llvm/trunk/include/llvm/Object/Archive.h
>     llvm/trunk/include/llvm/Object/Error.h
>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>     llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
>     llvm/trunk/lib/Object/Archive.cpp
>     llvm/trunk/test/Object/macho-invalid.test
>     llvm/trunk/test/Object/nm-archive.test
>     llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp
>     llvm/trunk/tools/llvm-nm/llvm-nm.cpp
>     llvm/trunk/tools/llvm-objdump/MachODump.cpp
>     llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
>     llvm/trunk/tools/llvm-objdump/llvm-objdump.h
>     llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
>     llvm/trunk/tools/llvm-size/llvm-size.cpp
>     llvm/trunk/tools/sancov/sancov.cc
>
> Modified: llvm/trunk/include/llvm/Object/Archive.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Archive.h?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/Archive.h (original)
> +++ llvm/trunk/include/llvm/Object/Archive.h Tue May 17 12:10:12 2016
> @@ -101,7 +101,7 @@ public:
>
>      ErrorOr<MemoryBufferRef> getMemoryBufferRef() const;
>
> -    ErrorOr<std::unique_ptr<Binary>>
> +    Expected<std::unique_ptr<Binary>>
>      getAsBinary(LLVMContext *Context = nullptr) const;
>    };
>
>
> Modified: llvm/trunk/include/llvm/Object/Error.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Error.h?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/Error.h (original)
> +++ llvm/trunk/include/llvm/Object/Error.h Tue May 17 12:10:12 2016
> @@ -81,4 +81,34 @@ template <>
>  struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
>  }
>
> +namespace llvm {
> +namespace object {
> +
> +// isNotObjectErrorInvalidFileType() is used when looping through the children
> +// of an archive after calling getAsBinary() on the child and it returns an
> +// llvm::Error.  In the cases we want to loop through the children and ignore the
> +// non-objects in the archive this is used to test the error to see if an
> +// error() function needs to called on the llvm::Error.
> +static inline llvm::Error 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;
> +}
> +
> +} // end namespace object.
> +
> +} // end namespace llvm.
> +
>  #endif
>
> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Tue May 17 12:10:12 2016
> @@ -329,10 +329,13 @@ RuntimeDyld::SymbolInfo MCJIT::findSymbo
>        report_fatal_error(EC.message());
>      if (ChildIt != A->child_end()) {
>        // FIXME: Support nested archives?
> -      ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
> +      Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
>            (*ChildIt)->getAsBinary();
> -      if (ChildBinOrErr.getError())
> +      if (!ChildBinOrErr) {
> +        // TODO: Actually report errors helpfully.
> +        consumeError(ChildBinOrErr.takeError());
>          continue;
> +      }
>        std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
>        if (ChildBin->isObject()) {
>          std::unique_ptr<object::ObjectFile> OF(
>
> Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)
> +++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Tue May 17 12:10:12 2016
> @@ -263,10 +263,13 @@ private:
>          report_fatal_error(EC.message());
>        if (ChildIt != A->child_end()) {
>          // FIXME: Support nested archives?
> -        ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
> +        Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
>              (*ChildIt)->getAsBinary();
> -        if (ChildBinOrErr.getError())
> +        if (!ChildBinOrErr) {
> +          // TODO: Actually report errors helpfully.
> +          consumeError(ChildBinOrErr.takeError());
>            continue;
> +        }
>          std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
>          if (ChildBin->isObject()) {
>            std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
>
> Modified: llvm/trunk/lib/Object/Archive.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Archive.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Object/Archive.cpp (original)
> +++ llvm/trunk/lib/Object/Archive.cpp Tue May 17 12:10:12 2016
> @@ -228,6 +228,11 @@ ErrorOr<StringRef> Archive::Child::getNa
>      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('\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] == '/')
> @@ -246,16 +251,16 @@ ErrorOr<MemoryBufferRef> Archive::Child:
>    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);
>
>    auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
>    if (BinaryOrErr)
>      return std::move(*BinaryOrErr);
> -  return errorToErrorCode(BinaryOrErr.takeError());
> +  return BinaryOrErr.takeError();
>  }
>
>  ErrorOr<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
>
> Added: llvm/trunk/test/Object/Inputs/macho-bad-archive1.a
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-bad-archive1.a?rev=269784&view=auto
> ==============================================================================
> Binary file - no diff available.
>
> Propchange: llvm/trunk/test/Object/Inputs/macho-bad-archive1.a
> ------------------------------------------------------------------------------
>     svn:mime-type = application/octet-stream
>
> Added: llvm/trunk/test/Object/Inputs/macho-bad-archive2.a
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/macho-bad-archive2.a?rev=269784&view=auto
> ==============================================================================
> Binary file - no diff available.
>
> Propchange: llvm/trunk/test/Object/Inputs/macho-bad-archive2.a
> ------------------------------------------------------------------------------
>     svn:mime-type = application/octet-stream
>
> Modified: llvm/trunk/test/Object/macho-invalid.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/macho-invalid.test?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/test/Object/macho-invalid.test (original)
> +++ llvm/trunk/test/Object/macho-invalid.test Tue May 17 12:10:12 2016
> @@ -56,6 +56,10 @@ RUN: llvm-nm -pax %p/Inputs/macho-invali
>  RUN:      | FileCheck -check-prefix NAME-PAST-EOF-nm-pax %s
>  NAME-PAST-EOF-nm-pax: 0000000000000000 64 00 0000 fe000002 bad string index
>
> +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: 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
> @@ -74,3 +78,6 @@ INVALID-HEADER: The file was not recogni
>
>  RUN: not llvm-objdump -macho -private-headers %p/Inputs/macho64-invalid-incomplete-segment-load-command 2>&1 | FileCheck -check-prefix INCOMPLETE-SEGMENT-LOADC %s
>  INCOMPLETE-SEGMENT-LOADC: truncated or malformed object (load commands extend past the end of the file)
> +
> +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)
>
> Modified: llvm/trunk/test/Object/nm-archive.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/nm-archive.test?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/test/Object/nm-archive.test (original)
> +++ llvm/trunk/test/Object/nm-archive.test Tue May 17 12:10:12 2016
> @@ -55,9 +55,10 @@ RUN: llvm-nm %p/Inputs/archive-test.a-em
>
>  This archive has an unaligned member and a unknown format member.
>  GNU AR is able to parse the unaligned member and warns about the member with
> -the unknown format. We should probably simply warn on both. For now just check
> -that we don't produce an error.
> -RUN: llvm-nm %p/Inputs/corrupt-archive.a
> +the unknown format. We should probably simply warn on both. For now we just
> +produce an error for the unknown format.
> +RUN: not llvm-nm %p/Inputs/corrupt-archive.a 2>&1 | FileCheck %s -check-prefix CORRUPT
> +CORRUPT: corrupt-archive.a(trivial-object-test2.elf-x86-64) Invalid data was encountered while parsing the file
>
>
>  RUN: llvm-nm %p/Inputs/thin.a | FileCheck %s -check-prefix THIN
>
> Modified: llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp (original)
> +++ llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp Tue May 17 12:10:12 2016
> @@ -485,11 +485,17 @@ static void dumpArchive(const Archive *A
>    for (auto &ErrorOrChild : Arc->children()) {
>      error(ErrorOrChild.getError());
>      const Archive::Child &ArcC = *ErrorOrChild;
> -    ErrorOr<std::unique_ptr<Binary>> ChildOrErr = ArcC.getAsBinary();
> -    if (std::error_code EC = ChildOrErr.getError()) {
> +    Expected<std::unique_ptr<Binary>> ChildOrErr = ArcC.getAsBinary();
> +    if (!ChildOrErr) {
>        // Ignore non-object files.
> -      if (EC != object_error::invalid_file_type)
> -        reportError(Arc->getFileName(), EC.message());
> +      if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
> +        std::string Buf;
> +        raw_string_ostream OS(Buf);
> +        logAllUnhandledErrors(std::move(E), OS, "");
> +        OS.flush();
> +        reportError(Arc->getFileName(), Buf);
> +      }
> +      ChildOrErr.takeError();
>        continue;
>      }
>
>
> Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
> +++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Tue May 17 12:10:12 2016
> @@ -190,6 +190,29 @@ static bool error(std::error_code EC, Tw
>    return false;
>  }
>
> +// 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) {
> +  HadError = true;
> +  errs() << ToolName << ": " << FileName;
> +
> +  ErrorOr<StringRef> 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())
> +    errs() << "(" << "???" << ")";
> +  else
> +    errs() << "(" << NameOrErr.get() << ")";
> +
> +  std::string Buf;
> +  raw_string_ostream OS(Buf);
> +  logAllUnhandledErrors(std::move(E), OS, "");
> +  OS.flush();
> +  errs() << " " << Buf << "\n";
> +}
> +
>  namespace {
>  struct NMSymbol {
>    uint64_t Address;
> @@ -1066,9 +1089,12 @@ static void dumpSymbolNamesFromFile(std:
>        if (error(I->getError()))
>          return;
>        auto &C = I->get();
> -      ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
> -      if (ChildOrErr.getError())
> +      Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
> +      if (!ChildOrErr) {
> +        if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +          error(std::move(E), Filename, C);
>          continue;
> +      }
>        if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
>          if (!checkMachOAndArchFlags(O, Filename))
>            return;
> @@ -1124,10 +1150,14 @@ static void dumpSymbolNamesFromFile(std:
>                  if (error(AI->getError()))
>                    return;
>                  auto &C = AI->get();
> -                ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
> +                Expected<std::unique_ptr<Binary>> ChildOrErr =
>                      C.getAsBinary(&Context);
> -                if (ChildOrErr.getError())
> +                if (!ChildOrErr) {
> +                  if (auto E = isNotObjectErrorInvalidFileType(
> +                                       ChildOrErr.takeError()))
> +                    error(std::move(E), Filename, C);
>                    continue;
> +                }
>                  if (SymbolicFile *O =
>                          dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
>                    if (PrintFileName) {
> @@ -1181,10 +1211,14 @@ static void dumpSymbolNamesFromFile(std:
>                if (error(AI->getError()))
>                  return;
>                auto &C = AI->get();
> -              ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
> +              Expected<std::unique_ptr<Binary>> ChildOrErr =
>                    C.getAsBinary(&Context);
> -              if (ChildOrErr.getError())
> +              if (!ChildOrErr) {
> +                if (auto E = isNotObjectErrorInvalidFileType(
> +                                     ChildOrErr.takeError()))
> +                  error(std::move(E), Filename, C);
>                  continue;
> +              }
>                if (SymbolicFile *O =
>                        dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
>                  if (PrintFileName)
> @@ -1233,9 +1267,13 @@ static void dumpSymbolNamesFromFile(std:
>            if (error(AI->getError()))
>              return;
>            auto &C = AI->get();
> -          ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
> -          if (ChildOrErr.getError())
> +          Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
> +          if (!ChildOrErr) {
> +            if (auto E = isNotObjectErrorInvalidFileType(
> +                                 ChildOrErr.takeError()))
> +              error(std::move(E), Filename, C);
>              continue;
> +          }
>            if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
>              if (PrintFileName) {
>                ArchiveName = A->getFileName();
>
> Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
> +++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Tue May 17 12:10:12 2016
> @@ -1211,7 +1211,7 @@ static void ProcessMachO(StringRef Filen
>    // If we are doing some processing here on the Mach-O file print the header
>    // info.  And don't print it otherwise like in the case of printing the
>    // UniversalHeaders or ArchiveHeaders.
> -  if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind ||
> +  if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable ||
>        LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints ||
>        DylibsUsed || DylibId || ObjcMetaData || (FilterSections.size() != 0)) {
>      outs() << Filename;
> @@ -1244,8 +1244,10 @@ static void ProcessMachO(StringRef Filen
>      PrintDylibs(MachOOF, false);
>    if (DylibId)
>      PrintDylibs(MachOOF, true);
> -  if (SymbolTable)
> -    PrintSymbolTable(MachOOF);
> +  if (SymbolTable) {
> +    StringRef ArchiveName = ArchiveMemberName == StringRef() ? "" : Filename;
> +    PrintSymbolTable(MachOOF, ArchiveName);
> +  }
>    if (UnwindInfo)
>      printMachOUnwindInfo(MachOOF);
>    if (PrivateHeaders) {
> @@ -1552,9 +1554,12 @@ void llvm::ParseInputMachO(StringRef Fil
>        if (std::error_code EC = I->getError())
>          report_error(Filename, EC);
>        auto &C = I->get();
> -      ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> -      if (ChildOrErr.getError())
> +      Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> +      if (!ChildOrErr) {
> +        if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +          report_error(Filename, C, std::move(E));
>          continue;
> +      }
>        if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
>          if (!checkMachOAndArchFlags(O, Filename))
>            return;
> @@ -1603,9 +1608,12 @@ void llvm::ParseInputMachO(StringRef Fil
>                  if (std::error_code EC = AI->getError())
>                    report_error(Filename, EC);
>                  auto &C = AI->get();
> -                ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> -                if (ChildOrErr.getError())
> +                Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> +                if (!ChildOrErr) {
> +                  if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +                    report_error(Filename, C, std::move(E));
>                    continue;
> +                }
>                  if (MachOObjectFile *O =
>                          dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
>                    ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
> @@ -1648,9 +1656,12 @@ void llvm::ParseInputMachO(StringRef Fil
>                if (std::error_code EC = AI->getError())
>                  report_error(Filename, EC);
>                auto &C = AI->get();
> -              ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> -              if (ChildOrErr.getError())
> +              Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> +              if (!ChildOrErr) {
> +                if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +                  report_error(Filename, C, std::move(E));
>                  continue;
> +              }
>                if (MachOObjectFile *O =
>                        dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
>                  ProcessMachO(Filename, O, O->getFileName());
> @@ -1687,9 +1698,12 @@ void llvm::ParseInputMachO(StringRef Fil
>            if (std::error_code EC = AI->getError())
>              report_error(Filename, EC);
>            auto &C = AI->get();
> -          ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> -          if (ChildOrErr.getError())
> +          Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> +          if (!ChildOrErr) {
> +            if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +              report_error(Filename, C, std::move(E));
>              continue;
> +          }
>            if (MachOObjectFile *O =
>                    dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
>              if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
>
> Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
> +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Tue May 17 12:10:12 2016
> @@ -281,6 +281,36 @@ LLVM_ATTRIBUTE_NORETURN void llvm::repor
>    exit(1);
>  }
>
> +LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
> +                                                StringRef FileName,
> +                                                llvm::Error E) {
> +  assert(E);
> +  errs() << ToolName << ": ";
> +  if (ArchiveName != "")
> +    errs() << ArchiveName << "(" << FileName << ")";
> +  else
> +    errs() << FileName;
> +  std::string Buf;
> +  raw_string_ostream OS(Buf);
> +  logAllUnhandledErrors(std::move(E), OS, "");
> +  OS.flush();
> +  errs() << " " << Buf;
> +  exit(1);
> +}
> +
> +LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
> +                                                const object::Archive::Child &C,
> +                                                llvm::Error E) {
> +  ErrorOr<StringRef> 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));
> +  else
> +    llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E));
> +}
> +
>  static const Target *getTarget(const ObjectFile *Obj = nullptr) {
>    // Figure out the target triple.
>    llvm::Triple TheTriple("unknown-unknown-unknown");
> @@ -1346,7 +1376,7 @@ void llvm::PrintSectionContents(const Ob
>    }
>  }
>
> -void llvm::PrintSymbolTable(const ObjectFile *o) {
> +void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName) {
>    outs() << "SYMBOL TABLE:\n";
>
>    if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
> @@ -1359,7 +1389,7 @@ void llvm::PrintSymbolTable(const Object
>      uint64_t Address = *AddressOrError;
>      Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
>      if (!TypeOrError)
> -      report_error(o->getFileName(), TypeOrError.takeError());
> +      report_error(ArchiveName, o->getFileName(), TypeOrError.takeError());
>      SymbolRef::Type Type = *TypeOrError;
>      uint32_t Flags = Symbol.getFlags();
>      Expected<section_iterator> SectionOrErr = Symbol.getSection();
> @@ -1371,7 +1401,7 @@ void llvm::PrintSymbolTable(const Object
>      } else {
>        Expected<StringRef> NameOrErr = Symbol.getName();
>        if (!NameOrErr)
> -        report_error(o->getFileName(), NameOrErr.takeError());
> +        report_error(ArchiveName, o->getFileName(), NameOrErr.takeError());
>        Name = *NameOrErr;
>      }
>
> @@ -1603,12 +1633,16 @@ static void printFirstPrivateFileHeader(
>      report_fatal_error("Invalid/Unsupported object file format");
>  }
>
> -static void DumpObject(const ObjectFile *o) {
> +static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
> +  StringRef ArchiveName = a != nullptr ? a->getFileName() : "";
>    // Avoid other output when using a raw option.
>    if (!RawClangAST) {
>      outs() << '\n';
> -    outs() << o->getFileName()
> -           << ":\tfile format " << o->getFileFormatName() << "\n\n";
> +    if (a)
> +      outs() << a->getFileName() << "(" << o->getFileName() << ")";
> +    else
> +      outs() << o->getFileName();
> +    outs() << ":\tfile format " << o->getFileFormatName() << "\n\n";
>    }
>
>    if (Disassemble)
> @@ -1620,7 +1654,7 @@ static void DumpObject(const ObjectFile
>    if (SectionContents)
>      PrintSectionContents(o);
>    if (SymbolTable)
> -    PrintSymbolTable(o);
> +    PrintSymbolTable(o, ArchiveName);
>    if (UnwindInfo)
>      PrintUnwindInfo(o);
>    if (PrivateHeaders)
> @@ -1654,12 +1688,14 @@ static void DumpArchive(const Archive *a
>      if (std::error_code EC = ErrorOrChild.getError())
>        report_error(a->getFileName(), EC);
>      const Archive::Child &C = *ErrorOrChild;
> -    ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> -    if (std::error_code EC = ChildOrErr.getError())
> -      if (EC != object_error::invalid_file_type)
> -        report_error(a->getFileName(), EC);
> +    Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
> +    if (!ChildOrErr) {
> +      if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +        report_error(a->getFileName(), C, std::move(E));
> +      continue;
> +    }
>      if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
> -      DumpObject(o);
> +      DumpObject(o, a);
>      else
>        report_error(a->getFileName(), object_error::invalid_file_type);
>    }
>
> Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original)
> +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Tue May 17 12:10:12 2016
> @@ -13,6 +13,7 @@
>  #include "llvm/Support/CommandLine.h"
>  #include "llvm/Support/Compiler.h"
>  #include "llvm/Support/DataTypes.h"
> +#include "llvm/Object/Archive.h"
>
>  namespace llvm {
>  class StringRef;
> @@ -21,6 +22,7 @@ namespace object {
>    class COFFObjectFile;
>    class MachOObjectFile;
>    class ObjectFile;
> +  class Archive;
>    class RelocationRef;
>  }
>
> @@ -84,9 +86,15 @@ void printRawClangAST(const object::Obje
>  void PrintRelocations(const object::ObjectFile *o);
>  void PrintSectionHeaders(const object::ObjectFile *o);
>  void PrintSectionContents(const object::ObjectFile *o);
> -void PrintSymbolTable(const object::ObjectFile *o);
> +void PrintSymbolTable(const object::ObjectFile *o, StringRef ArchiveName);
>  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_ATTRIBUTE_NORETURN void report_error(StringRef ArchiveName,
> +                                          const object::Archive::Child &C,
> +                                          llvm::Error E);
>
>  } // end namespace llvm
>
>
> Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
> +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Tue May 17 12:10:12 2016
> @@ -421,14 +421,17 @@ static void dumpArchive(const Archive *A
>      if (std::error_code EC = ErrorOrChild.getError())
>        reportError(Arc->getFileName(), EC.message());
>      const auto &Child = *ErrorOrChild;
> -    ErrorOr<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
> -    if (std::error_code EC = ChildOrErr.getError()) {
> -      // Ignore non-object files.
> -      if (EC != object_error::invalid_file_type)
> -        reportError(Arc->getFileName(), EC.message());
> +    Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
> +    if (!ChildOrErr) {
> +      if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
> +        std::string Buf;
> +        raw_string_ostream OS(Buf);
> +        logAllUnhandledErrors(ChildOrErr.takeError(), OS, "");
> +        OS.flush();
> +        reportError(Arc->getFileName(), Buf);
> +      }
>        continue;
>      }
> -
>      if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
>        dumpObject(Obj);
>      else
>
> Modified: llvm/trunk/tools/llvm-size/llvm-size.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-size/llvm-size.cpp?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-size/llvm-size.cpp (original)
> +++ llvm/trunk/tools/llvm-size/llvm-size.cpp Tue May 17 12:10:12 2016
> @@ -99,6 +99,29 @@ static bool error(std::error_code ec) {
>    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.
> +static void error(llvm::Error E, StringRef FileName, const Archive::Child &C) {
> +  HadError = true;
> +  errs() << ToolName << ": " << FileName;
> +
> +  ErrorOr<StringRef> 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())
> +    errs() << "(" << "???" << ")";
> +  else
> +    errs() << "(" << NameOrErr.get() << ")";
> +
> +  std::string Buf;
> +  raw_string_ostream OS(Buf);
> +  logAllUnhandledErrors(std::move(E), OS, "");
> +  OS.flush();
> +  errs() << " " << Buf << "\n";
> +}
> +
>  /// Get the length of the string that represents @p num in Radix including the
>  /// leading 0x or 0 for hexadecimal and octal respectively.
>  static size_t getNumLengthAsString(uint64_t num) {
> @@ -480,9 +503,12 @@ static void printFileSectionSizes(String
>           i != e; ++i) {
>        if (error(i->getError()))
>          exit(1);
> -      ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
> -      if (error(ChildOrErr.getError()))
> +      Expected<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
> +      if (!ChildOrErr) {
> +        if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +          error(std::move(E), a->getFileName(), i->get());
>          continue;
> +      }
>        if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
>          MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
>          if (!checkMachOAndArchFlags(o, file))
> @@ -542,9 +568,13 @@ static void printFileSectionSizes(String
>                     i != e; ++i) {
>                  if (error(i->getError()))
>                    exit(1);
> -                ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
> -                if (error(ChildOrErr.getError()))
> +                Expected<std::unique_ptr<Binary>> ChildOrErr =
> +                                                  i->get().getAsBinary();
> +                if (!ChildOrErr) {
> +                  if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +                    error(std::move(E), a->getFileName(), i->get());
>                    continue;
> +                }
>                  if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
>                    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
>                    if (OutputFormat == sysv)
> @@ -618,9 +648,13 @@ static void printFileSectionSizes(String
>                   i != e; ++i) {
>                if (error(i->getError()))
>                  exit(1);
> -              ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
> -              if (error(ChildOrErr.getError()))
> +              Expected<std::unique_ptr<Binary>> ChildOrErr =
> +                                                i->get().getAsBinary();
> +              if (!ChildOrErr) {
> +                if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +                  error(std::move(E), a->getFileName(), i->get());
>                  continue;
> +              }
>                if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
>                  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
>                  if (OutputFormat == sysv)
> @@ -681,9 +715,12 @@ static void printFileSectionSizes(String
>               i != e; ++i) {
>            if (error(i->getError()))
>              exit(1);
> -          ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
> -          if (error(ChildOrErr.getError()))
> +          Expected<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
> +          if (!ChildOrErr) {
> +            if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
> +              error(std::move(E), UA->getFileName(), i->get());
>              continue;
> +          }
>            if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
>              MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
>              if (OutputFormat == sysv)
>
> Modified: llvm/trunk/tools/sancov/sancov.cc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/sancov/sancov.cc?rev=269784&r1=269783&r2=269784&view=diff
> ==============================================================================
> --- llvm/trunk/tools/sancov/sancov.cc (original)
> +++ llvm/trunk/tools/sancov/sancov.cc Tue May 17 12:10:12 2016
> @@ -414,8 +414,8 @@ visitObjectFiles(const object::Archive &
>    for (auto &ErrorOrChild : A.children()) {
>      FailIfError(ErrorOrChild);
>      const object::Archive::Child &C = *ErrorOrChild;
> -    ErrorOr<std::unique_ptr<object::Binary>> ChildOrErr = C.getAsBinary();
> -    FailIfError(ChildOrErr);
> +    Expected<std::unique_ptr<object::Binary>> ChildOrErr = C.getAsBinary();
> +    FailIfError(errorToErrorCode(ChildOrErr.takeError()));
>      if (auto *O = dyn_cast<object::ObjectFile>(&*ChildOrErr.get()))
>        Fn(*O);
>      else
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



-- 
Sanjoy Das
http://playingwithpointers.com


More information about the llvm-commits mailing list