1 //===-- HistoryUnwind.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/lldb-private.h" 10 11 #include "Plugins/Process/Utility/HistoryUnwind.h" 12 #include "Plugins/Process/Utility/RegisterContextHistory.h" 13 14 #include "lldb/Target/Process.h" 15 #include "lldb/Target/StackFrame.h" 16 #include "lldb/Target/Target.h" 17 #include "lldb/Target/Thread.h" 18 19 #include <memory> 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 // Constructor 25 26 HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs, 27 bool stop_id_is_valid) 28 : Unwind(thread), m_pcs(pcs), m_stop_id_is_valid(stop_id_is_valid) {} 29 30 // Destructor 31 32 HistoryUnwind::~HistoryUnwind() {} 33 34 void HistoryUnwind::DoClear() { 35 std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); 36 m_pcs.clear(); 37 m_stop_id_is_valid = false; 38 } 39 40 lldb::RegisterContextSP 41 HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) { 42 RegisterContextSP rctx; 43 if (frame) { 44 addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress( 45 &frame->GetThread()->GetProcess()->GetTarget()); 46 if (pc != LLDB_INVALID_ADDRESS) { 47 rctx = std::make_shared<RegisterContextHistory>( 48 *frame->GetThread().get(), frame->GetConcreteFrameIndex(), 49 frame->GetThread()->GetProcess()->GetAddressByteSize(), pc); 50 } 51 } 52 return rctx; 53 } 54 55 bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, 56 lldb::addr_t &pc) { 57 // FIXME do not throw away the lock after we acquire it.. 58 std::unique_lock<std::recursive_mutex> guard(m_unwind_mutex); 59 guard.unlock(); 60 if (frame_idx < m_pcs.size()) { 61 cfa = frame_idx; 62 pc = m_pcs[frame_idx]; 63 return true; 64 } 65 return false; 66 } 67 68 uint32_t HistoryUnwind::DoGetFrameCount() { return m_pcs.size(); } 69