Author: spyffe Date: Tue Feb 23 17:09:06 2016 New Revision: 261704 URL: http://llvm.org/viewvc/llvm-project?rev=261704&view=rev Log: When looking for symbols, find load addresses in a more robust way.
IRExecutionUnit previously replicated a bunch of logic that already existed elsewhere for the purpose of getting a load address for a symbol. This approach failed to resolve certain types of symbols. Instead, we now use functions on SymbolContext to do the address resolution. This is a cleanup of IRExecutionUnit::FindInSymbols, and also fixes a latent bug where we looked at the wrong SymbolContext to determine whether or not it is external. <rdar://problem/24770829> Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?rev=261704&r1=261703&r2=261704&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRExecutionUnit.cpp (original) +++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Tue Feb 23 17:09:06 2016 @@ -769,9 +769,62 @@ IRExecutionUnit::CollectCandidateCPlusPl lldb::addr_t IRExecutionUnit::FindInSymbols(const std::vector<IRExecutionUnit::SearchSpec> &specs, const lldb_private::SymbolContext &sc) { + Target *target = sc.target_sp.get(); + + if (!target) + { + // we shouldn't be doing any symbol lookup at all without a target + return LLDB_INVALID_ADDRESS; + } + for (const SearchSpec &spec : specs) { SymbolContextList sc_list; + + lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS; + + std::function<bool (lldb::addr_t &, SymbolContextList &, const lldb_private::SymbolContext &)> get_external_load_address = + [&best_internal_load_address, target](lldb::addr_t &load_address, + SymbolContextList &sc_list, + const lldb_private::SymbolContext &sc) -> lldb::addr_t + { + load_address = LLDB_INVALID_ADDRESS; + + for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si) + { + SymbolContext candidate_sc; + + sc_list.GetContextAtIndex(si, candidate_sc); + + const bool is_external = (candidate_sc.function) || + (candidate_sc.symbol && candidate_sc.symbol->IsExternal()); + + AddressRange range; + + if (candidate_sc.GetAddressRange(lldb::eSymbolContextFunction | lldb::eSymbolContextSymbol, + 0, + false, + range)) + { + load_address = range.GetBaseAddress().GetCallableLoadAddress(target); + + if (load_address != LLDB_INVALID_ADDRESS) + { + if (is_external) + { + return true; + } + else if (best_internal_load_address == LLDB_INVALID_ADDRESS) + { + best_internal_load_address = load_address; + load_address = LLDB_INVALID_ADDRESS; + } + } + } + } + + return false; + }; if (sc.module_sp) { @@ -783,6 +836,17 @@ IRExecutionUnit::FindInSymbols(const std true, // append sc_list); } + + lldb::addr_t load_address = LLDB_INVALID_ADDRESS; + + if (get_external_load_address(load_address, sc_list, sc)) + { + return load_address; + } + else + { + sc_list.Clear(); + } if (sc_list.GetSize() == 0 && sc.target_sp) { @@ -794,49 +858,26 @@ IRExecutionUnit::FindInSymbols(const std sc_list); } + if (get_external_load_address(load_address, sc_list, sc)) + { + return load_address; + } + else + { + sc_list.Clear(); + } + if (sc_list.GetSize() == 0 && sc.target_sp) { sc.target_sp->GetImages().FindSymbolsWithNameAndType(spec.name, lldb::eSymbolTypeAny, sc_list); } - lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS; - - for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si) + if (get_external_load_address(load_address, sc_list, sc)) { - bool is_external = false; - - SymbolContext candidate_sc; - - sc_list.GetContextAtIndex(si, candidate_sc); - if (candidate_sc.function) - { - is_external = true; - } - else if (sc.symbol) - { - if (sc.symbol->IsExternal()) - { - is_external = true; - } - } - - lldb::addr_t load_address = candidate_sc.symbol->ResolveCallableAddress(*sc.target_sp); - - if (load_address == LLDB_INVALID_ADDRESS) - load_address = candidate_sc.symbol->GetAddress().GetLoadAddress(sc.target_sp.get()); - - if (load_address != LLDB_INVALID_ADDRESS) - { - if (is_external) - { - return load_address; - } - else - { - best_internal_load_address = load_address; - } - } + return load_address; } + // if there are any searches we try after this, add an sc_list.Clear() in an "else" clause here + if (best_internal_load_address != LLDB_INVALID_ADDRESS) { return best_internal_load_address; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits