Index: llvm/trunk/test/tools/llvm-symbolizer/basic.s =================================================================== --- llvm/trunk/test/tools/llvm-symbolizer/basic.s +++ llvm/trunk/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 Index: llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp =================================================================== --- llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -90,6 +90,10 @@ 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 @@ 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 @@ DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None, ClPrettyPrint, ClPrintSourceContextLines, ClVerbose); - 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 (ClInputAddresses.empty()) { + const int kMaxInputStringLength = 1024; + char InputString[kMaxInputStringLength]; - 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;