summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2017-02-06 20:19:02 +0000
committerDavid Blaikie <dblaikie@gmail.com>2017-02-06 20:19:02 +0000
commitefc4eba816264a4e109b4ee49ffb38ba1ae1a1a8 (patch)
tree7d60a8b375d26e0682eea6a9e5b1c7525748b7f8 /llvm/lib/DebugInfo/DWARF
parent1b4eed4c1e11ea5f51b00ad18cbc45c4169ba8a4 (diff)
downloadbcm5719-llvm-efc4eba816264a4e109b4ee49ffb38ba1ae1a1a8.tar.gz
bcm5719-llvm-efc4eba816264a4e109b4ee49ffb38ba1ae1a1a8.zip
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 llvm-svn: 294231
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp41
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp4
2 files changed, 33 insertions, 12 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index ab9f76a0bd5..4d620915b3d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -439,23 +439,32 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
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::getLineInfoForAddress(uint64_t Address,
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(uint64_t Address, uint64_t Size,
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(uint64_t Address, uint64_t Size,
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(uint64_t Address,
// 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
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 9a05ae8d38a..6949366323b 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -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);
OpenPOWER on IntegriCloud