forked from OSchip/llvm-project
[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 llvm-svn: 350821
This commit is contained in:
parent
97ed076dd1
commit
3a6a5a3370
|
@ -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
|
|
@ -90,6 +90,10 @@ static cl::opt<int> ClPrintSourceContextLines(
|
||||||
static cl::opt<bool> ClVerbose("verbose", cl::init(false),
|
static cl::opt<bool> ClVerbose("verbose", cl::init(false),
|
||||||
cl::desc("Print verbose line info"));
|
cl::desc("Print verbose line info"));
|
||||||
|
|
||||||
|
static cl::list<std::string> ClInputAddresses(cl::Positional,
|
||||||
|
cl::desc("<input addresses>..."),
|
||||||
|
cl::ZeroOrMore);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool error(Expected<T> &ResOrErr) {
|
static bool error(Expected<T> &ResOrErr) {
|
||||||
if (ResOrErr)
|
if (ResOrErr)
|
||||||
|
@ -137,6 +141,38 @@ static bool parseCommand(StringRef InputString, bool &IsData,
|
||||||
return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset);
|
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) {
|
int main(int argc, char **argv) {
|
||||||
InitLLVM X(argc, argv);
|
InitLLVM X(argc, argv);
|
||||||
|
|
||||||
|
@ -159,43 +195,15 @@ int main(int argc, char **argv) {
|
||||||
DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None,
|
DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None,
|
||||||
ClPrettyPrint, ClPrintSourceContextLines, ClVerbose);
|
ClPrettyPrint, ClPrintSourceContextLines, ClVerbose);
|
||||||
|
|
||||||
const int kMaxInputStringLength = 1024;
|
if (ClInputAddresses.empty()) {
|
||||||
char InputString[kMaxInputStringLength];
|
const int kMaxInputStringLength = 1024;
|
||||||
|
char InputString[kMaxInputStringLength];
|
||||||
|
|
||||||
while (true) {
|
while (fgets(InputString, sizeof(InputString), stdin))
|
||||||
if (!fgets(InputString, sizeof(InputString), stdin))
|
symbolizeInput(InputString, Symbolizer, Printer);
|
||||||
break;
|
} else {
|
||||||
|
for (StringRef Address : ClInputAddresses)
|
||||||
bool IsData = false;
|
symbolizeInput(Address, Symbolizer, Printer);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue