summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/Function.h5
-rw-r--r--lldb/source/Symbol/Function.cpp14
-rw-r--r--lldb/source/Target/StackFrameList.cpp15
3 files changed, 23 insertions, 11 deletions
diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h
index f68a16705d9..b0a7a0d1846 100644
--- a/lldb/include/lldb/Symbol/Function.h
+++ b/lldb/include/lldb/Symbol/Function.h
@@ -402,6 +402,11 @@ public:
/// return None.
llvm::MutableArrayRef<CallEdge> GetTailCallingEdges();
+ /// Get the outgoing call edge from this function which has the given return
+ /// address \p return_pc, or return nullptr. Note that this will not return a
+ /// tail-calling edge.
+ CallEdge *GetCallEdgeForReturnAddress(lldb::addr_t return_pc, Target &target);
+
/// Get accessor for the block list.
///
/// \return
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 28ce4fdd4ad..9ba178f2563 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -276,6 +276,20 @@ llvm::MutableArrayRef<CallEdge> Function::GetTailCallingEdges() {
});
}
+CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc,
+ Target &target) {
+ 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;
+ });
+ if (edge_it == edges.end() ||
+ edge_it->GetReturnPCAddress(*this, target) != return_pc)
+ return nullptr;
+ return &const_cast<CallEdge &>(*edge_it);
+}
+
Block &Function::GetBlock(bool can_create) {
if (!m_block.BlockInfoHasBeenParsed() && can_create) {
ModuleSP module_sp = CalculateSymbolContextModule();
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index 69445624a53..fbced5fd132 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -250,26 +250,19 @@ static void FindInterveningFrames(Function &begin, Function &end,
begin.GetDisplayName(), end.GetDisplayName(), return_pc);
// Find a non-tail calling edge with the correct return PC.
- auto first_level_edges = begin.GetCallEdges();
if (log)
- for (const CallEdge &edge : first_level_edges)
+ for (const CallEdge &edge : begin.GetCallEdges())
LLDB_LOG(log, "FindInterveningFrames: found call with retn-PC = {0:x}",
edge.GetReturnPCAddress(begin, target));
- auto first_edge_it = std::lower_bound(
- first_level_edges.begin(), first_level_edges.end(), return_pc,
- [&](const CallEdge &edge, addr_t target_pc) {
- return edge.GetReturnPCAddress(begin, target) < target_pc;
- });
- if (first_edge_it == first_level_edges.end() ||
- first_edge_it->GetReturnPCAddress(begin, target) != return_pc) {
+ CallEdge *first_edge = begin.GetCallEdgeForReturnAddress(return_pc, target);
+ if (!first_edge) {
LLDB_LOG(log, "No call edge outgoing from {0} with retn-PC == {1:x}",
begin.GetDisplayName(), return_pc);
return;
}
- CallEdge &first_edge = const_cast<CallEdge &>(*first_edge_it);
// The first callee may not be resolved, or there may be nothing to fill in.
- Function *first_callee = first_edge.GetCallee(images);
+ Function *first_callee = first_edge->GetCallee(images);
if (!first_callee) {
LLDB_LOG(log, "Could not resolve callee");
return;
OpenPOWER on IntegriCloud