[Lldb-commits] [lldb] r144981 - in /lldb/trunk: include/lldb/Core/ModuleList.h include/lldb/Target/DynamicLoader.h source/Core/ModuleList.cpp source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h

Jim Ingham jingham at apple.com
Fri Nov 18 16:19:25 PST 2011


Author: jingham
Date: Fri Nov 18 18:19:25 2011
New Revision: 144981

URL: http://llvm.org/viewvc/llvm-project?rev=144981&view=rev
Log:
Handle stepping through a trampoline where the jump target is calculated a runtime - and so doesn't match
the name of the PLT entry.  This solution assumes a naming convention agreed upon by us and the system folks,
and isn't general.  The general solution requires actually finding & calling the resolver function if it
hasn't been called yet.  That's more tricky.

Modified:
    lldb/trunk/include/lldb/Core/ModuleList.h
    lldb/trunk/include/lldb/Target/DynamicLoader.h
    lldb/trunk/source/Core/ModuleList.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h

Modified: lldb/trunk/include/lldb/Core/ModuleList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleList.h?rev=144981&r1=144980&r2=144981&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ModuleList.h (original)
+++ lldb/trunk/include/lldb/Core/ModuleList.h Fri Nov 18 18:19:25 2011
@@ -296,8 +296,15 @@
     size_t
     FindSymbolsWithNameAndType (const ConstString &name,
                                 lldb::SymbolType symbol_type,
-                                SymbolContextList &sc_list);
+                                SymbolContextList &sc_list,
+                                bool append = false);
 
+    size_t
+    FindSymbolsMatchingRegExAndType (const RegularExpression &regex, 
+                                     lldb::SymbolType symbol_type, 
+                                     SymbolContextList &sc_list,
+                                     bool append = false);
+                                     
     //------------------------------------------------------------------
     /// Find types by name.
     ///

Modified: lldb/trunk/include/lldb/Target/DynamicLoader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/DynamicLoader.h?rev=144981&r1=144980&r2=144981&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/DynamicLoader.h (original)
+++ lldb/trunk/include/lldb/Target/DynamicLoader.h Fri Nov 18 18:19:25 2011
@@ -143,6 +143,31 @@
 
 
     //------------------------------------------------------------------
+    /// Some dynamic loaders provide features where there are a group of symbols "equivalent to"
+    /// a given symbol one of which will be chosen when the symbol is bound.  If you want to
+    /// set a breakpoint on one of these symbols, you really need to set it on all the
+    /// equivalent symbols.
+    ///
+    ///
+    /// @param[in] original_symbol
+    ///     The symbol for which we are finding equivalences.
+    ///
+    /// @param[in] module_list
+    ///     The set of modules in which to search.
+    ///
+    /// @param[out] equivalent_symbols
+    ///     The equivalent symbol list - any equivalent symbols found are appended to this list.
+    ///
+    /// @return
+    ///    Number of equivalent symbols found.
+    //------------------------------------------------------------------
+    virtual size_t
+    FindEquivalentSymbols (Symbol *original_symbol, ModuleList &module_list, SymbolContextList &equivalent_symbols)
+    {
+        return 0;
+    }
+    
+    //------------------------------------------------------------------
     /// Ask if it is ok to try and load or unload an shared library 
     /// (image).
     ///

Modified: lldb/trunk/source/Core/ModuleList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=144981&r1=144980&r2=144981&view=diff
==============================================================================
--- lldb/trunk/source/Core/ModuleList.cpp (original)
+++ lldb/trunk/source/Core/ModuleList.cpp Fri Nov 18 18:19:25 2011
@@ -248,14 +248,35 @@
 size_t
 ModuleList::FindSymbolsWithNameAndType (const ConstString &name, 
                                         SymbolType symbol_type, 
-                                        SymbolContextList &sc_list)
+                                        SymbolContextList &sc_list,
+                                        bool append)
 {
     Mutex::Locker locker(m_modules_mutex);
-    sc_list.Clear();
+    if (!append)
+        sc_list.Clear();
+    size_t initial_size = sc_list.GetSize();
+    
     collection::iterator pos, end = m_modules.end();
     for (pos = m_modules.begin(); pos != end; ++pos)
         (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list);
-    return sc_list.GetSize();
+    return sc_list.GetSize() - initial_size;
+}
+
+    size_t
+ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, 
+                                             lldb::SymbolType symbol_type, 
+                                             SymbolContextList &sc_list,
+                                             bool append)
+{
+    Mutex::Locker locker(m_modules_mutex);
+    if (!append)
+        sc_list.Clear();
+    size_t initial_size = sc_list.GetSize();
+    
+    collection::iterator pos, end = m_modules.end();
+    for (pos = m_modules.begin(); pos != end; ++pos)
+        (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list);
+    return sc_list.GetSize() - initial_size;
 }
 
 class ModuleMatches

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=144981&r1=144980&r2=144981&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Fri Nov 18 18:19:25 2011
@@ -1423,6 +1423,14 @@
     }
 }
 
+// This bit in the n_desc field of the mach file means that this is a
+// stub that runs arbitrary code to determine the trampoline target.
+// We've established a naming convention with the CoreOS folks for the
+// equivalent symbols they will use for this (which the objc guys didn't follow...) 
+// For now we'll just look for all symbols matching that naming convention...
+
+#define MACH_O_N_SYMBOL_RESOLVER 0x100
+
 ThreadPlanSP
 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
 {
@@ -1442,46 +1450,75 @@
             {
                 SymbolContextList target_symbols;
                 ModuleList &images = thread.GetProcess().GetTarget().GetImages();
+                
                 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
-                // FIXME - Make the Run to Address take multiple addresses, and
-                // run to any of them.
-                uint32_t num_symbols = target_symbols.GetSize();
-                if (num_symbols == 1)
+
+                size_t num_original_symbols = target_symbols.GetSize();
+                bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
+                
+                if (num_original_symbols > 0)
                 {
-                    SymbolContext context;
-                    AddressRange addr_range;
-                    if (target_symbols.GetContextAtIndex(0, context))
+                    // We found symbols that look like they are the targets to our symbol.  Now look through the
+                    // modules containing our symbols to see if there are any for our symbol.  
+                    
+                    ModuleList modules_to_search;
+                    
+                    for (size_t i = 0; i < num_original_symbols; i++)
                     {
-                        context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
-                        thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others));
+                        SymbolContext sc;
+                        target_symbols.GetContextAtIndex(i, sc);
+                        
+                        Module* module_to_add = sc.symbol->CalculateSymbolContextModule();
+                        if (module_to_add)
+                             modules_to_search.AppendIfNeeded(static_cast<ModuleSP>(module_to_add));
                     }
-                    else
+                    
+                    // If the original stub symbol is a resolver, then we don't want to break on the symbol with the
+                    // original name, but instead on all the symbols it could resolve to since otherwise we would stop 
+                    // in the middle of the resolution...
+                    // Note that the stub is not of the resolver type it will point to the equivalent symbol,
+                    // not the original name, so in that case we don't need to do anything.
+                    
+                    if (orig_is_resolver)
                     {
-                        if (log)
-                            log->Printf ("Couldn't resolve the symbol context.");
+                        target_symbols.Clear();
+                        
+                        FindEquivalentSymbols (current_symbol, modules_to_search, target_symbols);
                     }
-                }
-                else if (num_symbols > 1)
-                {
-                    std::vector<lldb::addr_t>  addresses;
-                    addresses.resize (num_symbols);
-                    for (uint32_t i = 0; i < num_symbols; i++)
+                                            
+                    // FIXME - Make the Run to Address take multiple addresses, and
+                    // run to any of them.
+                    uint32_t num_symbols = target_symbols.GetSize();
+                    if (num_symbols > 0)
                     {
-                        SymbolContext context;
-                        AddressRange addr_range;
-                        if (target_symbols.GetContextAtIndex(i, context))
+                        std::vector<lldb::addr_t>  addresses;
+                        addresses.resize (num_symbols);
+                        for (uint32_t i = 0; i < num_symbols; i++)
                         {
-                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
-                            lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
-                            addresses[i] = load_addr;
+                            SymbolContext context;
+                            AddressRange addr_range;
+                            if (target_symbols.GetContextAtIndex(i, context))
+                            {
+                                context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+                                lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
+                                addresses[i] = load_addr;
+                            }
+                        }
+                        if (addresses.size() > 0)
+                            thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
+                        else
+                        {
+                            if (log)
+                                log->Printf ("Couldn't resolve the symbol contexts.");
                         }
                     }
-                    if (addresses.size() > 0)
-                        thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
                     else
                     {
                         if (log)
-                            log->Printf ("Couldn't resolve the symbol contexts.");
+                        {
+                            log->Printf ("Found a resolver stub for: \"%s\" but could not find any symbols it resolves to.", 
+                                         trampoline_name.AsCString());
+                        }
                     }
                 }
                 else
@@ -1503,6 +1540,29 @@
     return thread_plan_sp;
 }
 
+size_t
+DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol, 
+                                               lldb_private::ModuleList &images, 
+                                               lldb_private::SymbolContextList &equivalent_symbols)
+{
+    const ConstString &trampoline_name = original_symbol->GetMangled().GetName(Mangled::ePreferMangled);
+    if (!trampoline_name)
+        return 0;
+        
+    size_t initial_size = equivalent_symbols.GetSize();
+    
+    static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Z0-9]+)$";
+    std::string equivalent_regex_buf("^");
+    equivalent_regex_buf.append (trampoline_name.GetCString());
+    equivalent_regex_buf.append (resolver_name_regex);
+
+    RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
+    const bool append = true;
+    images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
+    
+    return equivalent_symbols.GetSize() - initial_size;
+}
+
 Error
 DynamicLoaderMacOSXDYLD::CanLoadImage ()
 {

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=144981&r1=144980&r2=144981&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Fri Nov 18 18:19:25 2011
@@ -66,6 +66,11 @@
     GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
                                   bool stop_others);
 
+    virtual size_t
+    FindEquivalentSymbols (lldb_private::Symbol *original_symbol, 
+                           lldb_private::ModuleList &module_list, 
+                           lldb_private::SymbolContextList &equivalent_symbols);
+    
     virtual lldb_private::Error
     CanLoadImage ();
 





More information about the lldb-commits mailing list