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