[llvm] r294231 - Get function start line number from DWARF info
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 6 12:19:03 PST 2017
Author: dblaikie
Date: Mon Feb 6 14:19:02 2017
New Revision: 294231
URL: http://llvm.org/viewvc/llvm-project?rev=294231&view=rev
Log:
Get function start line number from DWARF info
DWARF info contains info about the line number at which a function starts (DW_AT_decl_line).
This patch creates a function to look up the start line number for a function, and returns it in
DILineInfo when looking up debug info for a particular address.
Patch by Simon Que!
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D27962
Modified:
llvm/trunk/include/llvm/DebugInfo/DIContext.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp
llvm/trunk/test/tools/llvm-symbolizer/sym-verbose.test
Modified: llvm/trunk/include/llvm/DebugInfo/DIContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DIContext.h?rev=294231&r1=294230&r2=294231&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DIContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DIContext.h Mon Feb 6 14:19:02 2017
@@ -34,24 +34,28 @@ struct DILineInfo {
std::string FunctionName;
uint32_t Line;
uint32_t Column;
+ uint32_t StartLine;
// DWARF-specific.
uint32_t Discriminator;
DILineInfo()
: FileName("<invalid>"), FunctionName("<invalid>"), Line(0), Column(0),
- Discriminator(0) {}
+ StartLine(0), Discriminator(0) {}
bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column &&
- FileName == RHS.FileName && FunctionName == RHS.FunctionName;
+ FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
+ StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
}
bool operator!=(const DILineInfo &RHS) const {
return !(*this == RHS);
}
bool operator<(const DILineInfo &RHS) const {
- return std::tie(FileName, FunctionName, Line, Column) <
- std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column);
+ return std::tie(FileName, FunctionName, Line, Column, StartLine,
+ Discriminator) <
+ std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
+ RHS.StartLine, RHS.Discriminator);
}
};
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h?rev=294231&r1=294230&r2=294231&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h Mon Feb 6 14:19:02 2017
@@ -233,6 +233,12 @@ public:
/// references if necessary. Returns null if no name is found.
const char *getName(DINameKind Kind) const;
+ /// Returns the declaration line (start line) for a DIE, assuming it specifies
+ /// a subprogram. This may be fetched from specification or abstract origin
+ /// for this subprogram by resolving DW_AT_sepcification or
+ /// DW_AT_abstract_origin references if necessary.
+ uint64_t getDeclLine() const;
+
/// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column
/// from DIE (or zeroes if they are missing). This function looks for
/// DW_AT_call attributes in this DIE only, it will not resolve the attribute
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=294231&r1=294230&r2=294231&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Mon Feb 6 14:19:02 2017
@@ -439,23 +439,32 @@ DWARFCompileUnit *DWARFContext::getCompi
return getCompileUnitForOffset(CUOffset);
}
-static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
- FunctionNameKind Kind,
- std::string &FunctionName) {
- if (Kind == FunctionNameKind::None)
- return false;
+static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
+ uint64_t Address,
+ FunctionNameKind Kind,
+ std::string &FunctionName,
+ uint32_t &StartLine) {
// The address may correspond to instruction in some inlined function,
// so we have to build the chain of inlined functions and take the
- // name of the topmost function in it.SmallVectorImpl<DWARFDie> &InlinedChain
+ // name of the topmost function in it.
SmallVector<DWARFDie, 4> InlinedChain;
CU->getInlinedChainForAddress(Address, InlinedChain);
- if (InlinedChain.size() == 0)
+ if (InlinedChain.empty())
return false;
- if (const char *Name = InlinedChain[0].getSubroutineName(Kind)) {
+
+ const DWARFDie &DIE = InlinedChain[0];
+ bool FoundResult = false;
+ const char *Name = nullptr;
+ if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
FunctionName = Name;
- return true;
+ FoundResult = true;
}
- return false;
+ if (auto DeclLineResult = DIE.getDeclLine()) {
+ StartLine = DeclLineResult;
+ FoundResult = true;
+ }
+
+ return FoundResult;
}
DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
@@ -465,7 +474,9 @@ DILineInfo DWARFContext::getLineInfoForA
DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
if (!CU)
return Result;
- getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
+ getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
+ Result.FunctionName,
+ Result.StartLine);
if (Spec.FLIKind != FileLineInfoKind::None) {
if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
@@ -483,13 +494,16 @@ DWARFContext::getLineInfoForAddressRange
return Lines;
std::string FunctionName = "<invalid>";
- getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
+ uint32_t StartLine = 0;
+ getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
+ StartLine);
// If the Specifier says we don't need FileLineInfo, just
// return the top-most function at the starting address.
if (Spec.FLIKind == FileLineInfoKind::None) {
DILineInfo Result;
Result.FunctionName = FunctionName;
+ Result.StartLine = StartLine;
Lines.push_back(std::make_pair(Address, Result));
return Lines;
}
@@ -510,6 +524,7 @@ DWARFContext::getLineInfoForAddressRange
Result.FunctionName = FunctionName;
Result.Line = Row.Line;
Result.Column = Row.Column;
+ Result.StartLine = StartLine;
Lines.push_back(std::make_pair(Row.Address, Result));
}
@@ -549,6 +564,8 @@ DWARFContext::getInliningInfoForAddress(
// Get function name if necessary.
if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
Frame.FunctionName = Name;
+ if (auto DeclLineResult = FunctionDIE.getDeclLine())
+ Frame.StartLine = DeclLineResult;
if (Spec.FLIKind != FileLineInfoKind::None) {
if (i == 0) {
// For the topmost frame, initialize the line table of this
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=294231&r1=294230&r2=294231&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Mon Feb 6 14:19:02 2017
@@ -291,6 +291,10 @@ DWARFDie::getName(DINameKind Kind) const
return nullptr;
}
+uint64_t DWARFDie::getDeclLine() const {
+ return toUnsigned(findRecursively(DW_AT_decl_line), 0);
+}
+
void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
uint32_t &CallColumn) const {
CallFile = toUnsigned(find(DW_AT_call_file), 0);
Modified: llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp?rev=294231&r1=294230&r2=294231&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp Mon Feb 6 14:19:02 2017
@@ -84,6 +84,8 @@ void DIPrinter::print(const DILineInfo &
return;
}
OS << " Filename: " << Filename << "\n";
+ if (Info.StartLine)
+ OS << "Function start line: " << Info.StartLine << "\n";
OS << " Line: " << Info.Line << "\n";
OS << " Column: " << Info.Column << "\n";
if (Info.Discriminator)
Modified: llvm/trunk/test/tools/llvm-symbolizer/sym-verbose.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/sym-verbose.test?rev=294231&r1=294230&r2=294231&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-symbolizer/sym-verbose.test (original)
+++ llvm/trunk/test/tools/llvm-symbolizer/sym-verbose.test Mon Feb 6 14:19:02 2017
@@ -15,6 +15,7 @@ RUN: llvm-symbolizer -verbose -print-add
#CHECK: 0x4004f2
#CHECK-NEXT: main
#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+#CHECK-NEXT: Function start line: 4
#CHECK-NEXT: Line: 6
#CHECK-NEXT: Column: 7
#CHECK-NOT: Discriminator: 0
@@ -22,6 +23,7 @@ RUN: llvm-symbolizer -verbose -print-add
#CHECK: 0x400509
#CHECK-NEXT: main
#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+#CHECK-NEXT: Function start line: 4
#CHECK-NEXT: Line: 7
#CHECK-NEXT: Column: 3
#CHECK-NEXT: Discriminator: 1
@@ -29,6 +31,7 @@ RUN: llvm-symbolizer -verbose -print-add
#CHECK: 0x40050d
#CHECK-NEXT: main
#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+#CHECK-NEXT: Function start line: 4
#CHECK-NEXT: Line: 7
#CHECK-NEXT: Column: 3
#CHECK-NEXT: Discriminator: 2
More information about the llvm-commits
mailing list