diff options
author | Sean Callanan <scallanan@apple.com> | 2016-02-23 23:09:06 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2016-02-23 23:09:06 +0000 |
commit | fed0e758cb5f30cf19854315173f199420746ef8 (patch) | |
tree | 486222ac4e7e38213db9affcb4cdd55842bf5243 /lldb/source/Expression | |
parent | c289b74bd6c6837731459ef9620a859fdd158d4d (diff) | |
download | bcm5719-llvm-fed0e758cb5f30cf19854315173f199420746ef8.tar.gz bcm5719-llvm-fed0e758cb5f30cf19854315173f199420746ef8.zip |
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>
llvm-svn: 261704
Diffstat (limited to 'lldb/source/Expression')
-rw-r--r-- | lldb/source/Expression/IRExecutionUnit.cpp | 113 |
1 files changed, 77 insertions, 36 deletions
diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index 5d8cc344a6c..a209dd19429 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -769,9 +769,62 @@ IRExecutionUnit::CollectCandidateCPlusPlusNames(std::vector<IRExecutionUnit::Sea 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::vector<IRExecutionUnit::SearchSpec> &s 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::vector<IRExecutionUnit::SearchSpec> &s 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; |