forked from OSchip/llvm-project
Improve detection of global vs local variables
Summary: Improve detection of global vs local variables. Currently when a global variable is optimized out or otherwise has an unknown location (DW_AT_location is empty) it gets reported as local. I added two new heuristics: - if a mangled name is present, the variable is global (or static) - if DW_AT_location is present but invalid, the variable is global (or static) Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D26908 llvm-svn: 287636
This commit is contained in:
parent
72e43570b7
commit
30621391bc
|
@ -3873,6 +3873,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
||||||
const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
|
const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
|
||||||
SymbolContextScope *symbol_context_scope = NULL;
|
SymbolContextScope *symbol_context_scope = NULL;
|
||||||
|
|
||||||
|
bool has_explicit_mangled = mangled != nullptr;
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
// LLDB relies on the mangled name (DW_TAG_linkage_name or
|
// LLDB relies on the mangled name (DW_TAG_linkage_name or
|
||||||
// DW_AT_MIPS_linkage_name) to
|
// DW_AT_MIPS_linkage_name) to
|
||||||
|
@ -3894,23 +3895,24 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DWARF doesn't specify if a DW_TAG_variable is a local, global
|
|
||||||
// or static variable, so we have to do a little digging by
|
|
||||||
// looking at the location of a variable to see if it contains
|
|
||||||
// a DW_OP_addr opcode _somewhere_ in the definition. I say
|
|
||||||
// somewhere because clang likes to combine small global variables
|
|
||||||
// into the same symbol and have locations like:
|
|
||||||
// DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
|
|
||||||
// So if we don't have a DW_TAG_formal_parameter, we can look at
|
|
||||||
// the location to see if it contains a DW_OP_addr opcode, and
|
|
||||||
// then we can correctly classify our variables.
|
|
||||||
if (tag == DW_TAG_formal_parameter)
|
if (tag == DW_TAG_formal_parameter)
|
||||||
scope = eValueTypeVariableArgument;
|
scope = eValueTypeVariableArgument;
|
||||||
else {
|
else {
|
||||||
bool op_error = false;
|
// DWARF doesn't specify if a DW_TAG_variable is a local, global
|
||||||
|
// or static variable, so we have to do a little digging:
|
||||||
|
// 1) DW_AT_linkage_name implies static lifetime (but may be missing)
|
||||||
|
// 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
|
||||||
|
// 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
|
||||||
|
// Clang likes to combine small global variables into the same symbol
|
||||||
|
// with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
|
||||||
|
// so we need to look through the whole expression.
|
||||||
|
bool is_static_lifetime =
|
||||||
|
has_explicit_mangled ||
|
||||||
|
(has_explicit_location && !location.IsValid());
|
||||||
// Check if the location has a DW_OP_addr with any address value...
|
// Check if the location has a DW_OP_addr with any address value...
|
||||||
lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
|
lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
|
||||||
if (!location_is_const_value_data) {
|
if (!location_is_const_value_data) {
|
||||||
|
bool op_error = false;
|
||||||
location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
|
location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
|
||||||
if (op_error) {
|
if (op_error) {
|
||||||
StreamString strm;
|
StreamString strm;
|
||||||
|
@ -3920,10 +3922,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
||||||
"0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
|
"0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
|
||||||
die.GetTagAsCString(), strm.GetData());
|
die.GetTagAsCString(), strm.GetData());
|
||||||
}
|
}
|
||||||
|
if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
|
||||||
|
is_static_lifetime = true;
|
||||||
}
|
}
|
||||||
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
|
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
|
||||||
|
|
||||||
if (location_DW_OP_addr != LLDB_INVALID_ADDRESS) {
|
if (is_static_lifetime) {
|
||||||
if (is_external)
|
if (is_external)
|
||||||
scope = eValueTypeVariableGlobal;
|
scope = eValueTypeVariableGlobal;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue