1 //===-- HistoryUnwind.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-private.h"
11 
12 #include "Plugins/Process/Utility/RegisterContextHistory.h"
13 #include "Plugins/Process/Utility/HistoryUnwind.h"
14 
15 #include "lldb/Target/StackFrame.h"
16 #include "lldb/Target/Thread.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/Target.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 // Constructor
24 
25 HistoryUnwind::HistoryUnwind (Thread &thread,
26                               std::vector<lldb::addr_t> pcs,
27                               uint32_t stop_id,
28                               bool stop_id_is_valid) :
29         Unwind (thread),
30         m_pcs (pcs),
31         m_stop_id (stop_id),
32         m_stop_id_is_valid (stop_id_is_valid)
33 {
34 }
35 
36 // Destructor
37 
38 HistoryUnwind::~HistoryUnwind ()
39 {
40 }
41 
42 void
43 HistoryUnwind::DoClear ()
44 {
45     Mutex::Locker locker(m_unwind_mutex);
46     m_pcs.clear();
47     m_stop_id_is_valid = false;
48 }
49 
50 lldb::RegisterContextSP
51 HistoryUnwind::DoCreateRegisterContextForFrame (StackFrame *frame)
52 {
53     RegisterContextSP rctx;
54     if (frame)
55     {
56         addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress (&frame->GetThread()->GetProcess()->GetTarget());
57         if (pc != LLDB_INVALID_ADDRESS)
58         {
59             rctx.reset (new RegisterContextHistory (*frame->GetThread().get(), frame->GetConcreteFrameIndex(),
60                         frame->GetThread()->GetProcess()->GetAddressByteSize(), pc));
61         }
62     }
63     return rctx;
64 }
65 
66 bool
67 HistoryUnwind::DoGetFrameInfoAtIndex (uint32_t frame_idx, lldb::addr_t& cfa, lldb::addr_t& pc)
68 {
69     Mutex::Locker (m_unwind_mutex);   // FIXME do not throw away the lock after we acquire it..
70     if (frame_idx < m_pcs.size())
71     {
72         cfa = frame_idx;
73         pc = m_pcs[frame_idx];
74         return true;
75     }
76     return false;
77 }
78 
79 uint32_t
80 HistoryUnwind::DoGetFrameCount ()
81 {
82     return m_pcs.size();
83 }
84