diff options
author | Jim Ingham <jingham@apple.com> | 2014-01-10 23:46:59 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2014-01-10 23:46:59 +0000 |
commit | 1460e4bf0e722086d76de65ef74e76ec54a5534b (patch) | |
tree | e7e8ee24d300abecbf45a972b88a0bf9002e6d63 /lldb/source/Plugins/DynamicLoader | |
parent | 87c2b0400d0675ad68d7e3d5b4e7e81508ba3c51 (diff) | |
download | bcm5719-llvm-1460e4bf0e722086d76de65ef74e76ec54a5534b.tar.gz bcm5719-llvm-1460e4bf0e722086d76de65ef74e76ec54a5534b.zip |
Get the breakpoint setting, and the Mac OS X DYLD trampolines and expression evaluator to handle Indirect
symbols correctly. There were a couple of pieces to this.
1) When a breakpoint location finds itself pointing to an Indirect symbol, when the site for it is created
it needs to resolve the symbol and actually set the site at its target.
2) Not all breakpoints want to do this (i.e. a straight address breakpoint should always set itself on the
specified address, so somem machinery was needed to specify that.
3) I added some info to the break list output for indirect symbols so you could see what was happening.
Also I made it clear when we re-route through re-exported symbols.
4) I moved ResolveIndirectFunction from ProcessPosix to Process since it works the exact same way on Mac OS X
and the other posix systems. If we find a platform that doesn't do it this way, they can override the
call in Process.
5) Fixed one bug in RunThreadPlan, if you were trying to run a thread plan after a "running" event had
been broadcast, the event coalescing would cause you to miss the ThreadPlan running event. So I added
a way to override the coalescing.
6) Made DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan handle Indirect & Re-exported symbols.
<rdar://problem/15280639>
llvm-svn: 198976
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader')
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp | 165 |
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 ¤t_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); |