Skip to content

Commit

Permalink
[llvm-symbolizer] Add support for specifying addresses on command-line
Browse files Browse the repository at this point in the history
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

llvm-svn: 350821
  • Loading branch information
jh7370 committed Jan 10, 2019
1 parent 97ed076 commit 3a6a5a3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 36 deletions.
19 changes: 19 additions & 0 deletions llvm/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
80 changes: 44 additions & 36 deletions llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
Expand Up @@ -90,6 +90,10 @@ static cl::opt<int> ClPrintSourceContextLines(
static cl::opt<bool> ClVerbose("verbose", cl::init(false),
cl::desc("Print verbose line info"));

static cl::list<std::string> ClInputAddresses(cl::Positional,
cl::desc("<input addresses>..."),
cl::ZeroOrMore);

template<typename T>
static bool error(Expected<T> &ResOrErr) {
if (ResOrErr)
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down

0 comments on commit 3a6a5a3

Please sign in to comment.