[Lldb-commits] [lldb] r261704 - When looking for symbols, find load addresses in a more robust way.

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 23 15:09:07 PST 2016


Author: spyffe
Date: Tue Feb 23 17:09:06 2016
New Revision: 261704

URL: http://llvm.org/viewvc/llvm-project?rev=261704&view=rev
Log:
When looking for symbols, find load addresses in a more robust way.

IRExecutionUnit previously replicated a bunch of logic that already
existed elsewhere for the purpose of getting a load address for a
symbol.  This approach failed to resolve certain types of symbols.
Instead, we now use functions on SymbolContext to do the address
resolution.

This is a cleanup of IRExecutionUnit::FindInSymbols, and also fixes a
latent bug where we looked at the wrong SymbolContext to determine
whether or not it is external.

<rdar://problem/24770829>

Modified:
    lldb/trunk/source/Expression/IRExecutionUnit.cpp

Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?rev=261704&r1=261703&r2=261704&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRExecutionUnit.cpp (original)
+++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Tue Feb 23 17:09:06 2016
@@ -769,9 +769,62 @@ IRExecutionUnit::CollectCandidateCPlusPl
 lldb::addr_t
 IRExecutionUnit::FindInSymbols(const std::vector<IRExecutionUnit::SearchSpec> &specs, const lldb_private::SymbolContext &sc)
 {
+    Target *target = sc.target_sp.get();
+
+    if (!target)
+    {
+        // we shouldn't be doing any symbol lookup at all without a target
+        return LLDB_INVALID_ADDRESS;
+    }
+
     for (const SearchSpec &spec : specs)
     {
         SymbolContextList sc_list;
+
+        lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
+
+        std::function<bool (lldb::addr_t &, SymbolContextList &, const lldb_private::SymbolContext &)> get_external_load_address =
+            [&best_internal_load_address, target](lldb::addr_t &load_address,
+                                                  SymbolContextList &sc_list,
+                                                  const lldb_private::SymbolContext &sc) -> lldb::addr_t
+        {
+            load_address = LLDB_INVALID_ADDRESS;
+
+            for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si)
+            {
+                SymbolContext candidate_sc;
+
+                sc_list.GetContextAtIndex(si, candidate_sc);
+
+                const bool is_external = (candidate_sc.function) ||
+                                         (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
+
+                AddressRange range;
+
+                if (candidate_sc.GetAddressRange(lldb::eSymbolContextFunction | lldb::eSymbolContextSymbol,
+                                                 0,
+                                                 false,
+                                                 range))
+                {
+                    load_address = range.GetBaseAddress().GetCallableLoadAddress(target);
+
+                    if (load_address != LLDB_INVALID_ADDRESS)
+                    {
+                        if (is_external)
+                        {
+                            return true;
+                        }
+                        else if (best_internal_load_address == LLDB_INVALID_ADDRESS)
+                        {
+                            best_internal_load_address = load_address;
+                            load_address = LLDB_INVALID_ADDRESS;
+                        }
+                    }
+                }
+            }
+
+            return false;
+        };
         
         if (sc.module_sp)
         {
@@ -783,6 +836,17 @@ IRExecutionUnit::FindInSymbols(const std
                                         true,  // append
                                         sc_list);
         }
+
+        lldb::addr_t load_address = LLDB_INVALID_ADDRESS;
+
+        if (get_external_load_address(load_address, sc_list, sc))
+        {
+            return load_address;
+        }
+        else
+        {
+            sc_list.Clear();
+        }
     
         if (sc_list.GetSize() == 0 && sc.target_sp)
         {
@@ -794,49 +858,26 @@ IRExecutionUnit::FindInSymbols(const std
                                                     sc_list);
         }
         
+        if (get_external_load_address(load_address, sc_list, sc))
+        {
+            return load_address;
+        }
+        else
+        {
+            sc_list.Clear();
+        }
+
         if (sc_list.GetSize() == 0 && sc.target_sp)
         {
             sc.target_sp->GetImages().FindSymbolsWithNameAndType(spec.name, lldb::eSymbolTypeAny, sc_list);
         }
 
-        lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
-        
-        for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si)
+        if (get_external_load_address(load_address, sc_list, sc))
         {
-            bool is_external = false;
-            
-            SymbolContext candidate_sc;
-            
-            sc_list.GetContextAtIndex(si, candidate_sc);
-            if (candidate_sc.function)
-            {
-                is_external = true;
-            }
-            else if (sc.symbol)
-            {
-                if (sc.symbol->IsExternal())
-                {
-                    is_external = true;
-                }
-            }
-            
-            lldb::addr_t load_address = candidate_sc.symbol->ResolveCallableAddress(*sc.target_sp);
-            
-            if (load_address == LLDB_INVALID_ADDRESS)
-                load_address = candidate_sc.symbol->GetAddress().GetLoadAddress(sc.target_sp.get());
-
-            if (load_address != LLDB_INVALID_ADDRESS)
-            {
-                if (is_external)
-                {
-                    return load_address;
-                }
-                else
-                {
-                    best_internal_load_address = load_address;
-                }
-            }
+            return load_address;
         }
+        // if there are any searches we try after this, add an sc_list.Clear() in an "else" clause here
+
         if (best_internal_load_address != LLDB_INVALID_ADDRESS)
         {
             return best_internal_load_address;




More information about the lldb-commits mailing list