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;  | 

