blob: 98bbc8b80384f414a15de265f83206277ac37f37 [file] [log] [blame]
Greg Claytona46013b2013-05-01 21:54:04 +00001//===-- RegisterContextThreadMemory.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#include "lldb/Core/Error.h"
12#include "lldb/Target/OperatingSystem.h"
13#include "lldb/Target/Process.h"
14#include "lldb/Target/Thread.h"
15
16#include "RegisterContextThreadMemory.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21RegisterContextThreadMemory::RegisterContextThreadMemory (Thread &thread,
22 lldb::addr_t register_data_addr) :
23 RegisterContext (thread, 0),
24 m_thread_wp (thread.shared_from_this()),
25 m_reg_ctx_sp (),
26 m_register_data_addr (register_data_addr),
27 m_stop_id(0)
28{
29}
30
31RegisterContextThreadMemory::~RegisterContextThreadMemory()
32{
33}
34
35void
36RegisterContextThreadMemory::UpdateRegisterContext ()
37{
38 ThreadSP thread_sp (m_thread_wp.lock());
39 if (thread_sp)
40 {
41 ProcessSP process_sp (thread_sp->GetProcess());
42
43 if (process_sp)
44 {
45 const uint32_t stop_id = process_sp->GetModID().GetStopID();
46 if (m_stop_id != stop_id)
47 {
48 m_stop_id = stop_id;
49 m_reg_ctx_sp.reset();
50 }
51 if (!m_reg_ctx_sp)
52 {
Greg Claytona9467952013-05-02 04:15:24 +000053 ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
54 if (backing_thread_sp)
55 {
56 m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
57 }
Greg Claytona46013b2013-05-01 21:54:04 +000058 else
59 {
Greg Claytona9467952013-05-02 04:15:24 +000060 OperatingSystem *os = process_sp->GetOperatingSystem ();
61 if (os->IsOperatingSystemPluginThread (thread_sp))
62 m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), LLDB_INVALID_ADDRESS);
63 }
Greg Claytona46013b2013-05-01 21:54:04 +000064 }
65 }
66 }
67 else
68 {
69 m_reg_ctx_sp.reset();
70 }
71}
72
73//------------------------------------------------------------------
74// Subclasses must override these functions
75//------------------------------------------------------------------
76void
77RegisterContextThreadMemory::InvalidateAllRegisters ()
78{
79 UpdateRegisterContext ();
80 if (m_reg_ctx_sp)
81 m_reg_ctx_sp->InvalidateAllRegisters();
82}
83
84size_t
85RegisterContextThreadMemory::GetRegisterCount ()
86{
87 UpdateRegisterContext ();
88 if (m_reg_ctx_sp)
89 return m_reg_ctx_sp->GetRegisterCount();
90 return 0;
91}
92
93const RegisterInfo *
94RegisterContextThreadMemory::GetRegisterInfoAtIndex (size_t reg)
95{
96 UpdateRegisterContext ();
97 if (m_reg_ctx_sp)
98 return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
99 return NULL;
100}
101
102size_t
103RegisterContextThreadMemory::GetRegisterSetCount ()
104{
105 UpdateRegisterContext ();
106 if (m_reg_ctx_sp)
107 return m_reg_ctx_sp->GetRegisterSetCount();
108 return 0;
109}
110
111const RegisterSet *
112RegisterContextThreadMemory::GetRegisterSet (size_t reg_set)
113{
114 UpdateRegisterContext ();
115 if (m_reg_ctx_sp)
116 return m_reg_ctx_sp->GetRegisterSet(reg_set);
117 return NULL;
118}
119
120bool
121RegisterContextThreadMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
122{
123 UpdateRegisterContext ();
124 if (m_reg_ctx_sp)
125 return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
126 return false;
127}
128
129bool
130RegisterContextThreadMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
131{
132 UpdateRegisterContext ();
133 if (m_reg_ctx_sp)
134 return m_reg_ctx_sp->WriteRegister (reg_info, reg_value);
135 return false;
136}
137
138bool
139RegisterContextThreadMemory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
140{
141 UpdateRegisterContext ();
142 if (m_reg_ctx_sp)
143 return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
144 return false;
145}
146
147bool
148RegisterContextThreadMemory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
149{
150 UpdateRegisterContext ();
151 if (m_reg_ctx_sp)
152 return m_reg_ctx_sp->WriteAllRegisterValues (data_sp);
153 return false;
154}
155
156bool
157RegisterContextThreadMemory::CopyFromRegisterContext (lldb::RegisterContextSP reg_ctx_sp)
158{
159 UpdateRegisterContext ();
160 if (m_reg_ctx_sp)
161 return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
162 return false;
163}
164
165uint32_t
166RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
167{
168 UpdateRegisterContext ();
169 if (m_reg_ctx_sp)
170 return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
171 return false;
172}
173
174uint32_t
175RegisterContextThreadMemory::NumSupportedHardwareBreakpoints ()
176{
177 UpdateRegisterContext ();
178 if (m_reg_ctx_sp)
179 return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
180 return false;
181}
182
183uint32_t
184RegisterContextThreadMemory::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
185{
186 UpdateRegisterContext ();
187 if (m_reg_ctx_sp)
188 return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
189 return 0;
190}
191
192bool
193RegisterContextThreadMemory::ClearHardwareBreakpoint (uint32_t hw_idx)
194{
195 UpdateRegisterContext ();
196 if (m_reg_ctx_sp)
197 return m_reg_ctx_sp->ClearHardwareBreakpoint (hw_idx);
198 return false;
199}
200
201uint32_t
202RegisterContextThreadMemory::NumSupportedHardwareWatchpoints ()
203{
204 UpdateRegisterContext ();
205 if (m_reg_ctx_sp)
206 return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
207 return 0;
208}
209
210uint32_t
211RegisterContextThreadMemory::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
212{
213 UpdateRegisterContext ();
214 if (m_reg_ctx_sp)
215 return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
216 return 0;
217}
218
219bool
220RegisterContextThreadMemory::ClearHardwareWatchpoint (uint32_t hw_index)
221{
222 UpdateRegisterContext ();
223 if (m_reg_ctx_sp)
224 return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
225 return false;
226}
227
228bool
229RegisterContextThreadMemory::HardwareSingleStep (bool enable)
230{
231 UpdateRegisterContext ();
232 if (m_reg_ctx_sp)
233 return m_reg_ctx_sp->HardwareSingleStep(enable);
234 return false;
235}
236
237Error
238RegisterContextThreadMemory::ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value)
239{
240 UpdateRegisterContext ();
241 if (m_reg_ctx_sp)
242 return m_reg_ctx_sp->ReadRegisterValueFromMemory (reg_info, src_addr, src_len, reg_value);
243 Error error;
244 error.SetErrorString("invalid register context");
245 return error;
246}
247
248Error
249RegisterContextThreadMemory::WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
250{
251 UpdateRegisterContext ();
252 if (m_reg_ctx_sp)
253 return m_reg_ctx_sp->WriteRegisterValueToMemory (reg_info, dst_addr, dst_len, reg_value);
254 Error error;
255 error.SetErrorString("invalid register context");
256 return error;
257}