Add support for fetching inlining context (stack of source code locations)

by instruction address from DWARF.

Add --inlining flag to llvm-dwarfdump to demonstrate and test this functionality,
so that "llvm-dwarfdump --inlining --address=0x..." now works much like
"addr2line -i 0x...", provided that the binary has debug info
(Clang's -gline-tables-only *is* enough).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163128 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alexey Samsonov
2012-09-04 08:12:33 +00:00
parent 2d5c28da0d
commit 5eae90d727
12 changed files with 359 additions and 88 deletions

View File

@ -44,6 +44,18 @@ PrintFunctions("functions", cl::init(false),
cl::desc("Print function names as well as line information "
"for a given address"));
static cl::opt<bool>
PrintInlining("inlining", cl::init(false),
cl::desc("Print all inlined frames for a given address"));
static void PrintDILineInfo(DILineInfo dli) {
if (PrintFunctions)
outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
<< "\n";
outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
<< dli.getLine() << ':' << dli.getColumn() << '\n';
}
static void DumpInput(const StringRef &Filename) {
OwningPtr<MemoryBuffer> Buff;
@ -101,16 +113,27 @@ static void DumpInput(const StringRef &Filename) {
dictx->dump(outs());
} else {
// Print line info for the specified address.
int spec_flags = DILineInfoSpecifier::FileLineInfo |
DILineInfoSpecifier::AbsoluteFilePath;
int SpecFlags = DILineInfoSpecifier::FileLineInfo |
DILineInfoSpecifier::AbsoluteFilePath;
if (PrintFunctions)
spec_flags |= DILineInfoSpecifier::FunctionName;
DILineInfo dli = dictx->getLineInfoForAddress(Address, spec_flags);
if (PrintFunctions)
outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
<< "\n";
outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
<< dli.getLine() << ':' << dli.getColumn() << '\n';
SpecFlags |= DILineInfoSpecifier::FunctionName;
if (PrintInlining) {
DIInliningInfo InliningInfo = dictx->getInliningInfoForAddress(
Address, SpecFlags);
uint32_t n = InliningInfo.getNumberOfFrames();
if (n == 0) {
// Print one empty debug line info in any case.
PrintDILineInfo(DILineInfo());
} else {
for (uint32_t i = 0; i < n; i++) {
DILineInfo dli = InliningInfo.getFrame(i);
PrintDILineInfo(dli);
}
}
} else {
DILineInfo dli = dictx->getLineInfoForAddress(Address, SpecFlags);
PrintDILineInfo(dli);
}
}
}