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