xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
15ffd83dbSDimitry Andric //===-- HistoryUnwind.cpp -------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/lldb-private.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "Plugins/Process/Utility/HistoryUnwind.h"
120b57cec5SDimitry Andric #include "Plugins/Process/Utility/RegisterContextHistory.h"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "lldb/Target/Process.h"
150b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
160b57cec5SDimitry Andric #include "lldb/Target/Target.h"
170b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include <memory>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace lldb;
220b57cec5SDimitry Andric using namespace lldb_private;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric // Constructor
250b57cec5SDimitry Andric 
HistoryUnwind(Thread & thread,std::vector<lldb::addr_t> pcs,bool pcs_are_call_addresses)265ffd83dbSDimitry Andric HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
275ffd83dbSDimitry Andric                              bool pcs_are_call_addresses)
285ffd83dbSDimitry Andric     : Unwind(thread), m_pcs(pcs),
295ffd83dbSDimitry Andric       m_pcs_are_call_addresses(pcs_are_call_addresses) {}
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric // Destructor
320b57cec5SDimitry Andric 
33*fe6060f1SDimitry Andric HistoryUnwind::~HistoryUnwind() = default;
340b57cec5SDimitry Andric 
DoClear()350b57cec5SDimitry Andric void HistoryUnwind::DoClear() {
360b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
370b57cec5SDimitry Andric   m_pcs.clear();
380b57cec5SDimitry Andric }
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric lldb::RegisterContextSP
DoCreateRegisterContextForFrame(StackFrame * frame)410b57cec5SDimitry Andric HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
420b57cec5SDimitry Andric   RegisterContextSP rctx;
430b57cec5SDimitry Andric   if (frame) {
440b57cec5SDimitry Andric     addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress(
450b57cec5SDimitry Andric         &frame->GetThread()->GetProcess()->GetTarget());
460b57cec5SDimitry Andric     if (pc != LLDB_INVALID_ADDRESS) {
470b57cec5SDimitry Andric       rctx = std::make_shared<RegisterContextHistory>(
480b57cec5SDimitry Andric           *frame->GetThread().get(), frame->GetConcreteFrameIndex(),
490b57cec5SDimitry Andric           frame->GetThread()->GetProcess()->GetAddressByteSize(), pc);
500b57cec5SDimitry Andric     }
510b57cec5SDimitry Andric   }
520b57cec5SDimitry Andric   return rctx;
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
DoGetFrameInfoAtIndex(uint32_t frame_idx,lldb::addr_t & cfa,lldb::addr_t & pc,bool & behaves_like_zeroth_frame)550b57cec5SDimitry Andric bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
569dba64beSDimitry Andric                                           lldb::addr_t &pc,
579dba64beSDimitry Andric                                           bool &behaves_like_zeroth_frame) {
580b57cec5SDimitry Andric   // FIXME do not throw away the lock after we acquire it..
590b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex);
600b57cec5SDimitry Andric   guard.unlock();
610b57cec5SDimitry Andric   if (frame_idx < m_pcs.size()) {
620b57cec5SDimitry Andric     cfa = frame_idx;
630b57cec5SDimitry Andric     pc = m_pcs[frame_idx];
645ffd83dbSDimitry Andric     if (m_pcs_are_call_addresses)
655ffd83dbSDimitry Andric       behaves_like_zeroth_frame = true;
665ffd83dbSDimitry Andric     else
679dba64beSDimitry Andric       behaves_like_zeroth_frame = (frame_idx == 0);
680b57cec5SDimitry Andric     return true;
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric   return false;
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
DoGetFrameCount()730b57cec5SDimitry Andric uint32_t HistoryUnwind::DoGetFrameCount() { return m_pcs.size(); }
74