blob: 169ab743f5858cf66f3f8f4f35fda022698c0f16 [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"
Greg Clayton061b79d2011-05-09 20:18:18 +000016#include "lldb/Core/RegisterValue.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Scalar.h"
Greg Claytoncd548032011-02-01 01:31:41 +000018#include "lldb/Host/Endian.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Target/ExecutionContext.h"
20#include "lldb/Target/StackFrame.h"
Greg Claytona875b642011-01-09 21:07:35 +000021#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Target/Thread.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
Greg Clayton08d7d3a2011-01-06 22:15:06 +000027RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
Chris Lattner24943d22010-06-08 16:52:24 +000028 m_thread (thread),
Greg Claytona875b642011-01-09 21:07:35 +000029 m_concrete_frame_idx (concrete_frame_idx),
30 m_stop_id (thread.GetProcess().GetStopID())
Jason Molenda8280cbe2010-10-25 11:12:07 +000031{
32}
33
Chris Lattner24943d22010-06-08 16:52:24 +000034//----------------------------------------------------------------------
35// Destructor
36//----------------------------------------------------------------------
37RegisterContext::~RegisterContext()
38{
39}
40
Greg Claytona875b642011-01-09 21:07:35 +000041void
42RegisterContext::InvalidateIfNeeded (bool force)
43{
44 const uint32_t this_stop_id = GetStopID();
45 const uint32_t process_stop_id = m_thread.GetProcess().GetStopID();
46 if (force || process_stop_id != this_stop_id)
47 {
48 InvalidateAllRegisters ();
49 SetStopID (process_stop_id);
50 }
51}
52
53
Chris Lattner24943d22010-06-08 16:52:24 +000054const RegisterInfo *
55RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
56{
57 if (reg_name && reg_name[0])
58 {
59 const uint32_t num_registers = GetRegisterCount();
60 for (uint32_t reg = start_idx; reg < num_registers; ++reg)
61 {
62 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
63
64 if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) ||
65 (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
66 {
67 return reg_info;
68 }
69 }
70 }
71 return NULL;
72}
73
74const char *
75RegisterContext::GetRegisterName (uint32_t reg)
76{
77 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
78 if (reg_info)
79 return reg_info->name;
80 return NULL;
81}
82
83uint64_t
84RegisterContext::GetPC(uint64_t fail_value)
85{
86 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
87 return ReadRegisterAsUnsigned (reg, fail_value);
88}
89
90bool
91RegisterContext::SetPC(uint64_t pc)
92{
93 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
94 bool success = WriteRegisterFromUnsigned (reg, pc);
95 if (success)
96 {
Greg Clayton08d7d3a2011-01-06 22:15:06 +000097 StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx));
98 if (frame_sp)
99 frame_sp->ChangePC(pc);
Chris Lattner24943d22010-06-08 16:52:24 +0000100 else
101 m_thread.ClearStackFrames ();
102 }
103 return success;
104}
105
106uint64_t
107RegisterContext::GetSP(uint64_t fail_value)
108{
109 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
110 return ReadRegisterAsUnsigned (reg, fail_value);
111}
112
113bool
114RegisterContext::SetSP(uint64_t sp)
115{
116 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
117 return WriteRegisterFromUnsigned (reg, sp);
118}
119
120uint64_t
121RegisterContext::GetFP(uint64_t fail_value)
122{
123 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
124 return ReadRegisterAsUnsigned (reg, fail_value);
125}
126
127bool
128RegisterContext::SetFP(uint64_t fp)
129{
130 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
131 return WriteRegisterFromUnsigned (reg, fp);
132}
133
134uint64_t
135RegisterContext::GetReturnAddress (uint64_t fail_value)
136{
137 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
138 return ReadRegisterAsUnsigned (reg, fail_value);
139}
140
141uint64_t
142RegisterContext::GetFlags (uint64_t fail_value)
143{
144 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
145 return ReadRegisterAsUnsigned (reg, fail_value);
146}
147
148
149uint64_t
150RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value)
151{
152 if (reg != LLDB_INVALID_REGNUM)
153 {
Greg Clayton061b79d2011-05-09 20:18:18 +0000154 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
155 if (reg_info)
156 {
157 RegisterValue value;
158 if (ReadRegister (reg_info, value))
159 return value.GetAsUInt64();
160 }
Chris Lattner24943d22010-06-08 16:52:24 +0000161 }
162 return fail_value;
163}
164
165bool
166RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
167{
168 if (reg == LLDB_INVALID_REGNUM)
169 return false;
Greg Clayton061b79d2011-05-09 20:18:18 +0000170 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
171 if (reg_info)
172 {
173 RegisterValue value;
174 if (value.SetUInt(uval, reg_info->byte_size))
175 return WriteRegister (reg_info, value);
176 }
177 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000178}
179
180lldb::tid_t
181RegisterContext::GetThreadID() const
182{
183 return m_thread.GetID();
184}
185
186uint32_t
187RegisterContext::NumSupportedHardwareBreakpoints ()
188{
189 return 0;
190}
191
192uint32_t
193RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
194{
195 return LLDB_INVALID_INDEX32;
196}
197
198bool
199RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
200{
201 return false;
202}
203
204
205uint32_t
206RegisterContext::NumSupportedHardwareWatchpoints ()
207{
208 return 0;
209}
210
211uint32_t
212RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
213{
214 return LLDB_INVALID_INDEX32;
215}
216
217bool
218RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
219{
220 return false;
221}
222
223bool
224RegisterContext::HardwareSingleStep (bool enable)
225{
226 return false;
227}
228
Greg Clayton061b79d2011-05-09 20:18:18 +0000229Error
230RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info,
231 lldb::addr_t src_addr,
232 uint32_t src_len,
233 RegisterValue &reg_value)
234{
235 Error error;
236 if (reg_info == NULL)
237 {
238 error.SetErrorString ("invalid register info argument.");
239 return error;
240 }
241
242
243 // Moving from addr into a register
244 //
245 // Case 1: src_len == dst_len
246 //
247 // |AABBCCDD| Address contents
248 // |AABBCCDD| Register contents
249 //
250 // Case 2: src_len > dst_len
251 //
252 // Error! (The register should always be big enough to hold the data)
253 //
254 // Case 3: src_len < dst_len
255 //
256 // |AABB| Address contents
257 // |AABB0000| Register contents [on little-endian hardware]
258 // |0000AABB| Register contents [on big-endian hardware]
259 if (src_len > RegisterValue::kMaxRegisterByteSize)
260 {
261 error.SetErrorString ("register too small to receive memory data");
262 return error;
263 }
264
265 const uint32_t dst_len = reg_info->byte_size;
266
267 if (src_len > dst_len)
268 {
269 error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len);
270 return error;
271 }
272
273 Process &process = m_thread.GetProcess();
274 uint8_t src[RegisterValue::kMaxRegisterByteSize];
275
276 // Read the memory
277 const uint32_t bytes_read = process.ReadMemory (src_addr, src, src_len, error);
278
279 // Make sure the memory read succeeded...
280 if (bytes_read != src_len)
281 {
282 if (error.Success())
283 {
284 // This might happen if we read _some_ bytes but not all
285 error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len);
286 }
287 return error;
288 }
289
290 // We now have a memory buffer that contains the part or all of the register
291 // value. Set the register value using this memory data.
292 // TODO: we might need to add a parameter to this function in case the byte
293 // order of the memory data doesn't match the process. For now we are assuming
294 // they are the same.
295 reg_value.SetFromMemoryData (reg_info,
296 src,
297 src_len,
298 process.GetByteOrder(),
299 error);
300 return error;
301}
302
303Error
304RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
305 lldb::addr_t dst_addr,
306 uint32_t dst_len,
307 const RegisterValue &reg_value)
308{
309
310 uint8_t dst[RegisterValue::kMaxRegisterByteSize];
311
312 Error error;
313
314 Process &process = m_thread.GetProcess();
315
316 // TODO: we might need to add a parameter to this function in case the byte
317 // order of the memory data doesn't match the process. For now we are assuming
318 // they are the same.
319
320 const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
321 dst,
322 dst_len,
323 process.GetByteOrder(),
324 error);
325
326 if (error.Success())
327 {
328 if (bytes_copied == 0)
329 {
330 error.SetErrorString("byte copy failed.");
331 }
332 else
333 {
334 const uint32_t bytes_written = process.WriteMemory (dst_addr, dst, bytes_copied, error);
335 if (bytes_written != bytes_copied)
336 {
337 if (error.Success())
338 {
339 // This might happen if we read _some_ bytes but not all
340 error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied);
341 }
342 }
343 }
344 }
345
346 return error;
347
348}
349
Chris Lattner24943d22010-06-08 16:52:24 +0000350Target *
351RegisterContext::CalculateTarget ()
352{
353 return m_thread.CalculateTarget();
354}
355
356
357Process *
358RegisterContext::CalculateProcess ()
359{
360 return m_thread.CalculateProcess ();
361}
362
363Thread *
364RegisterContext::CalculateThread ()
365{
366 return &m_thread;
367}
368
369StackFrame *
370RegisterContext::CalculateStackFrame ()
371{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000372 // Register contexts might belong to many frames if we have inlined
373 // functions inside a frame since all inlined functions share the
374 // same registers, so we can't definitively say which frame we come from...
375 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000376}
377
378void
Greg Claytona830adb2010-10-04 01:05:56 +0000379RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx)
Chris Lattner24943d22010-06-08 16:52:24 +0000380{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000381 m_thread.CalculateExecutionContext (exe_ctx);
Chris Lattner24943d22010-06-08 16:52:24 +0000382}
383
384
Jason Molenda3a4ea242010-09-10 07:49:16 +0000385bool
Jason Molenda8280cbe2010-10-25 11:12:07 +0000386RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum)
Jason Molenda3a4ea242010-09-10 07:49:16 +0000387{
388 const uint32_t num_registers = GetRegisterCount();
389 for (uint32_t reg = 0; reg < num_registers; ++reg)
390 {
391 const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg);
Chris Lattner24943d22010-06-08 16:52:24 +0000392
Jason Molenda3a4ea242010-09-10 07:49:16 +0000393 if (reg_info->kinds[source_rk] == source_regnum)
394 {
395 target_regnum = reg_info->kinds[target_rk];
396 if (target_regnum == LLDB_INVALID_REGNUM)
397 {
398 return false;
399 }
400 else
401 {
402 return true;
403 }
404 }
405 }
406 return false;
407}
Jason Molenda8280cbe2010-10-25 11:12:07 +0000408
Greg Clayton061b79d2011-05-09 20:18:18 +0000409//bool
410//RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value)
411//{
412// DataExtractor data;
413// if (!ReadRegisterBytes (reg, data))
414// return false;
415//
416// const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
417// uint32_t offset = 0;
418// switch (reg_info->encoding)
419// {
420// case eEncodingInvalid:
421// case eEncodingVector:
422// break;
423//
424// case eEncodingUint:
425// switch (reg_info->byte_size)
426// {
427// case 1:
428// {
429// value = data.GetU8 (&offset);
430// return true;
431// }
432// case 2:
433// {
434// value = data.GetU16 (&offset);
435// return true;
436// }
437// case 4:
438// {
439// value = data.GetU32 (&offset);
440// return true;
441// }
442// case 8:
443// {
444// value = data.GetU64 (&offset);
445// return true;
446// }
447// }
448// break;
449// case eEncodingSint:
450// switch (reg_info->byte_size)
451// {
452// case 1:
453// {
454// int8_t v;
455// if (data.ExtractBytes (0, sizeof (int8_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int8_t))
456// return false;
457// value = v;
458// return true;
459// }
460// case 2:
461// {
462// int16_t v;
463// if (data.ExtractBytes (0, sizeof (int16_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int16_t))
464// return false;
465// value = v;
466// return true;
467// }
468// case 4:
469// {
470// int32_t v;
471// if (data.ExtractBytes (0, sizeof (int32_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int32_t))
472// return false;
473// value = v;
474// return true;
475// }
476// case 8:
477// {
478// int64_t v;
479// if (data.ExtractBytes (0, sizeof (int64_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int64_t))
480// return false;
481// value = v;
482// return true;
483// }
484// }
485// break;
486// case eEncodingIEEE754:
487// switch (reg_info->byte_size)
488// {
489// case sizeof (float):
490// {
491// float v;
492// if (data.ExtractBytes (0, sizeof (float), lldb::endian::InlHostByteOrder(), &v) != sizeof (float))
493// return false;
494// value = v;
495// return true;
496// }
497// case sizeof (double):
498// {
499// double v;
500// if (data.ExtractBytes (0, sizeof (double), lldb::endian::InlHostByteOrder(), &v) != sizeof (double))
501// return false;
502// value = v;
503// return true;
504// }
505// case sizeof (long double):
506// {
507// double v;
508// if (data.ExtractBytes (0, sizeof (long double), lldb::endian::InlHostByteOrder(), &v) != sizeof (long double))
509// return false;
510// value = v;
511// return true;
512// }
513// }
514// break;
515// }
516// return false;
517//}
518//
519//bool
520//RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value)
521//{
522// DataExtractor data;
523// if (!value.IsValid())
524// return false;
525// if (!value.GetData (data))
526// return false;
527//
528// return WriteRegisterBytes (reg, data);
529//}