[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 ®ex,
+ 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 ®ex,
+ 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