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