blob: 1edaf4964d8b2e68dfb126fd14331a8602787153 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- RegisterContext.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// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "lldb/Target/RegisterContext.h"
Jason Molenda8280cbe2010-10-25 11:12:07 +000015#include "lldb/Core/DataExtractor.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/Scalar.h"
17#include "lldb/Target/ExecutionContext.h"
18#include "lldb/Target/StackFrame.h"
19#include "lldb/Target/Thread.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
Greg Clayton08d7d3a2011-01-06 22:15:06 +000024RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
Chris Lattner24943d22010-06-08 16:52:24 +000025 m_thread (thread),
Greg Clayton08d7d3a2011-01-06 22:15:06 +000026 m_concrete_frame_idx (concrete_frame_idx)
Jason Molenda8280cbe2010-10-25 11:12:07 +000027{
28}
29
Chris Lattner24943d22010-06-08 16:52:24 +000030//----------------------------------------------------------------------
31// Destructor
32//----------------------------------------------------------------------
33RegisterContext::~RegisterContext()
34{
35}
36
37const RegisterInfo *
38RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
39{
40 if (reg_name && reg_name[0])
41 {
42 const uint32_t num_registers = GetRegisterCount();
43 for (uint32_t reg = start_idx; reg < num_registers; ++reg)
44 {
45 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
46
47 if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) ||
48 (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
49 {
50 return reg_info;
51 }
52 }
53 }
54 return NULL;
55}
56
57const char *
58RegisterContext::GetRegisterName (uint32_t reg)
59{
60 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
61 if (reg_info)
62 return reg_info->name;
63 return NULL;
64}
65
66uint64_t
67RegisterContext::GetPC(uint64_t fail_value)
68{
69 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
70 return ReadRegisterAsUnsigned (reg, fail_value);
71}
72
73bool
74RegisterContext::SetPC(uint64_t pc)
75{
76 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
77 bool success = WriteRegisterFromUnsigned (reg, pc);
78 if (success)
79 {
Greg Clayton08d7d3a2011-01-06 22:15:06 +000080 StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx));
81 if (frame_sp)
82 frame_sp->ChangePC(pc);
Chris Lattner24943d22010-06-08 16:52:24 +000083 else
84 m_thread.ClearStackFrames ();
85 }
86 return success;
87}
88
89uint64_t
90RegisterContext::GetSP(uint64_t fail_value)
91{
92 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
93 return ReadRegisterAsUnsigned (reg, fail_value);
94}
95
96bool
97RegisterContext::SetSP(uint64_t sp)
98{
99 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
100 return WriteRegisterFromUnsigned (reg, sp);
101}
102
103uint64_t
104RegisterContext::GetFP(uint64_t fail_value)
105{
106 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
107 return ReadRegisterAsUnsigned (reg, fail_value);
108}
109
110bool
111RegisterContext::SetFP(uint64_t fp)
112{
113 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
114 return WriteRegisterFromUnsigned (reg, fp);
115}
116
117uint64_t
118RegisterContext::GetReturnAddress (uint64_t fail_value)
119{
120 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
121 return ReadRegisterAsUnsigned (reg, fail_value);
122}
123
124uint64_t
125RegisterContext::GetFlags (uint64_t fail_value)
126{
127 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
128 return ReadRegisterAsUnsigned (reg, fail_value);
129}
130
131
132uint64_t
133RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value)
134{
135 if (reg != LLDB_INVALID_REGNUM)
136 {
137 Scalar value;
138 if (ReadRegisterValue (reg, value))
139 return value.GetRawBits64(fail_value);
140 }
141 return fail_value;
142}
143
144bool
145RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
146{
147 if (reg == LLDB_INVALID_REGNUM)
148 return false;
149 Scalar value(uval);
150 return WriteRegisterValue (reg, value);
151}
152
153lldb::tid_t
154RegisterContext::GetThreadID() const
155{
156 return m_thread.GetID();
157}
158
159uint32_t
160RegisterContext::NumSupportedHardwareBreakpoints ()
161{
162 return 0;
163}
164
165uint32_t
166RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
167{
168 return LLDB_INVALID_INDEX32;
169}
170
171bool
172RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
173{
174 return false;
175}
176
177
178uint32_t
179RegisterContext::NumSupportedHardwareWatchpoints ()
180{
181 return 0;
182}
183
184uint32_t
185RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
186{
187 return LLDB_INVALID_INDEX32;
188}
189
190bool
191RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
192{
193 return false;
194}
195
196bool
197RegisterContext::HardwareSingleStep (bool enable)
198{
199 return false;
200}
201
202Target *
203RegisterContext::CalculateTarget ()
204{
205 return m_thread.CalculateTarget();
206}
207
208
209Process *
210RegisterContext::CalculateProcess ()
211{
212 return m_thread.CalculateProcess ();
213}
214
215Thread *
216RegisterContext::CalculateThread ()
217{
218 return &m_thread;
219}
220
221StackFrame *
222RegisterContext::CalculateStackFrame ()
223{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000224 // Register contexts might belong to many frames if we have inlined
225 // functions inside a frame since all inlined functions share the
226 // same registers, so we can't definitively say which frame we come from...
227 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000228}
229
230void
Greg Claytona830adb2010-10-04 01:05:56 +0000231RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +0000232{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000233 m_thread.CalculateExecutionContext (exe_ctx);
Chris Lattner24943d22010-06-08 16:52:24 +0000234}
235
236
Jason Molenda3a4ea242010-09-10 07:49:16 +0000237bool
Jason Molenda8280cbe2010-10-25 11:12:07 +0000238RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum)
Jason Molenda3a4ea242010-09-10 07:49:16 +0000239{
240 const uint32_t num_registers = GetRegisterCount();
241 for (uint32_t reg = 0; reg < num_registers; ++reg)
242 {
243 const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg);
Chris Lattner24943d22010-06-08 16:52:24 +0000244
Jason Molenda3a4ea242010-09-10 07:49:16 +0000245 if (reg_info->kinds[source_rk] == source_regnum)
246 {
247 target_regnum = reg_info->kinds[target_rk];
248 if (target_regnum == LLDB_INVALID_REGNUM)
249 {
250 return false;
251 }
252 else
253 {
254 return true;
255 }
256 }
257 }
258 return false;
259}
Jason Molenda8280cbe2010-10-25 11:12:07 +0000260
261bool
262RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value)
263{
264 DataExtractor data;
265 if (!ReadRegisterBytes (reg, data))
266 return false;
267
268 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
269 uint32_t offset = 0;
270 switch (reg_info->encoding)
271 {
272 case eEncodingUint:
273 switch (reg_info->byte_size)
274 {
275 case 1:
276 {
277 value = data.GetU8 (&offset);
278 return true;
279 }
280 case 2:
281 {
282 value = data.GetU16 (&offset);
283 return true;
284 }
285 case 4:
286 {
287 value = data.GetU32 (&offset);
288 return true;
289 }
290 case 8:
291 {
292 value = data.GetU64 (&offset);
293 return true;
294 }
295 }
296 break;
297 case eEncodingSint:
298 switch (reg_info->byte_size)
299 {
300 case 1:
301 {
302 int8_t v;
303 if (data.ExtractBytes (0, sizeof (int8_t), eByteOrderHost, &v) != sizeof (int8_t))
304 return false;
305 value = v;
306 return true;
307 }
308 case 2:
309 {
310 int16_t v;
311 if (data.ExtractBytes (0, sizeof (int16_t), eByteOrderHost, &v) != sizeof (int16_t))
312 return false;
313 value = v;
314 return true;
315 }
316 case 4:
317 {
318 int32_t v;
319 if (data.ExtractBytes (0, sizeof (int32_t), eByteOrderHost, &v) != sizeof (int32_t))
320 return false;
321 value = v;
322 return true;
323 }
324 case 8:
325 {
326 int64_t v;
327 if (data.ExtractBytes (0, sizeof (int64_t), eByteOrderHost, &v) != sizeof (int64_t))
328 return false;
329 value = v;
330 return true;
331 }
332 }
333 break;
334 case eEncodingIEEE754:
335 switch (reg_info->byte_size)
336 {
337 case sizeof (float):
338 {
339 float v;
340 if (data.ExtractBytes (0, sizeof (float), eByteOrderHost, &v) != sizeof (float))
341 return false;
342 value = v;
343 return true;
344 }
345 case sizeof (double):
346 {
347 double v;
348 if (data.ExtractBytes (0, sizeof (double), eByteOrderHost, &v) != sizeof (double))
349 return false;
350 value = v;
351 return true;
352 }
353 case sizeof (long double):
354 {
355 double v;
356 if (data.ExtractBytes (0, sizeof (long double), eByteOrderHost, &v) != sizeof (long double))
357 return false;
358 value = v;
359 return true;
360 }
361 }
362 break;
363 }
364 return false;
365}
366
367bool
368RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value)
369{
370 DataExtractor data;
371 if (!value.IsValid())
372 return false;
373 if (!value.GetData (data))
374 return false;
375
376 return WriteRegisterBytes (reg, data);
377}