From 267dc8d764fd79de2cdaff780c00559cd3b1e6b5 Mon Sep 17 00:00:00 2001 From: James Henderson Date: Thu, 10 Jan 2019 14:10:02 +0000 Subject: [PATCH] [llvm-symbolizer] Add support for specifying addresses on command-line See https://bugs.llvm.org/show_bug.cgi?id=40070. GNU addr2line accepts input addresses both on the command-line and via stdin. llvm-symbolizer previously only supported the latter. This change adds support for the former. As with addr2line, the new behaviour is to only look for addresses on stdin if no positional arguments were provided to llvm-symbolizer. Reviewed by: ruiu Differential Revision: https://reviews.llvm.org/D56272 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350821 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/tools/llvm-symbolizer/basic.s | 19 ++++++++ tools/llvm-symbolizer/llvm-symbolizer.cpp | 80 +++++++++++++++++-------------- 2 files changed, 63 insertions(+), 36 deletions(-) create mode 100644 test/tools/llvm-symbolizer/basic.s diff --git a/test/tools/llvm-symbolizer/basic.s b/test/tools/llvm-symbolizer/basic.s new file mode 100644 index 00000000000..0ee3084d80a --- /dev/null +++ b/test/tools/llvm-symbolizer/basic.s @@ -0,0 +1,19 @@ +# REQUIRES: x86-registered-target + +foo: + .space 10 + nop + nop + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -g + +# Check input addresses specified on stdin. +# RUN: echo -e "0xa\n0xb" | llvm-symbolizer --obj=%t.o | FileCheck %s +# RUN: echo -e "10\n11" | llvm-symbolizer --obj=%t.o | FileCheck %s + +# Check input addresses specified on the command-line. +# RUN: llvm-symbolizer 0xa 0xb --obj=%t.o | FileCheck %s +# RUN: llvm-symbolizer 10 11 --obj=%t.o | FileCheck %s + +# CHECK: basic.s:5:0 +# CHECK: basic.s:6:0 diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index 6d40a540350..891f1127d61 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -90,6 +90,10 @@ static cl::opt ClPrintSourceContextLines( static cl::opt ClVerbose("verbose", cl::init(false), cl::desc("Print verbose line info")); +static cl::list ClInputAddresses(cl::Positional, + cl::desc("..."), + cl::ZeroOrMore); + template static bool error(Expected &ResOrErr) { if (ResOrErr) @@ -137,6 +141,38 @@ static bool parseCommand(StringRef InputString, bool &IsData, return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset); } +static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer, + DIPrinter &Printer) { + bool IsData = false; + std::string ModuleName; + uint64_t ModuleOffset = 0; + if (!parseCommand(StringRef(InputString), IsData, ModuleName, ModuleOffset)) { + outs() << InputString; + return; + } + + if (ClPrintAddress) { + outs() << "0x"; + outs().write_hex(ModuleOffset); + StringRef Delimiter = ClPrettyPrint ? ": " : "\n"; + outs() << Delimiter; + } + if (IsData) { + auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); + Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get()); + } else if (ClPrintInlining) { + auto ResOrErr = + Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset, ClDwpName); + Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get()); + } else { + auto ResOrErr = + Symbolizer.symbolizeCode(ModuleName, ModuleOffset, ClDwpName); + Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get()); + } + outs() << "\n"; + outs().flush(); +} + int main(int argc, char **argv) { InitLLVM X(argc, argv); @@ -159,43 +195,15 @@ int main(int argc, char **argv) { DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None, ClPrettyPrint, ClPrintSourceContextLines, ClVerbose); - const int kMaxInputStringLength = 1024; - char InputString[kMaxInputStringLength]; + if (ClInputAddresses.empty()) { + const int kMaxInputStringLength = 1024; + char InputString[kMaxInputStringLength]; - while (true) { - if (!fgets(InputString, sizeof(InputString), stdin)) - break; - - bool IsData = false; - std::string ModuleName; - uint64_t ModuleOffset = 0; - if (!parseCommand(StringRef(InputString), IsData, ModuleName, - ModuleOffset)) { - outs() << InputString; - continue; - } - - if (ClPrintAddress) { - outs() << "0x"; - outs().write_hex(ModuleOffset); - StringRef Delimiter = ClPrettyPrint ? ": " : "\n"; - outs() << Delimiter; - } - if (IsData) { - auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); - Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get()); - } else if (ClPrintInlining) { - auto ResOrErr = - Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset, ClDwpName); - Printer << (error(ResOrErr) ? DIInliningInfo() - : ResOrErr.get()); - } else { - auto ResOrErr = - Symbolizer.symbolizeCode(ModuleName, ModuleOffset, ClDwpName); - Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get()); - } - outs() << "\n"; - outs().flush(); + while (fgets(InputString, sizeof(InputString), stdin)) + symbolizeInput(InputString, Symbolizer, Printer); + } else { + for (StringRef Address : ClInputAddresses) + symbolizeInput(Address, Symbolizer, Printer); } return 0; -- 2.11.0