}
}
-lldb::addr_t IRExecutionUnit::FindInSymbols(
- const std::vector<IRExecutionUnit::SearchSpec> &specs,
- const lldb_private::SymbolContext &sc,
- bool &symbol_was_missing_weak) {
- symbol_was_missing_weak = false;
- Target *target = sc.target_sp.get();
+class LoadAddressResolver {
+public:
+ LoadAddressResolver(Target *target, bool &symbol_was_missing_weak)
+ : m_target(target), m_symbol_was_missing_weak(symbol_was_missing_weak) {}
- if (!target) {
- // we shouldn't be doing any symbol lookup at all without a target
- return LLDB_INVALID_ADDRESS;
- }
+ llvm::Optional<lldb::addr_t> Resolve(SymbolContextList &sc_list) {
+ if (sc_list.IsEmpty())
+ return llvm::None;
- 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,
- &symbol_was_missing_weak](
- lldb::addr_t &load_address, SymbolContextList &sc_list,
- const lldb_private::SymbolContext &sc) -> lldb::addr_t {
- load_address = LLDB_INVALID_ADDRESS;
-
- if (sc_list.GetSize() == 0)
- return false;
-
- // missing_weak_symbol will be true only if we found only weak undefined
- // references to this symbol.
- symbol_was_missing_weak = true;
- for (auto candidate_sc : sc_list.SymbolContexts()) {
- // Only symbols can be weak undefined:
- if (!candidate_sc.symbol)
- symbol_was_missing_weak = false;
- else if (candidate_sc.symbol->GetType() != lldb::eSymbolTypeUndefined
- || !candidate_sc.symbol->IsWeak())
- symbol_was_missing_weak = false;
-
- const bool is_external =
- (candidate_sc.function) ||
- (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
- if (candidate_sc.symbol) {
- load_address = candidate_sc.symbol->ResolveCallableAddress(*target);
-
- if (load_address == LLDB_INVALID_ADDRESS) {
- if (target->GetProcessSP())
- load_address =
- candidate_sc.symbol->GetAddress().GetLoadAddress(target);
- else
- load_address = candidate_sc.symbol->GetAddress().GetFileAddress();
- }
- }
+ lldb::addr_t load_address = LLDB_INVALID_ADDRESS;
- if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) {
- if (target->GetProcessSP())
- load_address = candidate_sc.function->GetAddressRange()
- .GetBaseAddress()
- .GetLoadAddress(target);
- else
- load_address = candidate_sc.function->GetAddressRange()
- .GetBaseAddress()
- .GetFileAddress();
+ // Missing_weak_symbol will be true only if we found only weak undefined
+ // references to this symbol.
+ m_symbol_was_missing_weak = true;
+
+ for (auto candidate_sc : sc_list.SymbolContexts()) {
+ // Only symbols can be weak undefined.
+ if (!candidate_sc.symbol ||
+ candidate_sc.symbol->GetType() != lldb::eSymbolTypeUndefined ||
+ !candidate_sc.symbol->IsWeak())
+ m_symbol_was_missing_weak = false;
+
+ // First try the symbol.
+ if (candidate_sc.symbol) {
+ load_address = candidate_sc.symbol->ResolveCallableAddress(*m_target);
+ if (load_address == LLDB_INVALID_ADDRESS) {
+ Address addr = candidate_sc.symbol->GetAddress();
+ load_address = m_target->GetProcessSP()
+ ? addr.GetLoadAddress(m_target)
+ : addr.GetFileAddress();
}
+ }
- 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;
- }
- }
+ // If that didn't work, try the function.
+ if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) {
+ Address addr =
+ candidate_sc.function->GetAddressRange().GetBaseAddress();
+ load_address = m_target->GetProcessSP() ? addr.GetLoadAddress(m_target)
+ : addr.GetFileAddress();
}
- // You test the address of a weak symbol against NULL to see if it is
- // present. So we should return 0 for a missing weak symbol.
- if (symbol_was_missing_weak) {
- load_address = 0;
- return true;
+ // We found a load address.
+ if (load_address != LLDB_INVALID_ADDRESS) {
+ // If the load address is external, we're done.
+ const bool is_external =
+ (candidate_sc.function) ||
+ (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
+ if (is_external)
+ return load_address;
+
+ // Otherwise, remember the best internal load address.
+ if (m_best_internal_load_address == LLDB_INVALID_ADDRESS)
+ m_best_internal_load_address = load_address;
}
-
- return false;
- };
+ }
+
+ // You test the address of a weak symbol against NULL to see if it is
+ // present. So we should return 0 for a missing weak symbol.
+ if (m_symbol_was_missing_weak)
+ return 0;
+
+ return llvm::None;
+ }
- ModuleFunctionSearchOptions function_options;
- function_options.include_symbols = true;
- function_options.include_inlines = false;
+ lldb::addr_t GetBestInternalLoadAddress() const {
+ return m_best_internal_load_address;
+ }
+private:
+ Target *m_target;
+ bool &m_symbol_was_missing_weak;
+ lldb::addr_t m_best_internal_load_address = LLDB_INVALID_ADDRESS;
+};
+
+lldb::addr_t IRExecutionUnit::FindInSymbols(
+ const std::vector<IRExecutionUnit::SearchSpec> &specs,
+ const lldb_private::SymbolContext &sc, bool &symbol_was_missing_weak) {
+ symbol_was_missing_weak = false;
+
+ 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;
+ }
+
+ LoadAddressResolver resolver(target, symbol_was_missing_weak);
+
+ ModuleFunctionSearchOptions function_options;
+ function_options.include_symbols = true;
+ function_options.include_inlines = false;
+
+ for (const SearchSpec &spec : specs) {
if (sc.module_sp) {
+ SymbolContextList sc_list;
sc.module_sp->FindFunctions(spec.name, CompilerDeclContext(), spec.mask,
function_options, sc_list);
+ if (auto load_addr = resolver.Resolve(sc_list))
+ return *load_addr;
}
- 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) {
+ if (sc.target_sp) {
+ SymbolContextList sc_list;
sc.target_sp->GetImages().FindFunctions(spec.name, spec.mask,
function_options, sc_list);
+ if (auto load_addr = resolver.Resolve(sc_list))
+ return *load_addr;
}
- 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) {
+ if (sc.target_sp) {
+ SymbolContextList sc_list;
sc.target_sp->GetImages().FindSymbolsWithNameAndType(
spec.name, lldb::eSymbolTypeAny, sc_list);
+ if (auto load_addr = resolver.Resolve(sc_list))
+ return *load_addr;
}
- if (get_external_load_address(load_address, sc_list, sc)) {
- 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) {
+ lldb::addr_t best_internal_load_address =
+ resolver.GetBestInternalLoadAddress();
+ if (best_internal_load_address != LLDB_INVALID_ADDRESS)
return best_internal_load_address;
- }
}
return LLDB_INVALID_ADDRESS;