summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp')
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp165
1 files changed, 88 insertions, 77 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index f71b9cac3a3..43f6ce9e6a1 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -1596,14 +1596,6 @@ DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType
}
}
-// 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)
{
@@ -1612,104 +1604,123 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop
const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
Symbol *current_symbol = current_context.symbol;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ TargetSP target_sp (thread.CalculateTarget());
if (current_symbol != NULL)
{
+ std::vector<Address> addresses;
+
if (current_symbol->IsTrampoline())
{
const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
if (trampoline_name)
{
- SymbolContextList target_symbols;
- TargetSP target_sp (thread.CalculateTarget());
const ModuleList &images = target_sp->GetImages();
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
-
- size_t num_original_symbols = target_symbols.GetSize();
- // FIXME: The resolver symbol is only valid in object files. In binaries it is reused for the
- // shared library slot number. So we'll have to look this up in the dyld info.
- // For now, just turn this off.
-
- // bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
- // FIXME: Actually that isn't true, the N_SYMBOL_RESOLVER bit is only valid in .o files. You can't use
- // the symbol flags to tell whether something is a symbol resolver in a linked image.
- bool orig_is_resolver = false;
+ SymbolContextList code_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
+ size_t num_code_symbols = code_symbols.GetSize();
- if (num_original_symbols > 0)
+ if (num_code_symbols > 0)
{
- // 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++)
- {
- SymbolContext sc;
- target_symbols.GetContextAtIndex(i, sc);
-
- ModuleSP module_sp (sc.symbol->CalculateSymbolContextModule());
- if (module_sp)
- modules_to_search.AppendIfNeeded(module_sp);
- }
-
- // 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)
- {
- target_symbols.Clear();
-
- FindEquivalentSymbols (current_symbol, modules_to_search, 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 > 0)
+ for (uint32_t i = 0; i < num_code_symbols; i++)
{
- std::vector<lldb::addr_t> addresses;
- addresses.resize (num_symbols);
- for (uint32_t i = 0; i < num_symbols; i++)
+ SymbolContext context;
+ AddressRange addr_range;
+ if (code_symbols.GetContextAtIndex(i, context))
{
- SymbolContext context;
- AddressRange addr_range;
- if (target_symbols.GetContextAtIndex(i, context))
+ context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log)
{
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
- addresses[i] = load_addr;
+ addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", 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.");
- }
}
- else
+ }
+
+ SymbolContextList reexported_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
+ size_t num_reexported_symbols = reexported_symbols.GetSize();
+ if (num_reexported_symbols > 0)
+ {
+ for (uint32_t i = 0; i < num_reexported_symbols; i++)
{
- if (log)
+ SymbolContext context;
+ if (reexported_symbols.GetContextAtIndex(i, context))
{
- log->Printf ("Found a resolver stub for: \"%s\" but could not find any symbols it resolves to.",
- trampoline_name.AsCString());
+ if (context.symbol)
+ {
+ Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
+ if (actual_symbol)
+ {
+ if (actual_symbol->GetAddress().IsValid())
+ {
+ addresses.push_back(actual_symbol->GetAddress());
+ if (log)
+ {
+ lldb::addr_t load_addr = actual_symbol->GetAddress().GetLoadAddress(target_sp.get());
+ log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
+ actual_symbol->GetName().GetCString(), load_addr);
+ }
+ }
+ }
+ }
}
}
}
- else
+ }
+ }
+ else if (current_symbol->GetType() == eSymbolTypeReExported)
+ {
+ // I am not sure we could ever end up stopped AT a re-exported symbol. But just in case:
+
+ const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
+ if (actual_symbol)
+ {
+ Address target_addr(actual_symbol->GetAddress());
+ if (target_addr.IsValid())
{
if (log)
+ log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
+ current_symbol->GetName().GetCString(),
+ actual_symbol->GetName().GetCString(),
+ target_addr.GetLoadAddress(target_sp.get()));
+ addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
+
+ }
+ }
+ }
+
+ if (addresses.size() > 0)
+ {
+ // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
+ std::vector<lldb::addr_t> load_addrs;
+ for (Address address : addresses)
+ {
+ Symbol *symbol = address.CalculateSymbolContextSymbol();
+ if (symbol && symbol->IsIndirect())
+ {
+ Error error;
+ addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol->GetAddress(), error);
+ if (error.Success())
{
- log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
+ load_addrs.push_back(resolved_addr);
+ if (log)
+ log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
+ symbol->GetName().GetCString(), resolved_addr);
}
}
+ else
+ {
+ load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
+ }
+
}
+ thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
}
}
else
@@ -1732,7 +1743,7 @@ DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_s
size_t initial_size = equivalent_symbols.GetSize();
- static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Z0-9]+)$";
+ static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
std::string equivalent_regex_buf("^");
equivalent_regex_buf.append (trampoline_name.GetCString());
equivalent_regex_buf.append (resolver_name_regex);
OpenPOWER on IntegriCloud