<rdar://problem/14496092>

Fixed the expression parser to be able to iterate across all function name matches that it finds when it is looking for the address of a function that the IR is looking for. Also taught it to deal with reexported symbols.

llvm-svn: 193716
This commit is contained in:
Greg Clayton 2013-10-30 21:37:46 +00:00
parent ba8ce0414e
commit f32db51c50
1 changed files with 41 additions and 22 deletions

View File

@ -515,6 +515,7 @@ FindCodeSymbolInContext
{ {
case eSymbolTypeCode: case eSymbolTypeCode:
case eSymbolTypeResolver: case eSymbolTypeResolver:
case eSymbolTypeReExported:
sc_list.Append(sym_ctx); sc_list.Append(sym_ctx);
break; break;
@ -547,7 +548,8 @@ ClangExpressionDeclMap::GetFunctionAddress
FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list); FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list);
if (!sc_list.GetSize()) uint32_t sc_list_size = sc_list.GetSize();
if (sc_list_size == 0)
{ {
// We occasionally get debug information in which a const function is reported // We occasionally get debug information in which a const function is reported
// as non-const, so the mangled name is wrong. This is a hack to compensate. // as non-const, so the mangled name is wrong. This is a hack to compensate.
@ -563,32 +565,49 @@ ClangExpressionDeclMap::GetFunctionAddress
log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString()); log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString());
FindCodeSymbolInContext(fixed_name, m_parser_vars->m_sym_ctx, sc_list); FindCodeSymbolInContext(fixed_name, m_parser_vars->m_sym_ctx, sc_list);
sc_list_size = sc_list.GetSize();
} }
} }
if (!sc_list.GetSize())
return false;
SymbolContext sym_ctx; for (uint32_t i=0; i<sc_list_size; ++i)
sc_list.GetContextAtIndex(0, sym_ctx); {
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
const Address *func_so_addr = NULL; const Address *func_so_addr = NULL;
bool is_indirect_function = false; bool is_indirect_function = false;
if (sym_ctx.function)
func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress();
else if (sym_ctx.symbol)
{
if (sym_ctx.symbol->GetType() == eSymbolTypeReExported)
{
Symbol *reexported_symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
if (reexported_symbol)
{
func_so_addr = &reexported_symbol->GetAddress();
is_indirect_function = reexported_symbol->IsIndirect();
}
}
else
{
func_so_addr = &sym_ctx.symbol->GetAddress();
is_indirect_function = sym_ctx.symbol->IsIndirect();
}
}
if (sym_ctx.function) if (func_so_addr && func_so_addr->IsValid())
func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress(); {
else if (sym_ctx.symbol) { lldb::addr_t load_addr = func_so_addr->GetCallableLoadAddress (target, is_indirect_function);
func_so_addr = &sym_ctx.symbol->GetAddress();
is_indirect_function = sym_ctx.symbol->IsIndirect(); if (load_addr != LLDB_INVALID_ADDRESS)
} else {
return false; func_addr = load_addr;
return true;
if (!func_so_addr || !func_so_addr->IsValid()) }
return false; }
}
func_addr = func_so_addr->GetCallableLoadAddress (target, is_indirect_function); return false;
return true;
} }
addr_t addr_t