11 changes: 5 additions & 6 deletions lldb/source/Core/ModuleList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {

void ModuleList::FindFunctions(ConstString name,
FunctionNameType name_type_mask,
bool include_symbols, bool include_inlines,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) const {
const size_t old_size = sc_list.GetSize();

Expand All @@ -375,8 +375,7 @@ void ModuleList::FindFunctions(ConstString name,
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindFunctions(lookup_info.GetLookupName(), CompilerDeclContext(),
lookup_info.GetNameTypeMask(), include_symbols,
include_inlines, sc_list);
lookup_info.GetNameTypeMask(), options, sc_list);
}

const size_t new_size = sc_list.GetSize();
Expand All @@ -388,7 +387,7 @@ void ModuleList::FindFunctions(ConstString name,
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindFunctions(name, CompilerDeclContext(), name_type_mask,
include_symbols, include_inlines, sc_list);
options, sc_list);
}
}
}
Expand Down Expand Up @@ -422,12 +421,12 @@ void ModuleList::FindFunctionSymbols(ConstString name,
}

void ModuleList::FindFunctions(const RegularExpression &name,
bool include_symbols, bool include_inlines,
const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos) {
(*pos)->FindFunctions(name, include_symbols, include_inlines, sc_list);
(*pos)->FindFunctions(name, options, sc_list);
}
}

Expand Down
11 changes: 7 additions & 4 deletions lldb/source/Core/SourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,14 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) {
if (executable_ptr) {
SymbolContextList sc_list;
ConstString main_name("main");
bool symbols_okay = false; // Force it to be a debug symbol.
bool inlines_okay = true;

ModuleFunctionSearchOptions function_options;
function_options.include_symbols =
false; // Force it to be a debug symbol.
function_options.include_inlines = true;
executable_ptr->FindFunctions(main_name, CompilerDeclContext(),
lldb::eFunctionNameTypeBase, inlines_okay,
symbols_okay, sc_list);
lldb::eFunctionNameTypeBase,
function_options, sc_list);
size_t num_matches = sc_list.GetSize();
for (size_t idx = 0; idx < num_matches; idx++) {
SymbolContext sc;
Expand Down
203 changes: 98 additions & 105 deletions lldb/source/Expression/IRExecutionUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,133 +769,126 @@ void IRExecutionUnit::CollectFallbackNames(
}
}

class LoadAddressResolver {
public:
LoadAddressResolver(Target *target, bool &symbol_was_missing_weak)
: m_target(target), m_symbol_was_missing_weak(symbol_was_missing_weak) {}

llvm::Optional<lldb::addr_t> Resolve(SymbolContextList &sc_list) {
if (sc_list.IsEmpty())
return llvm::None;

lldb::addr_t load_address = LLDB_INVALID_ADDRESS;

// 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 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();
}

// 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;
}
}

// 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;
}

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) {
const lldb_private::SymbolContext &sc, bool &symbol_was_missing_weak) {
symbol_was_missing_weak = false;
Target *target = sc.target_sp.get();

Target *target = sc.target_sp.get();
if (!target) {
// we shouldn't be doing any symbol lookup at all without a 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,
&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();
}
}

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();
}

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;
}
}
}
LoadAddressResolver resolver(target, symbol_was_missing_weak);

// 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;
}

return false;
};
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,
true, // include_symbols
false, // include_inlines
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();
function_options, sc_list);
if (auto load_addr = resolver.Resolve(sc_list))
return *load_addr;
}

if (sc_list.GetSize() == 0 && sc.target_sp) {
if (sc.target_sp) {
SymbolContextList sc_list;
sc.target_sp->GetImages().FindFunctions(spec.name, spec.mask,
true, // include_symbols
false, // include_inlines
sc_list);
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;
Expand Down
23 changes: 12 additions & 11 deletions lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -974,8 +974,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
interface_decl->getName(), selector_name);
SymbolContextList sc_list;

const bool include_symbols = false;
const bool include_inlines = false;
ModuleFunctionSearchOptions function_options;
function_options.include_symbols = false;
function_options.include_inlines = false;

std::string interface_name = interface_decl->getNameAsString();

Expand All @@ -986,9 +987,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ConstString instance_method_name(ms.GetString());

sc_list.Clear();
m_target->GetImages().FindFunctions(
instance_method_name, lldb::eFunctionNameTypeFull, include_symbols,
include_inlines, sc_list);
m_target->GetImages().FindFunctions(instance_method_name,
lldb::eFunctionNameTypeFull,
function_options, sc_list);

if (sc_list.GetSize())
break;
Expand All @@ -999,9 +1000,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
ConstString class_method_name(ms.GetString());

sc_list.Clear();
m_target->GetImages().FindFunctions(
class_method_name, lldb::eFunctionNameTypeFull, include_symbols,
include_inlines, sc_list);
m_target->GetImages().FindFunctions(class_method_name,
lldb::eFunctionNameTypeFull,
function_options, sc_list);

if (sc_list.GetSize())
break;
Expand All @@ -1012,9 +1013,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {

SymbolContextList candidate_sc_list;

m_target->GetImages().FindFunctions(
selector_name, lldb::eFunctionNameTypeSelector, include_symbols,
include_inlines, candidate_sc_list);
m_target->GetImages().FindFunctions(selector_name,
lldb::eFunctionNameTypeSelector,
function_options, candidate_sc_list);

for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) {
SymbolContext candidate_sc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1220,22 +1220,25 @@ void ClangExpressionDeclMap::LookupFunction(
}
}

const bool include_inlines = false;
SymbolContextList sc_list;
if (namespace_decl && module_sp) {
const bool include_symbols = false;
ModuleFunctionSearchOptions function_options;
function_options.include_inlines = false;
function_options.include_symbols = false;

module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,
include_symbols, include_inlines, sc_list);
function_options, sc_list);
} else if (target && !namespace_decl) {
const bool include_symbols = true;
ModuleFunctionSearchOptions function_options;
function_options.include_inlines = false;
function_options.include_symbols = true;

// TODO Fix FindFunctions so that it doesn't return
// instance methods for eFunctionNameTypeBase.

target->GetImages().FindFunctions(
name, eFunctionNameTypeFull | eFunctionNameTypeBase, include_symbols,
include_inlines, sc_list);
name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options,
sc_list);
}

// If we found more than one function, see if we can use the frame's decl
Expand Down
21 changes: 12 additions & 9 deletions lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

#include "InferiorCallPOSIX.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
Expand Down Expand Up @@ -41,12 +42,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
if (thread == nullptr)
return false;

const bool include_symbols = true;
const bool include_inlines = false;
ModuleFunctionSearchOptions function_options;
function_options.include_symbols = true;
function_options.include_inlines = false;

SymbolContextList sc_list;
process->GetTarget().GetImages().FindFunctions(
ConstString("mmap"), eFunctionNameTypeFull, include_symbols,
include_inlines, sc_list);
ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list);
const uint32_t count = sc_list.GetSize();
if (count > 0) {
SymbolContext sc;
Expand Down Expand Up @@ -135,12 +137,13 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
if (thread == nullptr)
return false;

const bool include_symbols = true;
const bool include_inlines = false;
ModuleFunctionSearchOptions function_options;
function_options.include_symbols = true;
function_options.include_inlines = false;

SymbolContextList sc_list;
process->GetTarget().GetImages().FindFunctions(
ConstString("munmap"), eFunctionNameTypeFull, include_symbols,
include_inlines, sc_list);
ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list);
const uint32_t count = sc_list.GetSize();
if (count > 0) {
SymbolContext sc;
Expand Down