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