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
diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 59ecafa..38c3a1e 100644
--- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -44,6 +44,18 @@
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 @@
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);
+ }
}
}