diff options
| -rw-r--r-- | lldb/include/lldb/Symbol/Function.h | 5 | ||||
| -rw-r--r-- | lldb/source/Symbol/Function.cpp | 14 | ||||
| -rw-r--r-- | lldb/source/Target/StackFrameList.cpp | 15 |
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; |

