[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