From eceb5b99777ba944a0ae3748a0371e9a3aa94d56 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 27 Aug 2012 07:17:47 +0000 Subject: Add basic support for .debug_ranges section to LLVM's DebugInfo library. This section (introduced in DWARF-3) is used to define instruction address ranges for functions that are not contiguous and can't be described by low_pc/high_pc attributes (this is the usual case for inlined subroutines). The patch is the first step to support fetching complete inlining info from DWARF. Reviewed by Benjamin Kramer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162657 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/llvm-dwarfdump/llvm-dwarfdump.cpp') diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index ec0b4ae..59ecafa 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -59,6 +59,7 @@ static void DumpInput(const StringRef &Filename) { StringRef DebugLineSection; StringRef DebugArangesSection; StringRef DebugStringSection; + StringRef DebugRangesSection; error_code ec; for (section_iterator i = Obj->begin_sections(), @@ -82,6 +83,8 @@ static void DumpInput(const StringRef &Filename) { DebugArangesSection = data; else if (name == "debug_str") DebugStringSection = data; + else if (name == "debug_ranges") + DebugRangesSection = data; } OwningPtr dictx(DIContext::getDWARFContext(/*FIXME*/true, @@ -89,7 +92,8 @@ static void DumpInput(const StringRef &Filename) { DebugAbbrevSection, DebugArangesSection, DebugLineSection, - DebugStringSection)); + DebugStringSection, + DebugRangesSection)); if (Address == -1ULL) { outs() << Filename << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; -- cgit v1.1 From 5eae90d727c64ca5b4b43b110521b38dcd9f0de6 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 4 Sep 2012 08:12:33 +0000 Subject: 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 --- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 41 +++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'tools/llvm-dwarfdump/llvm-dwarfdump.cpp') 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 @@ PrintFunctions("functions", cl::init(false), cl::desc("Print function names as well as line information " "for a given address")); +static cl::opt +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() : "") + << "\n"; + outs() << (dli.getFileName() ? dli.getFileName() : "") << ':' + << dli.getLine() << ':' << dli.getColumn() << '\n'; +} + static void DumpInput(const StringRef &Filename) { OwningPtr 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; - if (PrintFunctions) - spec_flags |= DILineInfoSpecifier::FunctionName; - DILineInfo dli = dictx->getLineInfoForAddress(Address, spec_flags); + int SpecFlags = DILineInfoSpecifier::FileLineInfo | + DILineInfoSpecifier::AbsoluteFilePath; if (PrintFunctions) - outs() << (dli.getFunctionName() ? dli.getFunctionName() : "") - << "\n"; - outs() << (dli.getFileName() ? dli.getFileName() : "") << ':' - << 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); + } } } -- cgit v1.1