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::GetClangType ()
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::GetClangAST ()
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     ExecutionContextScope *exe_scope = GetExecutionContextScope();
81     StackFrame *frame = exe_scope->CalculateStackFrame();
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         new_valobj = new ValueObjectRegisterSet(GetExecutionContextScope(), m_reg_ctx_sp, idx);
106 
107     return new_valobj;
108 }
109 
110 
111 #pragma mark -
112 #pragma mark ValueObjectRegisterSet
113 
114 ValueObjectSP
115 ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
116 {
117     return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
118 }
119 
120 
121 ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_set_idx) :
122     ValueObject (exe_scope),
123     m_reg_ctx_sp (reg_ctx),
124     m_reg_set (NULL),
125     m_reg_set_idx (reg_set_idx)
126 {
127     assert (reg_ctx);
128     m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
129     if (m_reg_set)
130     {
131         m_name.SetCString (m_reg_set->name);
132     }
133 }
134 
135 ValueObjectRegisterSet::~ValueObjectRegisterSet()
136 {
137 }
138 
139 lldb::clang_type_t
140 ValueObjectRegisterSet::GetClangType ()
141 {
142     return NULL;
143 }
144 
145 ConstString
146 ValueObjectRegisterSet::GetTypeName()
147 {
148     return ConstString();
149 }
150 
151 uint32_t
152 ValueObjectRegisterSet::CalculateNumChildren()
153 {
154     const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
155     if (reg_set)
156         return reg_set->num_registers;
157     return 0;
158 }
159 
160 clang::ASTContext *
161 ValueObjectRegisterSet::GetClangAST ()
162 {
163     return NULL;
164 }
165 
166 size_t
167 ValueObjectRegisterSet::GetByteSize()
168 {
169     return 0;
170 }
171 
172 bool
173 ValueObjectRegisterSet::UpdateValue ()
174 {
175     m_error.Clear();
176     SetValueDidChange (false);
177     ExecutionContextScope *exe_scope = GetExecutionContextScope();
178     StackFrame *frame = exe_scope->CalculateStackFrame();
179     if (frame == NULL)
180         m_reg_ctx_sp.reset();
181     else
182     {
183         m_reg_ctx_sp = frame->GetRegisterContext ();
184         if (m_reg_ctx_sp)
185         {
186             const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
187             if (reg_set == NULL)
188                 m_reg_ctx_sp.reset();
189             else if (m_reg_set != reg_set)
190             {
191                 SetValueDidChange (true);
192                 m_name.SetCString(reg_set->name);
193             }
194         }
195     }
196     if (m_reg_ctx_sp)
197     {
198         SetValueIsValid (true);
199     }
200     else
201     {
202         SetValueIsValid (false);
203         m_error.SetErrorToGenericError ();
204         m_children.clear();
205     }
206     return m_error.Success();
207 }
208 
209 
210 ValueObject *
211 ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
212 {
213     ValueObject *valobj;
214     if (m_reg_ctx_sp && m_reg_set)
215     {
216         const uint32_t num_children = GetNumChildren();
217         if (idx < num_children)
218             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
219     }
220     return valobj;
221 }
222 
223 lldb::ValueObjectSP
224 ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
225 {
226     ValueObject *valobj = NULL;
227     if (m_reg_ctx_sp && m_reg_set)
228     {
229         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
230         if (reg_info != NULL)
231             valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
232     }
233     if (valobj)
234         return valobj->GetSP();
235     else
236         return ValueObjectSP();
237 }
238 
239 uint32_t
240 ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
241 {
242     if (m_reg_ctx_sp && m_reg_set)
243     {
244         const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
245         if (reg_info != NULL)
246             return reg_info->kinds[eRegisterKindLLDB];
247     }
248     return UINT32_MAX;
249 }
250 
251 #pragma mark -
252 #pragma mark ValueObjectRegister
253 
254 void
255 ValueObjectRegister::ConstructObject ()
256 {
257     m_reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_num);
258     if (m_reg_info)
259     {
260         if (m_reg_info->name)
261             m_name.SetCString(m_reg_info->name);
262         else if (m_reg_info->alt_name)
263             m_name.SetCString(m_reg_info->alt_name);
264     }
265 }
266 
267 ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
268     ValueObject (parent),
269     m_reg_ctx_sp (reg_ctx),
270     m_reg_info (NULL),
271     m_reg_num (reg_num),
272     m_type_name (),
273     m_clang_type (NULL)
274 {
275     assert (reg_ctx);
276     ConstructObject();
277 }
278 
279 ValueObjectSP
280 ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
281 {
282     return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
283 }
284 
285 ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
286     ValueObject (exe_scope),
287     m_reg_ctx_sp (reg_ctx),
288     m_reg_info (NULL),
289     m_reg_num (reg_num),
290     m_type_name (),
291     m_clang_type (NULL)
292 {
293     assert (reg_ctx);
294     ConstructObject();
295 }
296 
297 ValueObjectRegister::~ValueObjectRegister()
298 {
299 }
300 
301 lldb::clang_type_t
302 ValueObjectRegister::GetClangType ()
303 {
304     if (m_clang_type == NULL && m_reg_info)
305     {
306         Process *process = m_reg_ctx_sp->CalculateProcess ();
307         if (process)
308         {
309             Module *exe_module = process->GetTarget().GetExecutableModule ().get();
310             if (exe_module)
311             {
312                 m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info->encoding, m_reg_info->byte_size * 8);
313             }
314         }
315     }
316     return m_clang_type;
317 }
318 
319 ConstString
320 ValueObjectRegister::GetTypeName()
321 {
322     if (m_type_name.IsEmpty())
323         m_type_name = ClangASTType::GetClangTypeName (GetClangType());
324     return m_type_name;
325 }
326 
327 uint32_t
328 ValueObjectRegister::CalculateNumChildren()
329 {
330     return 0;
331 }
332 
333 clang::ASTContext *
334 ValueObjectRegister::GetClangAST ()
335 {
336     Process *process = m_reg_ctx_sp->CalculateProcess ();
337     if (process)
338     {
339         Module *exe_module = process->GetTarget().GetExecutableModule ().get();
340         if (exe_module)
341             return exe_module->GetClangASTContext().getASTContext();
342     }
343     return NULL;
344 }
345 
346 size_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     ExecutionContextScope *exe_scope = GetExecutionContextScope();
357     StackFrame *frame = exe_scope->CalculateStackFrame();
358     if (frame)
359     {
360         m_reg_ctx_sp = frame->GetRegisterContext();
361         if (m_reg_ctx_sp)
362         {
363             const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_num);
364             if (m_reg_info != reg_info)
365             {
366                 m_reg_info = reg_info;
367                 if (m_reg_info)
368                 {
369                     if (m_reg_info->name)
370                         m_name.SetCString(m_reg_info->name);
371                     else if (m_reg_info->alt_name)
372                         m_name.SetCString(m_reg_info->alt_name);
373                 }
374             }
375         }
376     }
377     else
378     {
379         m_reg_ctx_sp.reset();
380         m_reg_info = NULL;
381     }
382 
383 
384     if (m_reg_ctx_sp && m_reg_info)
385     {
386         if (m_reg_ctx_sp->ReadRegisterBytes (m_reg_num, m_data))
387         {
388             m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)m_reg_info);
389             m_value.SetValueType(Value::eValueTypeHostAddress);
390             m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
391             SetValueIsValid (true);
392             return true;
393         }
394     }
395 
396     SetValueIsValid (false);
397     m_error.SetErrorToGenericError ();
398     return false;
399 }
400 
401 
402