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