diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -119,6 +119,8 @@ BIDFetcher = std::move(Fetcher); } + bool findBinaryFile(StringRef Name, std::string &Message); + private: // Bundles together object file with code/data and object file with // corresponding debug info. These objects can be the same. diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -710,6 +710,21 @@ return Name; } +/// Checks if the given file exists and can be opened as executable/relocatable +/// file. +/// \param BinName Name of the file to search for. +/// \param Message Error message if the file cannot be opened. +/// \returns True if the file was successfully opened. +bool LLVMSymbolizer::findBinaryFile(StringRef BinName, std::string &Message) { + Expected BinFile = getOrCreateModuleInfo(BinName.str()); + if (!BinFile) { + handleAllErrors(BinFile.takeError(), + [&](const ErrorInfoBase &EI) { Message = EI.message(); }); + return false; + } + return true; +} + void LLVMSymbolizer::recordAccess(CachedBinary &Bin) { if (Bin->getBinary()) LRUBinaries.splice(LRUBinaries.end(), LRUBinaries, Bin.getIterator()); diff --git a/llvm/test/tools/llvm-symbolizer/input-base.test b/llvm/test/tools/llvm-symbolizer/input-base.test --- a/llvm/test/tools/llvm-symbolizer/input-base.test +++ b/llvm/test/tools/llvm-symbolizer/input-base.test @@ -11,14 +11,14 @@ RUN: llvm-symbolizer -e /dev/null -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL-UPPER # llvm-addr2line always requires hexadecimal, but accepts an optional 0x prefix. -RUN: llvm-addr2line -e /dev/null -a 0x1234 | FileCheck %s -RUN: llvm-addr2line -e /dev/null -a 0X1234 | FileCheck %s -RUN: llvm-addr2line -e /dev/null -a 1234 | FileCheck %s -RUN: llvm-addr2line -e /dev/null -a 01234 | FileCheck %s -RUN: llvm-addr2line -e /dev/null -a 0b1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY -RUN: llvm-addr2line -e /dev/null -a 0B1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY -RUN: llvm-addr2line -e /dev/null -a 0o1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL -RUN: llvm-addr2line -e /dev/null -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0x1234 | FileCheck %s +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0X1234 | FileCheck %s +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 1234 | FileCheck %s +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 01234 | FileCheck %s +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0b1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0B1010 | FileCheck %s --check-prefix=HEXADECIMAL-NOT-BINARY +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0o1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL +RUN: llvm-addr2line -e %p/Inputs/addr.exe -a 0O1234 | FileCheck %s --check-prefix=INVALID-NOT-OCTAL CHECK: 0x1234 CHECK-NEXT: ?? diff --git a/llvm/test/tools/llvm-symbolizer/untag-addresses.test b/llvm/test/tools/llvm-symbolizer/untag-addresses.test --- a/llvm/test/tools/llvm-symbolizer/untag-addresses.test +++ b/llvm/test/tools/llvm-symbolizer/untag-addresses.test @@ -3,12 +3,13 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo DATA %t.o 0 | llvm-symbolizer | FileCheck --check-prefix=UNTAG %s # RUN: echo DATA %t.o 0 | llvm-symbolizer --no-untag-addresses | FileCheck --check-prefix=NOUNTAG %s -# RUN: echo DATA %t.o 0 | llvm-addr2line | FileCheck --check-prefix=NOUNTAG %s +# RUN: echo DATA %t.o 0 | llvm-addr2line -e %t.o| FileCheck --check-prefix=NOUNTAG-GNU %s # UNTAG: foo # UNTAG: 0 4 # NOUNTAG: ?? # NOUNTAG: 0 0 +# NOUNTAG-GNU: ??:0 .data .globl foo diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -387,7 +387,8 @@ InitLLVM X(argc, argv); sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded); - bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line"); + StringRef ToolName = sys::path::stem(argv[0]); + bool IsAddr2Line = ToolName.contains("addr2line"); BumpPtrAllocator A; StringSaver Saver(A); SymbolizerOptTable Tbl; @@ -476,6 +477,17 @@ else Printer = std::make_unique(outs(), errs(), Config); + if (IsAddr2Line) { + StringRef InputFile = Args.getLastArgValue(OPT_obj_EQ); + if (InputFile.empty()) + InputFile = "a.out"; + std::string Message; + if (!Symbolizer.findBinaryFile(InputFile, Message)) { + errs() << ToolName << ": '" << InputFile << "': " << Message << '\n'; + return EXIT_FAILURE; + } + } + std::vector InputAddresses = Args.getAllArgValues(OPT_INPUT); if (InputAddresses.empty()) { const int kMaxInputStringLength = 1024;