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