1 //===-- ValueObjectRegister.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 
11 #include "lldb/Core/ValueObjectRegister.h"
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Module.h"
18 #include "lldb/Symbol/ClangASTType.h"
19 #include "lldb/Symbol/ClangASTContext.h"
20 #include "lldb/Symbol/TypeList.h"
21 #include "lldb/Target/ExecutionContext.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 #pragma mark ValueObjectRegisterContext
31 
32 ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP &reg_ctx) :
33     ValueObject (parent),
34     m_reg_ctx_sp (reg_ctx)
35 {
36     assert (reg_ctx);
37     m_name.SetCString("Registers");
38     SetValueIsValid (true);
39 }
40 
41 ValueObjectRegisterContext::~ValueObjectRegisterContext()
42 {
43 }
44 
45 lldb::clang_type_t
46 ValueObjectRegisterContext::GetClangTypeImpl ()
47 {
48     return NULL;
49 }
50 
51 ConstString
52 ValueObjectRegisterContext::GetTypeName()
53 {
54     ConstString empty_type_name;
55     return empty_type_name;
56 }
57 
58 uint32_t
59 ValueObjectRegisterContext::CalculateNumChildren()
60 {
61     return m_reg_ctx_sp->GetRegisterSetCount();
62 }
63 
64 clang::ASTContext *
65 ValueObjectRegisterContext::GetClangASTImpl ()
66 {
67     return NULL;
68 }
69 
70 size_t
71 ValueObjectRegisterContext::GetByteSize()
72 {
73     return 0;
74 }
75 
76 bool
77 ValueObjectRegisterContext::UpdateValue ()
78 {
79     m_error.Clear();
80     ExecutionContext exe_ctx(GetExecutionContextRef());
81     StackFrame *frame = exe_ctx.GetFramePtr();
82     if (frame)
83         m_reg_ctx_sp = frame->GetRegisterContext();
84     else
85         m_reg_ctx_sp.reset();
86 
87     if (m_reg_ctx_sp.get() == NULL)
88     {
89         SetValueIsValid (false);
90         m_error.SetErrorToGenericError();
91     }
92     else
93         SetValueIsValid (true);
94 
95     return m_error.Success();
96 }
97 
98 ValueObject *
99 ValueObjectRegisterContext::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
100 {
101     ValueObject *new_valobj = NULL;
102 
103     const uint32_t num_children = GetNumChildren();
104     if (idx < num_children)
105     {
106         ExecutionContext exe_ctx(GetExecutionContextRef());
107         new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
108     }
109 
110     return new_valobj;
111 }
112 
113 
114 #pragma mark -
115 #pragma mark ValueObjectRegisterSet
116 
117 ValueObjectSP
118 ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
119 {
120     return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
121 }
122 
123 
124 ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_set_idx) :
125     ValueObject (exe_scope),
126     m_reg_ctx_sp (reg_ctx),
127     m_reg_set (NULL),
128     m_reg_set_idx (reg_set_idx)
129 {
130     assert (reg_ctx);
131     m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
132     if (m_reg_set)
133     {
134         m_name.SetCString (m_reg_set->name);
135     }
136 }
137 
138 ValueObjectRegisterSet::~ValueObjectRegisterSet()
139 {
140 }
141 
142 lldb::clang_type_t
143 ValueObjectRegisterSet::GetClangTypeImpl ()
144 {
145     return NULL;
146 }
147 
148 ConstString
149 ValueObjectRegisterSet::GetTypeName()
150 {
151     return ConstString();
152 }
153 
154 uint32_t
155 ValueObjectRegisterSet::CalculateNumChildren()
156 {
157     const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
158     if (reg_set)
159         return reg_set->num_registers;
160     return 0;
161 }
162 
163 clang::ASTContext *
164 ValueObjectRegisterSet::GetClangASTImpl ()
165 {
166     return NULL;
167 }
168 
169 size_t
170 ValueObjectRegisterSet::GetByteSize()
171 {
172     return 0;
173 }
174 
175 bool
176 ValueObjectRegisterSet::UpdateValue ()
177 {
178     m_error.Clear();
179     SetValueDidChange (false);
180     ExecutionContext exe_ctx(GetExecutionContextRef());
181     StackFrame *frame = exe_ctx.GetFramePtr();
182     if (frame == NULL)
183         m_reg_ctx_sp.reset();
184     else
185     {
186         m_reg_ctx_sp = frame->GetRegisterContext ();
187         if (m_reg_ctx_sp)
188         {
189             const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
190             if (reg_set == NULL)
191                 m_reg_ctx_sp.reset();
192             else if (m_reg_set != reg_set)
193             {
194                 SetValueDidChange (true);
195                 m_name.SetCString(reg_set->name);
196             }
197         }
198     }
199     if (m_reg_ctx_sp)
200     {
201         SetValueIsValid (true);
202     }
203     else
204     {
205         SetValueIsValid (false);
206         m_error.SetErrorToGenericError ();
207         m_children.Clear();
208     }
209     return m_error.Success();
210 }
211 
212 
213 ValueObject *
214 ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
215 {
216     ValueObject *valobj = NULL;
217     if (m_reg_ctx_sp && m_reg_set)
218     {
219         const uint32_t num_children = GetNumChildren();
220         if (idx < num_children)
221             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
222     }
223     return valobj;
224 }
225 
226 lldb::ValueObjectSP
227 ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
228 {
229     ValueObject *valobj = NULL;
230     if (m_reg_ctx_sp && m_reg_set)
231     {
232         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
233         if (reg_info != NULL)
234             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
235     }
236     if (valobj)
237         return valobj->GetSP();
238     else
239         return ValueObjectSP();
240 }
241 
242 uint32_t
243 ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
244 {
245     if (m_reg_ctx_sp && m_reg_set)
246     {
247         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
248         if (reg_info != NULL)
249             return reg_info->kinds[eRegisterKindLLDB];
250     }
251     return UINT32_MAX;
252 }
253 
254 #pragma mark -
255 #pragma mark ValueObjectRegister
256 
257 void
258 ValueObjectRegister::ConstructObject (uint32_t reg_num)
259 {
260     const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
261     if (reg_info)
262     {
263         m_reg_info = *reg_info;
264         if (reg_info->name)
265             m_name.SetCString(reg_info->name);
266         else if (reg_info->alt_name)
267             m_name.SetCString(reg_info->alt_name);
268     }
269 }
270 
271 ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num) :
272     ValueObject (parent),
273     m_reg_ctx_sp (reg_ctx_sp),
274     m_reg_info (),
275     m_reg_value (),
276     m_type_name (),
277     m_clang_type (NULL)
278 {
279     assert (reg_ctx_sp.get());
280     ConstructObject(reg_num);
281 }
282 
283 ValueObjectSP
284 ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
285 {
286     return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
287 }
288 
289 ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
290     ValueObject (exe_scope),
291     m_reg_ctx_sp (reg_ctx),
292     m_reg_info (),
293     m_reg_value (),
294     m_type_name (),
295     m_clang_type (NULL)
296 {
297     assert (reg_ctx);
298     ConstructObject(reg_num);
299 }
300 
301 ValueObjectRegister::~ValueObjectRegister()
302 {
303 }
304 
305 lldb::clang_type_t
306 ValueObjectRegister::GetClangTypeImpl ()
307 {
308     if (m_clang_type == NULL)
309     {
310         ExecutionContext exe_ctx (GetExecutionContextRef());
311         Target *target = exe_ctx.GetTargetPtr();
312         if (target)
313         {
314             Module *exe_module = target->GetExecutableModulePointer();
315             if (exe_module)
316             {
317                 m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding,
318                                                                                                      m_reg_info.byte_size * 8);
319             }
320         }
321     }
322     return m_clang_type;
323 }
324 
325 ConstString
326 ValueObjectRegister::GetTypeName()
327 {
328     if (m_type_name.IsEmpty())
329         m_type_name = ClangASTType::GetConstTypeName (GetClangType());
330     return m_type_name;
331 }
332 
333 uint32_t
334 ValueObjectRegister::CalculateNumChildren()
335 {
336     return 0;
337 }
338 
339 clang::ASTContext *
340 ValueObjectRegister::GetClangASTImpl ()
341 {
342     ExecutionContext exe_ctx (GetExecutionContextRef());
343     Target *target = exe_ctx.GetTargetPtr();
344     if (target)
345     {
346         Module *exe_module = target->GetExecutableModulePointer();
347         if (exe_module)
348             return exe_module->GetClangASTContext().getASTContext();
349     }
350     return NULL;
351 }
352 
353 size_t
354 ValueObjectRegister::GetByteSize()
355 {
356     return m_reg_info.byte_size;
357 }
358 
359 bool
360 ValueObjectRegister::UpdateValue ()
361 {
362     m_error.Clear();
363     ExecutionContext exe_ctx(GetExecutionContextRef());
364     StackFrame *frame = exe_ctx.GetFramePtr();
365     if (frame == NULL)
366     {
367         m_reg_ctx_sp.reset();
368         m_reg_value.Clear();
369     }
370 
371 
372     if (m_reg_ctx_sp)
373     {
374         if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
375         {
376             if (m_reg_value.GetData (m_data))
377             {
378                 Process *process = exe_ctx.GetProcessPtr();
379                 if (process)
380                     m_data.SetAddressByteSize(process->GetAddressByteSize());
381                 m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
382                 m_value.SetValueType(Value::eValueTypeHostAddress);
383                 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
384                 SetValueIsValid (true);
385                 return true;
386             }
387         }
388     }
389 
390     SetValueIsValid (false);
391     m_error.SetErrorToGenericError ();
392     return false;
393 }
394 
395 bool
396 ValueObjectRegister::SetValueFromCString (const char *value_str)
397 {
398     // The new value will be in the m_data.  Copy that into our register value.
399     Error error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
400     if (error.Success())
401     {
402         if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
403         {
404             SetNeedsUpdate();
405             return true;
406         }
407         else
408             return false;
409     }
410     else
411         return false;
412 }
413 
414 bool
415 ValueObjectRegister::ResolveValue (Scalar &scalar)
416 {
417     if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
418         return m_reg_value.GetScalarValue(scalar);
419     return false;
420 }
421 
422 
423