Improve behavior of DebugInfoEntryMinimal::getSubprogramName() introduced in r159512.

To fetch a subprogram name we should not only inspect the DIE for this subprogram, but optionally inspect
its specification, or its abstract origin (even if there is no inlining), or even specification of an abstract origin.

Reviewed by Benjamin Kramer.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160365 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alexey Samsonov
2012-07-17 15:28:35 +00:00
parent 4f0c69623c
commit 9d26b0ba06
6 changed files with 41 additions and 29 deletions

View File

@@ -155,8 +155,10 @@ DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address,
if (specifier.needs(DILineInfoSpecifier::FunctionName)) { if (specifier.needs(DILineInfoSpecifier::FunctionName)) {
const DWARFDebugInfoEntryMinimal *function_die = const DWARFDebugInfoEntryMinimal *function_die =
cu->getFunctionDIEForAddress(address); cu->getFunctionDIEForAddress(address);
if (function_die) if (function_die) {
functionName = function_die->getSubprogramName(cu); if (const char *name = function_die->getSubprogramName(cu))
functionName = name;
}
} }
if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) { if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
// Get the line table for this compile unit. // Get the line table for this compile unit.

View File

@@ -456,35 +456,38 @@ DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
return false; return false;
} }
static inline const char*
getSubprogramNameFromDie(const DWARFCompileUnit *cu,
const DWARFDebugInfoEntryMinimal *die) {
const char *result = 0;
if (!die->isNULL() && die->getTag() == DW_TAG_subprogram) {
// Try to get mangled name if possible.
result = die->getAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, 0);
if (result == 0)
result = die->getAttributeValueAsString(cu, DW_AT_linkage_name, 0);
if (result == 0)
result = die->getAttributeValueAsString(cu, DW_AT_name, 0);
}
return result;
}
const char* const char*
DWARFDebugInfoEntryMinimal::getSubprogramName( DWARFDebugInfoEntryMinimal::getSubprogramName(
const DWARFCompileUnit *cu) const { const DWARFCompileUnit *cu) const {
if (isNULL() || getTag() != DW_TAG_subprogram) if (isNULL() || getTag() != DW_TAG_subprogram)
return 0; return 0;
const char *name = getSubprogramNameFromDie(cu, this); // Try to get mangled name if possible.
if (name == 0) { if (const char *name =
// Try to get name from specification DIE. getAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, 0))
uint32_t ref = getAttributeValueAsReference(cu, DW_AT_specification, -1U); return name;
if (ref != -1U) { if (const char *name = getAttributeValueAsString(cu, DW_AT_linkage_name, 0))
DWARFDebugInfoEntryMinimal spec_die; return name;
if (spec_die.extract(cu, &ref)) if (const char *name = getAttributeValueAsString(cu, DW_AT_name, 0))
name = getSubprogramNameFromDie(cu, &spec_die); return name;
// Try to get name from specification DIE.
uint32_t spec_ref =
getAttributeValueAsReference(cu, DW_AT_specification, -1U);
if (spec_ref != -1U) {
DWARFDebugInfoEntryMinimal spec_die;
if (spec_die.extract(cu, &spec_ref)) {
if (const char *name = spec_die.getSubprogramName(cu))
return name;
} }
} }
return name; // Try to get name from abstract origin DIE.
uint32_t abs_origin_ref =
getAttributeValueAsReference(cu, DW_AT_abstract_origin, -1U);
if (abs_origin_ref != -1U) {
DWARFDebugInfoEntryMinimal abs_origin_die;
if (abs_origin_die.extract(cu, &abs_origin_ref)) {
if (const char *name = abs_origin_die.getSubprogramName(cu))
return name;
}
}
return 0;
} }

View File

@@ -132,8 +132,10 @@ public:
bool addressRangeContainsAddress(const DWARFCompileUnit *cu, bool addressRangeContainsAddress(const DWARFCompileUnit *cu,
const uint64_t address) const; const uint64_t address) const;
// If a DIE represents a subroutine, returns its mangled name // If a DIE represents a subprogram, returns its mangled name
// (or short name, if mangled is missing). Otherwise returns null. // (or short name, if mangled is missing). This name may be fetched
// from specification or abstract origin for this subprogram.
// Returns null if no name is found.
const char* getSubprogramName(const DWARFCompileUnit *cu) const; const char* getSubprogramName(const DWARFCompileUnit *cu) const;
}; };

Binary file not shown.

View File

@@ -8,6 +8,8 @@ RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test2.elf-x86-64 \
RUN: --address=0x4004b8 --functions | FileCheck %s -check-prefix MANY_CU_1 RUN: --address=0x4004b8 --functions | FileCheck %s -check-prefix MANY_CU_1
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test2.elf-x86-64 \ RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test2.elf-x86-64 \
RUN: --address=0x4004c4 --functions | FileCheck %s -check-prefix MANY_CU_2 RUN: --address=0x4004c4 --functions | FileCheck %s -check-prefix MANY_CU_2
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test3.elf-x86-64 \
RUN: --address=0x538 --functions | FileCheck %s -check-prefix ABS_ORIGIN_1
MAIN: main MAIN: main
MAIN-NEXT: dwarfdump-test.cc:16:10 MAIN-NEXT: dwarfdump-test.cc:16:10
@@ -23,3 +25,6 @@ MANY_CU_1-NEXT: a.cc:2:0
MANY_CU_2: main MANY_CU_2: main
MANY_CU_2-NEXT: main.cc:4:0 MANY_CU_2-NEXT: main.cc:4:0
ABS_ORIGIN_1: C
ABS_ORIGIN_1-NEXT: def.cc:3:0

View File

@@ -1 +1 @@
config.suffixes = ['.ll', '.c', '.cpp'] config.suffixes = ['.ll', '.c', '.cpp', '.test']