diff options
Diffstat (limited to 'lldb/source/Plugins')
5 files changed, 115 insertions, 102 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); diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 878f15645ec..9781dcb093a 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -403,7 +403,9 @@ ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp, FileSpecList filter_modules; BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions); SearchFilterSP filter_sp (CreateExceptionSearchFilter ()); - return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, false); + const bool hardware = false; + const bool resolve_indirect_functions = false; + return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, hardware, resolve_indirect_functions); } void diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index a5bd9b510a4..62394623c59 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -632,20 +632,6 @@ ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr) return error; } -addr_t -ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error) -{ - addr_t function_addr = LLDB_INVALID_ADDRESS; - if (address == NULL) { - error.SetErrorStringWithFormat("unable to determine direct function call for NULL address"); - } else if (!InferiorCall(this, address, function_addr)) { - function_addr = LLDB_INVALID_ADDRESS; - error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s", - address->CalculateSymbolContextSymbol()->GetName().AsCString()); - } - return function_addr; -} - size_t ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) { diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h index beacb0186c6..7f705d33fe6 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h @@ -104,9 +104,6 @@ public: virtual lldb_private::Error DoDeallocateMemory(lldb::addr_t ptr); - virtual lldb::addr_t - ResolveIndirectFunction(const lldb_private::Address *address, lldb_private::Error &error); - virtual size_t GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site); diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 6d1b04f7f1a..1d5d19fad25 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -34,9 +34,16 @@ using namespace lldb; using namespace lldb_private; -bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, - addr_t addr, addr_t length, unsigned prot, - unsigned flags, addr_t fd, addr_t offset) { +bool +lldb_private::InferiorCallMmap (Process *process, + addr_t &allocated_addr, + addr_t addr, + addr_t length, + unsigned prot, + unsigned flags, + addr_t fd, + addr_t offset) +{ Thread *thread = process->GetThreadList().GetSelectedThread().get(); if (thread == NULL) return false; @@ -139,8 +146,11 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, return false; } -bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, - addr_t length) { +bool +lldb_private::InferiorCallMunmap (Process *process, + addr_t addr, + addr_t length) +{ Thread *thread = process->GetThreadList().GetSelectedThread().get(); if (thread == NULL) return false; @@ -209,7 +219,14 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, return false; } -bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) { +// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a +// function of the form "void * (*)(void)". We should find a better place to put this. + +bool +lldb_private::InferiorCall (Process *process, + const Address *address, + addr_t &returned_func) +{ Thread *thread = process->GetThreadList().GetSelectedThread().get(); if (thread == NULL || address == NULL) return false; @@ -233,7 +250,7 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); if (call_plan_sp) { - StreamFile error_strm; + StreamString error_strm; // This plan is a utility plan, so set it to discard itself when done. call_plan_sp->SetIsMasterPlan (true); call_plan_sp->SetOkayToDiscard(true); |