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/ClangASTContext.h"
19 #include "lldb/Symbol/TypeList.h"
20 #include "lldb/Target/ExecutionContext.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 #pragma mark ValueObjectRegisterContext
30 
31 ValueObjectRegisterContext::ValueObjectRegisterContext (RegisterContext *reg_ctx) :
32     ValueObject (),
33     m_reg_ctx (reg_ctx)
34 {
35     assert (reg_ctx);
36     m_name.SetCString("Registers");
37     SetValueIsValid (true);
38 }
39 
40 ValueObjectRegisterContext::~ValueObjectRegisterContext()
41 {
42 }
43 
44 void *
45 ValueObjectRegisterContext::GetOpaqueClangQualType ()
46 {
47     return NULL;
48 }
49 
50 ConstString
51 ValueObjectRegisterContext::GetTypeName()
52 {
53     ConstString empty_type_name;
54     return empty_type_name;
55 }
56 
57 uint32_t
58 ValueObjectRegisterContext::CalculateNumChildren()
59 {
60     return m_reg_ctx->GetRegisterSetCount();
61 }
62 
63 clang::ASTContext *
64 ValueObjectRegisterContext::GetClangAST ()
65 {
66     return NULL;
67 }
68 
69 size_t
70 ValueObjectRegisterContext::GetByteSize()
71 {
72     return 0;
73 }
74 
75 void
76 ValueObjectRegisterContext::UpdateValue (ExecutionContextScope *exe_scope)
77 {
78     m_error.Clear();
79     StackFrame *frame = exe_scope->CalculateStackFrame();
80     if (frame)
81         m_reg_ctx = frame->GetRegisterContext();
82     else
83         m_reg_ctx = NULL;
84 
85     SetValueIsValid (m_reg_ctx != NULL);
86 }
87 
88 ValueObjectSP
89 ValueObjectRegisterContext::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
90 {
91     ValueObjectSP valobj_sp;
92 
93     const uint32_t num_children = GetNumChildren();
94     if (idx < num_children)
95         valobj_sp.reset (new ValueObjectRegisterSet(m_reg_ctx, idx));
96     return valobj_sp;
97 }
98 
99 
100 #pragma mark -
101 #pragma mark ValueObjectRegisterSet
102 
103 ValueObjectRegisterSet::ValueObjectRegisterSet (RegisterContext *reg_ctx, uint32_t reg_set_idx) :
104     ValueObject (),
105     m_reg_ctx (reg_ctx),
106     m_reg_set (NULL),
107     m_reg_set_idx (reg_set_idx)
108 {
109     assert (reg_ctx);
110     m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
111     if (m_reg_set)
112     {
113         m_name.SetCString (m_reg_set->name);
114     }
115 }
116 
117 ValueObjectRegisterSet::~ValueObjectRegisterSet()
118 {
119 }
120 
121 void *
122 ValueObjectRegisterSet::GetOpaqueClangQualType ()
123 {
124     return NULL;
125 }
126 
127 ConstString
128 ValueObjectRegisterSet::GetTypeName()
129 {
130     return ConstString();
131 }
132 
133 uint32_t
134 ValueObjectRegisterSet::CalculateNumChildren()
135 {
136     const RegisterSet *reg_set = m_reg_ctx->GetRegisterSet(m_reg_set_idx);
137     if (reg_set)
138         return reg_set->num_registers;
139     return 0;
140 }
141 
142 clang::ASTContext *
143 ValueObjectRegisterSet::GetClangAST ()
144 {
145     return NULL;
146 }
147 
148 size_t
149 ValueObjectRegisterSet::GetByteSize()
150 {
151     return 0;
152 }
153 
154 void
155 ValueObjectRegisterSet::UpdateValue (ExecutionContextScope *exe_scope)
156 {
157     m_error.Clear();
158     SetValueDidChange (false);
159     StackFrame *frame = exe_scope->CalculateStackFrame();
160     if (frame == NULL)
161         m_reg_ctx = NULL;
162     else
163     {
164         m_reg_ctx = frame->GetRegisterContext ();
165         if (m_reg_ctx)
166         {
167             const RegisterSet *reg_set = m_reg_ctx->GetRegisterSet (m_reg_set_idx);
168             if (reg_set == NULL)
169                 m_reg_ctx = NULL;
170             else if (m_reg_set != reg_set)
171             {
172                 SetValueDidChange (true);
173                 m_name.SetCString(reg_set->name);
174             }
175         }
176     }
177     if (m_reg_ctx)
178     {
179         SetValueIsValid (true);
180     }
181     else
182     {
183         SetValueIsValid (false);
184         m_children.clear();
185     }
186 }
187 
188 
189 ValueObjectSP
190 ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
191 {
192     ValueObjectSP valobj_sp;
193     if (m_reg_ctx && m_reg_set)
194     {
195         const uint32_t num_children = GetNumChildren();
196         if (idx < num_children)
197             valobj_sp.reset (new ValueObjectRegister(m_reg_ctx, m_reg_set->registers[idx]));
198     }
199     return valobj_sp;
200 }
201 
202 
203 #pragma mark -
204 #pragma mark ValueObjectRegister
205 
206 ValueObjectRegister::ValueObjectRegister (RegisterContext *reg_ctx, uint32_t reg_num) :
207     ValueObject (),
208     m_reg_ctx (reg_ctx),
209     m_reg_info (NULL),
210     m_reg_num (reg_num),
211     m_type_name (),
212     m_clang_type (NULL)
213 {
214     assert (reg_ctx);
215     m_reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
216     if (m_reg_info)
217     {
218         if (m_reg_info->name)
219             m_name.SetCString(m_reg_info->name);
220         else if (m_reg_info->alt_name)
221             m_name.SetCString(m_reg_info->alt_name);
222     }
223 }
224 
225 ValueObjectRegister::~ValueObjectRegister()
226 {
227 }
228 
229 void *
230 ValueObjectRegister::GetOpaqueClangQualType ()
231 {
232     if (m_clang_type == NULL && m_reg_info)
233     {
234         Process *process = m_reg_ctx->CalculateProcess ();
235         if (process)
236         {
237             Module *exe_module = process->GetTarget().GetExecutableModule ().get();
238             if (exe_module)
239             {
240                 TypeList *type_list = exe_module->GetTypeList();
241                 if (type_list)
242                     m_clang_type = type_list->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info->encoding, m_reg_info->byte_size * 8);
243             }
244         }
245     }
246     return m_clang_type;
247 }
248 
249 ConstString
250 ValueObjectRegister::GetTypeName()
251 {
252     if (m_type_name.IsEmpty())
253         m_type_name = Type::GetClangTypeName (GetOpaqueClangQualType());
254     return m_type_name;
255 }
256 
257 uint32_t
258 ValueObjectRegister::CalculateNumChildren()
259 {
260     return 0;
261 }
262 
263 clang::ASTContext *
264 ValueObjectRegister::GetClangAST ()
265 {
266     Process *process = m_reg_ctx->CalculateProcess ();
267     if (process)
268     {
269         Module *exe_module = process->GetTarget().GetExecutableModule ().get();
270         if (exe_module)
271         {
272             TypeList *type_list = exe_module->GetTypeList();
273             if (type_list)
274                 return type_list->GetClangASTContext().getASTContext();
275         }
276     }
277     return NULL;
278 }
279 
280 size_t
281 ValueObjectRegister::GetByteSize()
282 {
283     return m_reg_info->byte_size;
284 }
285 
286 void
287 ValueObjectRegister::UpdateValue (ExecutionContextScope *exe_scope)
288 {
289     m_error.Clear();
290     StackFrame *frame = exe_scope->CalculateStackFrame();
291     if (frame)
292     {
293         m_reg_ctx = frame->GetRegisterContext();
294         if (m_reg_ctx)
295         {
296             const RegisterInfo *reg_info = m_reg_ctx->GetRegisterInfoAtIndex(m_reg_num);
297             if (m_reg_info != reg_info)
298             {
299                 m_reg_info = reg_info;
300                 if (m_reg_info)
301                 {
302                     if (m_reg_info->name)
303                         m_name.SetCString(m_reg_info->name);
304                     else if (m_reg_info->alt_name)
305                         m_name.SetCString(m_reg_info->alt_name);
306                 }
307             }
308         }
309     }
310     else
311     {
312         m_reg_ctx = NULL;
313         m_reg_info = NULL;
314     }
315 
316 
317     if (m_reg_ctx && m_reg_info)
318     {
319         if (m_reg_ctx->ReadRegisterBytes (m_reg_num, m_data))
320         {
321             m_value.SetContext(Value::eContextTypeDCRegisterInfo, (void *)m_reg_info);
322             m_value.SetValueType(Value::eValueTypeHostAddress);
323             m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
324             SetValueIsValid (true);
325             return;
326         }
327     }
328     SetValueIsValid (false);
329 }
330 
331 
332