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