aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Symbol/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Symbol/Function.cpp')
-rw-r--r--lldb/source/Symbol/Function.cpp104
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);
}