[Lldb-commits] [lldb] r226084 - Modified LLDB to be able to lookup global variables by address.
Greg Clayton
gclayton at apple.com
Wed Jan 14 18:59:20 PST 2015
Author: gclayton
Date: Wed Jan 14 20:59:20 2015
New Revision: 226084
URL: http://llvm.org/viewvc/llvm-project?rev=226084&view=rev
Log:
Modified LLDB to be able to lookup global variables by address.
This is done by adding a "Variable *" to SymbolContext and allowing SymbolFile::ResolveSymbolContext() so if an address is resolved into a symbol context, we can include the global or static variable for that address.
This means you can now find global variables that are merged globals when doing a "image lookup --verbose --address 0x1230000". Previously we would resolve a symbol and show "_MergedGlobals123 + 1234". But now we can show the global variable name.
The eSymbolContextEverything purposely does not include the new eSymbolContextVariable in its lookup since stack frame code does many lookups and we don't want it triggering the global variable lookups.
<rdar://problem/18945678>
Modified:
lldb/trunk/include/lldb/Symbol/SymbolContext.h
lldb/trunk/include/lldb/lldb-enumerations.h
lldb/trunk/source/Commands/CommandObjectTarget.cpp
lldb/trunk/source/Core/Address.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/trunk/source/Symbol/SymbolContext.cpp
lldb/trunk/source/Symbol/Variable.cpp
Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Wed Jan 14 20:59:20 2015
@@ -347,6 +347,7 @@ public:
Block * block; ///< The Block for a given query
LineEntry line_entry; ///< The LineEntry for a given query
Symbol * symbol; ///< The Symbol for a given query
+ Variable * variable; ///< The global variable matching the given query
};
Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Jan 14 20:59:20 2015
@@ -290,7 +290,11 @@ namespace lldb {
eSymbolContextBlock = (1u << 4), ///< Set when the deepest \a block is requested from a query, or was located in query results
eSymbolContextLineEntry = (1u << 5), ///< Set when \a line_entry is requested from a query, or was located in query results
eSymbolContextSymbol = (1u << 6), ///< Set when \a symbol is requested from a query, or was located in query results
- eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u) ///< Indicates to try and lookup everything up during a query.
+ eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u), ///< Indicates to try and lookup everything up during a routine symbol context query.
+ eSymbolContextVariable = (1u << 7) ///< Set when \a global or static variable is requested from a query, or was located in query results.
+ ///< eSymbolContextVariable is potentially expensive to lookup so it isn't included in
+ ///< eSymbolContextEverything which stops it from being used during frame PC lookups and
+ ///< many other potential address to symbol context lookups.
} SymbolContextItem;
typedef enum Permissions
Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Wed Jan 14 20:59:20 2015
@@ -4078,7 +4078,7 @@ public:
if (LookupAddressInModule (m_interpreter,
result.GetOutputStream(),
module,
- eSymbolContextEverything,
+ eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0),
m_options.m_addr,
m_options.m_offset,
m_options.m_verbose))
Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Wed Jan 14 20:59:20 2015
@@ -654,7 +654,7 @@ Address::Dump (Stream *s, ExecutionConte
if (module_sp)
{
SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
+ module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
if (sc.function || sc.symbol)
{
bool show_stop_context = true;
@@ -712,7 +712,7 @@ Address::Dump (Stream *s, ExecutionConte
if (module_sp)
{
SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
+ module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
if (sc.symbol)
{
// If we have just a symbol make sure it is in the same section
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Jan 14 20:59:20 2015
@@ -2786,6 +2786,59 @@ SymbolFileDWARF::GetFunction (DWARFCompi
return false;
}
+
+
+SymbolFileDWARF::GlobalVariableMap &
+SymbolFileDWARF::GetGlobalAranges()
+{
+ if (!m_global_aranges_ap)
+ {
+ m_global_aranges_ap.reset (new GlobalVariableMap());
+
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ if (module_sp)
+ {
+ const size_t num_cus = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_cus; ++i)
+ {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
+ if (cu_sp)
+ {
+ VariableListSP globals_sp = cu_sp->GetVariableList(true);
+ if (globals_sp)
+ {
+ const size_t num_globals = globals_sp->GetSize();
+ for (size_t g = 0; g < num_globals; ++g)
+ {
+ VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
+ if (var_sp && !var_sp->GetLocationIsConstantValueData())
+ {
+ const DWARFExpression &location = var_sp->LocationExpression();
+ Value location_result;
+ Error error;
+ if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
+ {
+ if (location_result.GetValueType() == Value::eValueTypeFileAddress)
+ {
+ lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
+ lldb::addr_t byte_size = 1;
+ if (var_sp->GetType())
+ byte_size = var_sp->GetType()->GetByteSize();
+ m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ m_global_aranges_ap->Sort();
+ }
+ return *m_global_aranges_ap;
+}
+
+
uint32_t
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
@@ -2794,10 +2847,11 @@ SymbolFileDWARF::ResolveSymbolContext (c
static_cast<void*>(so_addr.GetSection().get()),
so_addr.GetOffset(), resolve_scope);
uint32_t resolved = 0;
- if (resolve_scope & ( eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextBlock |
- eSymbolContextLineEntry))
+ if (resolve_scope & ( eSymbolContextCompUnit |
+ eSymbolContextFunction |
+ eSymbolContextBlock |
+ eSymbolContextLineEntry |
+ eSymbolContextVariable ))
{
lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
@@ -2805,7 +2859,30 @@ SymbolFileDWARF::ResolveSymbolContext (c
if (debug_info)
{
const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
- if (cu_offset != DW_INVALID_OFFSET)
+ if (cu_offset == DW_INVALID_OFFSET)
+ {
+ // Global variables are not in the compile unit address ranges. The only way to
+ // currently find global variables is to iterate over the .debug_pubnames or the
+ // __apple_names table and find all items in there that point to DW_TAG_variable
+ // DIEs and then find the address that matches.
+ if (resolve_scope & eSymbolContextVariable)
+ {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data)
+ {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc)
+ {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
+ }
+ return sc.GetResolvedMask();
+ }
+ }
+ }
+ else
{
uint32_t cu_idx = DW_INVALID_INDEX;
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Wed Jan 14 20:59:20 2015
@@ -29,6 +29,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -557,6 +558,11 @@ protected:
uint32_t type_mask,
TypeSet &type_set);
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap;
+
+ GlobalVariableMap &
+ GetGlobalAranges();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
@@ -584,6 +590,7 @@ protected:
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
NameToDIE m_function_basename_index; // All concrete functions
NameToDIE m_function_fullname_index; // All concrete functions
NameToDIE m_function_method_index; // All inlined functions
Modified: lldb/trunk/source/Symbol/SymbolContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolContext.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolContext.cpp Wed Jan 14 20:59:20 2015
@@ -21,6 +21,7 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Target.h"
using namespace lldb;
@@ -33,7 +34,8 @@ SymbolContext::SymbolContext() :
function (nullptr),
block (nullptr),
line_entry (),
- symbol (nullptr)
+ symbol (nullptr),
+ variable (nullptr)
{
}
@@ -44,7 +46,8 @@ SymbolContext::SymbolContext(const Modul
function (f),
block (b),
line_entry (),
- symbol (s)
+ symbol (s),
+ variable (nullptr)
{
if (le)
line_entry = *le;
@@ -57,7 +60,8 @@ SymbolContext::SymbolContext(const Targe
function (f),
block (b),
line_entry (),
- symbol (s)
+ symbol (s),
+ variable (nullptr)
{
if (le)
line_entry = *le;
@@ -70,7 +74,8 @@ SymbolContext::SymbolContext(const Symbo
function (rhs.function),
block (rhs.block),
line_entry (rhs.line_entry),
- symbol (rhs.symbol)
+ symbol (rhs.symbol),
+ variable (rhs.variable)
{
}
@@ -82,7 +87,8 @@ SymbolContext::SymbolContext (SymbolCont
function (nullptr),
block (nullptr),
line_entry (),
- symbol (nullptr)
+ symbol (nullptr),
+ variable (nullptr)
{
sc_scope->CalculateSymbolContext (this);
}
@@ -103,6 +109,7 @@ SymbolContext::operator= (const SymbolCo
block = rhs.block;
line_entry = rhs.line_entry;
symbol = rhs.symbol;
+ variable = rhs.variable;
}
return *this;
}
@@ -118,6 +125,7 @@ SymbolContext::Clear(bool clear_target)
block = nullptr;
line_entry.Clear();
symbol = nullptr;
+ variable = nullptr;
}
bool
@@ -309,6 +317,37 @@ SymbolContext::GetDescription(Stream *s,
symbol->GetDescription(s, level, target);
s->EOL();
}
+
+ if (variable != nullptr)
+ {
+ s->Indent(" Variable: ");
+
+ s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
+
+ switch (variable->GetScope())
+ {
+ case eValueTypeVariableGlobal:
+ s->PutCString("kind = global, ");
+ break;
+
+ case eValueTypeVariableStatic:
+ s->PutCString("kind = static, ");
+ break;
+
+ case eValueTypeVariableArgument:
+ s->PutCString("kind = argument, ");
+ break;
+
+ case eValueTypeVariableLocal:
+ s->PutCString("kind = local, ");
+ break;
+
+ default:
+ break;
+ }
+
+ s->Printf ("name = \"%s\"\n", variable->GetName().GetCString());
+ }
}
uint32_t
@@ -322,6 +361,7 @@ SymbolContext::GetResolvedMask () const
if (block) resolved_mask |= eSymbolContextBlock;
if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
if (symbol) resolved_mask |= eSymbolContextSymbol;
+ if (variable) resolved_mask |= eSymbolContextVariable;
return resolved_mask;
}
@@ -377,6 +417,12 @@ SymbolContext::Dump(Stream *s, Target *t
if (symbol != nullptr && symbol->GetMangled())
*s << ' ' << symbol->GetMangled().GetName().AsCString();
s->EOL();
+ *s << "Variable = " << (void *)variable;
+ if (variable != nullptr)
+ {
+ *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName();
+ s->EOL();
+ }
s->IndentLess();
s->IndentLess();
}
@@ -389,7 +435,8 @@ lldb_private::operator== (const SymbolCo
&& lhs.module_sp.get() == rhs.module_sp.get()
&& lhs.comp_unit == rhs.comp_unit
&& lhs.target_sp.get() == rhs.target_sp.get()
- && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
+ && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0
+ && lhs.variable == rhs.variable;
}
bool
@@ -400,7 +447,8 @@ lldb_private::operator!= (const SymbolCo
|| lhs.module_sp.get() != rhs.module_sp.get()
|| lhs.comp_unit != rhs.comp_unit
|| lhs.target_sp.get() != rhs.target_sp.get()
- || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
+ || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0
+ || lhs.variable != rhs.variable;
}
bool
Modified: lldb/trunk/source/Symbol/Variable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Variable.cpp?rev=226084&r1=226083&r2=226084&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Variable.cpp (original)
+++ lldb/trunk/source/Symbol/Variable.cpp Wed Jan 14 20:59:20 2015
@@ -203,7 +203,10 @@ void
Variable::CalculateSymbolContext (SymbolContext *sc)
{
if (m_owner_scope)
+ {
m_owner_scope->CalculateSymbolContext(sc);
+ sc->variable = this;
+ }
else
sc->Clear(false);
}
More information about the lldb-commits
mailing list