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     return ConstString();
55 }
56 
57 ConstString
58 ValueObjectRegisterContext::GetQualifiedTypeName()
59 {
60     return ConstString();
61 }
62 
63 uint32_t
64 ValueObjectRegisterContext::CalculateNumChildren()
65 {
66     return m_reg_ctx_sp->GetRegisterSetCount();
67 }
68 
69 clang::ASTContext *
70 ValueObjectRegisterContext::GetClangASTImpl ()
71 {
72     return NULL;
73 }
74 
75 size_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 (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
105 {
106     ValueObject *new_valobj = NULL;
107 
108     const uint32_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 lldb::clang_type_t
148 ValueObjectRegisterSet::GetClangTypeImpl ()
149 {
150     return NULL;
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 uint32_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 clang::ASTContext *
175 ValueObjectRegisterSet::GetClangASTImpl ()
176 {
177     return NULL;
178 }
179 
180 size_t
181 ValueObjectRegisterSet::GetByteSize()
182 {
183     return 0;
184 }
185 
186 bool
187 ValueObjectRegisterSet::UpdateValue ()
188 {
189     m_error.Clear();
190     SetValueDidChange (false);
191     ExecutionContext exe_ctx(GetExecutionContextRef());
192     StackFrame *frame = exe_ctx.GetFramePtr();
193     if (frame == NULL)
194         m_reg_ctx_sp.reset();
195     else
196     {
197         m_reg_ctx_sp = frame->GetRegisterContext ();
198         if (m_reg_ctx_sp)
199         {
200             const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
201             if (reg_set == NULL)
202                 m_reg_ctx_sp.reset();
203             else if (m_reg_set != reg_set)
204             {
205                 SetValueDidChange (true);
206                 m_name.SetCString(reg_set->name);
207             }
208         }
209     }
210     if (m_reg_ctx_sp)
211     {
212         SetValueIsValid (true);
213     }
214     else
215     {
216         SetValueIsValid (false);
217         m_error.SetErrorToGenericError ();
218         m_children.Clear();
219     }
220     return m_error.Success();
221 }
222 
223 
224 ValueObject *
225 ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
226 {
227     ValueObject *valobj = NULL;
228     if (m_reg_ctx_sp && m_reg_set)
229     {
230         const uint32_t num_children = GetNumChildren();
231         if (idx < num_children)
232             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
233     }
234     return valobj;
235 }
236 
237 lldb::ValueObjectSP
238 ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
239 {
240     ValueObject *valobj = NULL;
241     if (m_reg_ctx_sp && m_reg_set)
242     {
243         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
244         if (reg_info != NULL)
245             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
246     }
247     if (valobj)
248         return valobj->GetSP();
249     else
250         return ValueObjectSP();
251 }
252 
253 uint32_t
254 ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
255 {
256     if (m_reg_ctx_sp && m_reg_set)
257     {
258         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
259         if (reg_info != NULL)
260             return reg_info->kinds[eRegisterKindLLDB];
261     }
262     return UINT32_MAX;
263 }
264 
265 #pragma mark -
266 #pragma mark ValueObjectRegister
267 
268 void
269 ValueObjectRegister::ConstructObject (uint32_t reg_num)
270 {
271     const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
272     if (reg_info)
273     {
274         m_reg_info = *reg_info;
275         if (reg_info->name)
276             m_name.SetCString(reg_info->name);
277         else if (reg_info->alt_name)
278             m_name.SetCString(reg_info->alt_name);
279     }
280 }
281 
282 ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num) :
283     ValueObject (parent),
284     m_reg_ctx_sp (reg_ctx_sp),
285     m_reg_info (),
286     m_reg_value (),
287     m_type_name (),
288     m_clang_type (NULL)
289 {
290     assert (reg_ctx_sp.get());
291     ConstructObject(reg_num);
292 }
293 
294 ValueObjectSP
295 ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
296 {
297     return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
298 }
299 
300 ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
301     ValueObject (exe_scope),
302     m_reg_ctx_sp (reg_ctx),
303     m_reg_info (),
304     m_reg_value (),
305     m_type_name (),
306     m_clang_type (NULL)
307 {
308     assert (reg_ctx);
309     ConstructObject(reg_num);
310 }
311 
312 ValueObjectRegister::~ValueObjectRegister()
313 {
314 }
315 
316 lldb::clang_type_t
317 ValueObjectRegister::GetClangTypeImpl ()
318 {
319     if (m_clang_type == NULL)
320     {
321         ExecutionContext exe_ctx (GetExecutionContextRef());
322         Target *target = exe_ctx.GetTargetPtr();
323         if (target)
324         {
325             Module *exe_module = target->GetExecutableModulePointer();
326             if (exe_module)
327             {
328                 m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding,
329                                                                                                      m_reg_info.byte_size * 8);
330             }
331         }
332     }
333     return m_clang_type;
334 }
335 
336 ConstString
337 ValueObjectRegister::GetTypeName()
338 {
339     if (m_type_name.IsEmpty())
340         m_type_name = ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
341     return m_type_name;
342 }
343 
344 uint32_t
345 ValueObjectRegister::CalculateNumChildren()
346 {
347     return 0;
348 }
349 
350 clang::ASTContext *
351 ValueObjectRegister::GetClangASTImpl ()
352 {
353     ExecutionContext exe_ctx (GetExecutionContextRef());
354     Target *target = exe_ctx.GetTargetPtr();
355     if (target)
356     {
357         Module *exe_module = target->GetExecutableModulePointer();
358         if (exe_module)
359             return exe_module->GetClangASTContext().getASTContext();
360     }
361     return NULL;
362 }
363 
364 size_t
365 ValueObjectRegister::GetByteSize()
366 {
367     return m_reg_info.byte_size;
368 }
369 
370 bool
371 ValueObjectRegister::UpdateValue ()
372 {
373     m_error.Clear();
374     ExecutionContext exe_ctx(GetExecutionContextRef());
375     StackFrame *frame = exe_ctx.GetFramePtr();
376     if (frame == NULL)
377     {
378         m_reg_ctx_sp.reset();
379         m_reg_value.Clear();
380     }
381 
382 
383     if (m_reg_ctx_sp)
384     {
385         if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
386         {
387             if (m_reg_value.GetData (m_data))
388             {
389                 Process *process = exe_ctx.GetProcessPtr();
390                 if (process)
391                     m_data.SetAddressByteSize(process->GetAddressByteSize());
392                 m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
393                 m_value.SetValueType(Value::eValueTypeHostAddress);
394                 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
395                 SetValueIsValid (true);
396                 return true;
397             }
398         }
399     }
400 
401     SetValueIsValid (false);
402     m_error.SetErrorToGenericError ();
403     return false;
404 }
405 
406 bool
407 ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error)
408 {
409     // The new value will be in the m_data.  Copy that into our register value.
410     error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
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