[Lldb-commits] [lldb] r131063 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangExpressionVariable.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp

Sean Callanan scallanan at apple.com
Sat May 7 19:21:26 PDT 2011


Author: spyffe
Date: Sat May  7 21:21:26 2011
New Revision: 131063

URL: http://llvm.org/viewvc/llvm-project?rev=131063&view=rev
Log:
Added support for reading untyped symbols.  Right now
they are treated as pointers of type (void*).  This
allows reading of environ, for instance.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=131063&r1=131062&r2=131063&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Sat May  7 21:21:26 2011
@@ -316,6 +316,10 @@
     /// [Used by IRForTarget] Get the address of a symbol given nothing
     /// but its name.
     ///
+    /// @param[in] target
+    ///     The target to find the symbol in.  If not provided,
+    ///     then the current parsing context's Target.
+    ///
     /// @param[in] name
     ///     The name of the symbol.  
     ///
@@ -326,6 +330,11 @@
     ///     True if the address could be retrieved; false otherwise.
     //------------------------------------------------------------------
     bool 
+    GetSymbolAddress (Target &target,
+                      const ConstString &name,
+                      uint64_t &ptr);
+    
+    bool 
     GetSymbolAddress (const ConstString &name,
                       uint64_t &ptr);
     
@@ -648,6 +657,22 @@
                          TypeFromUser *type = NULL);
     
     //------------------------------------------------------------------
+    /// Given a target, find a data symbol that has the given name.
+    ///
+    /// @param[in] target
+    ///     The target to use as the basis for the search.
+    ///
+    /// @param[in] name
+    ///     The name as a plain C string.
+    ///
+    /// @return
+    ///     The LLDB Symbol found, or NULL if none was found.
+    //---------------------------------------------------------
+    Symbol *
+    FindGlobalDataSymbol (Target &target,
+                          const ConstString &name);
+    
+    //------------------------------------------------------------------
     /// Get the value of a variable in a given execution context and return
     /// the associated Types if needed.
     ///
@@ -699,7 +724,7 @@
     
     //------------------------------------------------------------------
     /// Use the NameSearchContext to generate a Decl for the given
-    /// persistent variable, and put it in the Tuple list.
+    /// persistent variable, and put it in the list of found entities.
     ///
     /// @param[in] context
     ///     The NameSearchContext to use when constructing the Decl.
@@ -712,6 +737,21 @@
                     lldb::ClangExpressionVariableSP &pvar_sp);
     
     //------------------------------------------------------------------
+    /// Use the NameSearchContext to generate a Decl for the given LLDB
+    /// symbol (treated as a variable), and put it in the list of found
+    /// entities.
+    ///
+    /// @param[in] context
+    ///     The NameSearchContext to use when constructing the Decl.
+    ///
+    /// @param[in] var
+    ///     The LLDB Variable that needs a Decl.
+    //------------------------------------------------------------------
+    void
+    AddOneGenericVariable (NameSearchContext &context,
+                           Symbol &symbol);
+    
+    //------------------------------------------------------------------
     /// Use the NameSearchContext to generate a Decl for the given
     /// function.  (Functions are not placed in the Tuple list.)  Can
     /// handle both fully typed functions and generic functions.

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=131063&r1=131062&r2=131063&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Sat May  7 21:21:26 2011
@@ -107,6 +107,7 @@
         llvm::Value            *m_llvm_value;   ///< The IR value corresponding to this variable; usually a GlobalValue
         lldb_private::Value    *m_lldb_value;   ///< The value found in LLDB for this variable
         lldb::VariableSP        m_lldb_var;     ///< The original variable for this variable
+        lldb_private::Symbol   *m_lldb_sym;     ///< The original symbol for this variable, if it was a symbol
 
     private:
         DISALLOW_COPY_AND_ASSIGN (ParserVars);

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=131063&r1=131062&r2=131063&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Sat May  7 21:21:26 2011
@@ -533,19 +533,14 @@
 bool 
 ClangExpressionDeclMap::GetSymbolAddress
 (
+    Target &target,
     const ConstString &name,
     uint64_t &ptr
 )
 {
-    assert (m_parser_vars.get());
-    
-    // Back out in all cases where we're not fully initialized
-    if (m_parser_vars->m_exe_ctx->target == NULL)
-        return false;
-    
     SymbolContextList sc_list;
     
-    m_parser_vars->m_exe_ctx->target->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
+    target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
     
     if (!sc_list.GetSize())
         return false;
@@ -555,11 +550,29 @@
     
     const Address *sym_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
     
-    ptr = sym_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
+    ptr = sym_address->GetLoadAddress(&target);
     
     return true;
 }
 
+bool 
+ClangExpressionDeclMap::GetSymbolAddress
+(
+    const ConstString &name,
+    uint64_t &ptr
+)
+{
+    assert (m_parser_vars.get());
+    
+    if (!m_parser_vars->m_exe_ctx ||
+        !m_parser_vars->m_exe_ctx->target)
+        return false;
+    
+    return GetSymbolAddress(*m_parser_vars->m_exe_ctx->target,
+                            name,
+                            ptr);
+}
+
 // Interface for CommandObjectExpression
 
 bool 
@@ -1225,8 +1238,32 @@
     TypeFromUser type(expr_var->GetTypeFromUser());
     
     VariableSP var = FindVariableInScope (*exe_ctx.frame, name, &type);
+    Symbol *sym = FindGlobalDataSymbol(*exe_ctx.target, name);
     
-    if (!var)
+    std::auto_ptr<lldb_private::Value> location_value;
+    
+    if (var)
+    {
+        location_value.reset(GetVariableValue(exe_ctx,
+                                              var,
+                                              NULL));
+    }
+    else if (sym)
+    {
+        location_value.reset(new Value);
+        
+        uint64_t location_load_addr;
+        
+        if (!GetSymbolAddress(*exe_ctx.target, name, location_load_addr))
+        {
+            if (log)
+                err.SetErrorStringWithFormat("Couldn't find value for global symbol %s", name.GetCString());
+        }
+        
+        location_value->SetValueType(Value::eValueTypeLoadAddress);
+        location_value->GetScalar() = location_load_addr;
+    }
+    else
     {
         err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
         return false;
@@ -1235,9 +1272,6 @@
     if (log)
         log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
     
-    std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
-                                                                       var,
-                                                                       NULL));
     
     if (!location_value.get())
     {
@@ -1627,6 +1661,30 @@
     return var_sp;
 }
 
+Symbol *
+ClangExpressionDeclMap::FindGlobalDataSymbol
+(
+    Target &target,
+    const ConstString &name
+)
+{
+    SymbolContextList sc_list;
+    
+    target.GetImages().FindSymbolsWithNameAndType(name, 
+                                                   eSymbolTypeData, 
+                                                   sc_list);
+    
+    if (sc_list.GetSize())
+    {
+        SymbolContext sym_ctx;
+        sc_list.GetContextAtIndex(0, sym_ctx);
+        
+        return sym_ctx.symbol;
+    }
+    
+    return NULL;
+}
+
 // Interface for ClangASTSource
 void 
 ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
@@ -1677,48 +1735,61 @@
                                                           append, 
                                                           sc_list);
         
-            bool found_specific = false;
-            Symbol *generic_symbol = NULL;
-            Symbol *non_extern_symbol = NULL;
-            
-            for (uint32_t index = 0, num_indices = sc_list.GetSize();
-                 index < num_indices;
-                 ++index)
+            if (sc_list.GetSize())
             {
-                SymbolContext sym_ctx;
-                sc_list.GetContextAtIndex(index, sym_ctx);
-
-                if (sym_ctx.function)
+                bool found_specific = false;
+                Symbol *generic_symbol = NULL;
+                Symbol *non_extern_symbol = NULL;
+                
+                for (uint32_t index = 0, num_indices = sc_list.GetSize();
+                     index < num_indices;
+                     ++index)
                 {
-                    // TODO only do this if it's a C function; C++ functions may be
-                    // overloaded
-                    if (!found_specific)
-                        AddOneFunction(context, sym_ctx.function, NULL);
-                    found_specific = true;
+                    SymbolContext sym_ctx;
+                    sc_list.GetContextAtIndex(index, sym_ctx);
+                    
+                    if (sym_ctx.function)
+                    {
+                        // TODO only do this if it's a C function; C++ functions may be
+                        // overloaded
+                        if (!found_specific)
+                            AddOneFunction(context, sym_ctx.function, NULL);
+                        found_specific = true;
+                    }
+                    else if (sym_ctx.symbol)
+                    {
+                        if (sym_ctx.symbol->IsExternal())
+                            generic_symbol = sym_ctx.symbol;
+                        else
+                            non_extern_symbol = sym_ctx.symbol;
+                    }
                 }
-                else if (sym_ctx.symbol)
+                
+                if (!found_specific)
                 {
-                    if (sym_ctx.symbol->IsExternal())
-                        generic_symbol = sym_ctx.symbol;
-                    else
-                        non_extern_symbol = sym_ctx.symbol;
+                    if (generic_symbol)
+                        AddOneFunction (context, NULL, generic_symbol);
+                    else if (non_extern_symbol)
+                        AddOneFunction (context, NULL, non_extern_symbol);
+                }
+                
+                ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name));
+                if (namespace_decl)
+                {
+                    clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
+                    if (clang_namespace_decl)
+                        clang_namespace_decl->setHasExternalLexicalStorage();
                 }
             }
-        
-            if (!found_specific)
-            {
-                if (generic_symbol)
-                    AddOneFunction (context, NULL, generic_symbol);
-                else if (non_extern_symbol)
-                    AddOneFunction (context, NULL, non_extern_symbol);
-            }
-
-            ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name));
-            if (namespace_decl)
+            else
             {
-                clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
-                if (clang_namespace_decl)
-                    clang_namespace_decl->setHasExternalLexicalStorage();
+                // We couldn't find a variable or function for this.  Now we'll hunt for a generic 
+                // data symbol, and -- if it is found -- treat it as a variable.
+                
+                Symbol *data_symbol = FindGlobalDataSymbol(*m_parser_vars->m_exe_ctx->target, name);
+                
+                if (data_symbol)
+                    AddOneGenericVariable(context, *data_symbol);
             }
         }
     }
@@ -2060,6 +2131,68 @@
 }
 
 void
+ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, 
+                                              Symbol &symbol)
+{
+    assert(m_parser_vars.get());
+    
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    clang::ASTContext *scratch_ast_context = m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext();
+    
+    TypeFromUser user_type (ClangASTContext::GetVoidPtrType(scratch_ast_context, false),
+                            scratch_ast_context);
+    
+    TypeFromParser parser_type (ClangASTContext::GetVoidPtrType(context.GetASTContext(), false),
+                                context.GetASTContext());
+    
+    NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType()));
+    
+    std::string decl_name(context.m_decl_name.getAsString());
+    ConstString entity_name(decl_name.c_str());
+    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope (),
+                                                                      entity_name, 
+                                                                      user_type,
+                                                                      m_parser_vars->m_exe_ctx->process->GetByteOrder(),
+                                                                      m_parser_vars->m_exe_ctx->process->GetAddressByteSize()));
+    assert (entity.get());
+    entity->EnableParserVars();
+    
+    std::auto_ptr<Value> symbol_location(new Value);
+    
+    AddressRange &symbol_range = symbol.GetAddressRangeRef();
+    Address &symbol_address = symbol_range.GetBaseAddress();
+    lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(m_parser_vars->m_exe_ctx->target);
+    
+    symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
+    symbol_location->GetScalar() = symbol_load_addr;
+    symbol_location->SetValueType(Value::eValueTypeLoadAddress);
+    
+    entity->m_parser_vars->m_parser_type = parser_type;
+    entity->m_parser_vars->m_named_decl  = var_decl;
+    entity->m_parser_vars->m_llvm_value  = NULL;
+    entity->m_parser_vars->m_lldb_value  = symbol_location.release();
+    entity->m_parser_vars->m_lldb_sym    = &symbol;
+    
+    if (log)
+    {
+        std::string var_decl_print_string;
+        llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
+        var_decl->print(var_decl_print_stream);
+        var_decl_print_stream.flush();
+        
+        log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str());
+        
+        if (log->GetVerbose())
+        {
+            StreamString var_decl_dump_string;
+            ASTDumper::DumpDecl(var_decl_dump_string, var_decl);
+            log->Printf("%s\n", var_decl_dump_string.GetData());
+        }
+    }
+}
+
+void
 ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
                                         const RegisterInfo *reg_info)
 {

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=131063&r1=131062&r2=131063&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Sat May  7 21:21:26 2011
@@ -1295,7 +1295,7 @@
 bool
 IRForTarget::HandleSymbol (Module &llvm_module,
                            Value *symbol)
-{
+{    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     lldb_private::ConstString name(symbol->getName().str().c_str());





More information about the lldb-commits mailing list