diff options
Diffstat (limited to 'lldb/source/Symbol/Function.cpp')
-rw-r--r-- | lldb/source/Symbol/Function.cpp | 104 |
1 files changed, 64 insertions, 40 deletions
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index a4c2d3b4b44a..e92585ccfed7 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -17,6 +17,7 @@ #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/Language.h" +#include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" #include "llvm/Support/Casting.h" @@ -75,16 +76,6 @@ InlineFunctionInfo::InlineFunctionInfo(ConstString name, InlineFunctionInfo::~InlineFunctionInfo() {} -int InlineFunctionInfo::Compare(const InlineFunctionInfo &a, - const InlineFunctionInfo &b) { - - int result = FunctionInfo::Compare(a, b); - if (result) - return result; - // only compare the mangled names if both have them - return Mangled::Compare(a.m_mangled, a.m_mangled); -} - void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const { FunctionInfo::Dump(s, show_fullpaths); if (m_mangled) @@ -127,23 +118,21 @@ size_t InlineFunctionInfo::MemorySize() const { return FunctionInfo::MemorySize() + m_mangled.MemorySize(); } -// -CallEdge::CallEdge(const char *symbol_name, lldb::addr_t return_pc, - CallSiteParameterArray parameters) - : return_pc(return_pc), parameters(std::move(parameters)), resolved(false) { - lazy_callee.symbol_name = symbol_name; -} +/// @name Call site related structures +/// @{ -llvm::ArrayRef<CallSiteParameter> CallEdge::GetCallSiteParameters() const { - return parameters; +lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, + Target &target) const { + const Address &base = caller.GetAddressRange().GetBaseAddress(); + return base.GetLoadAddress(&target) + return_pc; } -void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { +void DirectCallEdge::ParseSymbolFileAndResolve(ModuleList &images) { if (resolved) return; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - LLDB_LOG(log, "CallEdge: Lazily parsing the call graph for {0}", + LLDB_LOG(log, "DirectCallEdge: Lazily parsing the call graph for {0}", lazy_callee.symbol_name); auto resolve_lazy_callee = [&]() -> Function * { @@ -152,18 +141,19 @@ void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { images.FindFunctionSymbols(callee_name, eFunctionNameTypeAuto, sc_list); size_t num_matches = sc_list.GetSize(); if (num_matches == 0 || !sc_list[0].symbol) { - LLDB_LOG(log, "CallEdge: Found no symbols for {0}, cannot resolve it", + LLDB_LOG(log, + "DirectCallEdge: Found no symbols for {0}, cannot resolve it", callee_name); return nullptr; } Address callee_addr = sc_list[0].symbol->GetAddress(); if (!callee_addr.IsValid()) { - LLDB_LOG(log, "CallEdge: Invalid symbol address"); + LLDB_LOG(log, "DirectCallEdge: Invalid symbol address"); return nullptr; } Function *f = callee_addr.CalculateSymbolContextFunction(); if (!f) { - LLDB_LOG(log, "CallEdge: Could not find complete function"); + LLDB_LOG(log, "DirectCallEdge: Could not find complete function"); return nullptr; } return f; @@ -172,18 +162,50 @@ void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { resolved = true; } -Function *CallEdge::GetCallee(ModuleList &images) { +Function *DirectCallEdge::GetCallee(ModuleList &images, ExecutionContext &) { ParseSymbolFileAndResolve(images); assert(resolved && "Did not resolve lazy callee"); return lazy_callee.def; } -lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, - Target &target) const { - const Address &base = caller.GetAddressRange().GetBaseAddress(); - return base.GetLoadAddress(&target) + return_pc; +Function *IndirectCallEdge::GetCallee(ModuleList &images, + ExecutionContext &exe_ctx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Status error; + Value callee_addr_val; + if (!call_target.Evaluate(&exe_ctx, exe_ctx.GetRegisterContext(), + /*loclist_base_addr=*/LLDB_INVALID_ADDRESS, + /*initial_value_ptr=*/nullptr, + /*object_address_ptr=*/nullptr, callee_addr_val, + &error)) { + LLDB_LOGF(log, "IndirectCallEdge: Could not evaluate expression: %s", + error.AsCString()); + return nullptr; + } + + addr_t raw_addr = callee_addr_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + if (raw_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "IndirectCallEdge: Could not extract address from scalar"); + return nullptr; + } + + Address callee_addr; + if (!exe_ctx.GetTargetPtr()->ResolveLoadAddress(raw_addr, callee_addr)) { + LLDB_LOG(log, "IndirectCallEdge: Could not resolve callee's load address"); + return nullptr; + } + + Function *f = callee_addr.CalculateSymbolContextFunction(); + if (!f) { + LLDB_LOG(log, "IndirectCallEdge: Could not find complete function"); + return nullptr; + } + + return f; } +/// @} + // Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, lldb::user_id_t type_uid, const Mangled &mangled, Type *type, @@ -246,7 +268,7 @@ void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) { } } -llvm::MutableArrayRef<CallEdge> Function::GetCallEdges() { +llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetCallEdges() { if (m_call_edges_resolved) return m_call_edges; @@ -267,19 +289,20 @@ llvm::MutableArrayRef<CallEdge> Function::GetCallEdges() { // Sort the call edges to speed up return_pc lookups. llvm::sort(m_call_edges.begin(), m_call_edges.end(), - [](const CallEdge &LHS, const CallEdge &RHS) { - return LHS.GetUnresolvedReturnPCAddress() < - RHS.GetUnresolvedReturnPCAddress(); + [](const std::unique_ptr<CallEdge> &LHS, + const std::unique_ptr<CallEdge> &RHS) { + return LHS->GetUnresolvedReturnPCAddress() < + RHS->GetUnresolvedReturnPCAddress(); }); return m_call_edges; } -llvm::MutableArrayRef<CallEdge> Function::GetTailCallingEdges() { +llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetTailCallingEdges() { // Call edges are sorted by return PC, and tail calling edges have invalid // return PCs. Find them at the end of the list. - return GetCallEdges().drop_until([](const CallEdge &edge) { - return edge.GetUnresolvedReturnPCAddress() == LLDB_INVALID_ADDRESS; + return GetCallEdges().drop_until([](const std::unique_ptr<CallEdge> &edge) { + return edge->GetUnresolvedReturnPCAddress() == LLDB_INVALID_ADDRESS; }); } @@ -288,13 +311,13 @@ CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc, auto edges = GetCallEdges(); auto edge_it = std::lower_bound(edges.begin(), edges.end(), return_pc, - [&](const CallEdge &edge, addr_t pc) { - return edge.GetReturnPCAddress(*this, target) < pc; + [&](const std::unique_ptr<CallEdge> &edge, addr_t pc) { + return edge->GetReturnPCAddress(*this, target) < pc; }); if (edge_it == edges.end() || - edge_it->GetReturnPCAddress(*this, target) != return_pc) + edge_it->get()->GetReturnPCAddress(*this, target) != return_pc) return nullptr; - return &const_cast<CallEdge &>(*edge_it); + return &const_cast<CallEdge &>(*edge_it->get()); } Block &Function::GetBlock(bool can_create) { @@ -307,7 +330,8 @@ Block &Function::GetBlock(bool can_create) { "error: unable to find module " "shared pointer for function '%s' " "in %s\n", - GetName().GetCString(), m_comp_unit->GetPath().c_str()); + GetName().GetCString(), + m_comp_unit->GetPrimaryFile().GetPath().c_str()); } m_block.SetBlockInfoHasBeenParsed(true, true); } |