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 (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->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.reset();
85 
86     SetValueIsValid (m_reg_ctx.get() != 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, lldb::RegisterContextSP &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 lldb::clang_type_t
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.reset();
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.reset();
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, lldb::RegisterContextSP &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 lldb::clang_type_t
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                 m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info->encoding, m_reg_info->byte_size * 8);
242             }
243         }
244     }
245     return m_clang_type;
246 }
247 
248 ConstString
249 ValueObjectRegister::GetTypeName()
250 {
251     if (m_type_name.IsEmpty())
252         m_type_name = ClangASTType::GetClangTypeName (GetClangType());
253     return m_type_name;
254 }
255 
256 uint32_t
257 ValueObjectRegister::CalculateNumChildren()
258 {
259     return 0;
260 }
261 
262 clang::ASTContext *
263 ValueObjectRegister::GetClangAST ()
264 {
265     Process *process = m_reg_ctx->CalculateProcess ();
266     if (process)
267     {
268         Module *exe_module = process->GetTarget().GetExecutableModule ().get();
269         if (exe_module)
270             return exe_module->GetClangASTContext().getASTContext();
271     }
272     return NULL;
273 }
274 
275 size_t
276 ValueObjectRegister::GetByteSize()
277 {
278     return m_reg_info->byte_size;
279 }
280 
281 void
282 ValueObjectRegister::UpdateValue (ExecutionContextScope *exe_scope)
283 {
284     m_error.Clear();
285     StackFrame *frame = exe_scope->CalculateStackFrame();
286     if (frame)
287     {
288         m_reg_ctx = frame->GetRegisterContext();
289         if (m_reg_ctx)
290         {
291             const RegisterInfo *reg_info = m_reg_ctx->GetRegisterInfoAtIndex(m_reg_num);
292             if (m_reg_info != reg_info)
293             {
294                 m_reg_info = reg_info;
295                 if (m_reg_info)
296                 {
297                     if (m_reg_info->name)
298                         m_name.SetCString(m_reg_info->name);
299                     else if (m_reg_info->alt_name)
300                         m_name.SetCString(m_reg_info->alt_name);
301                 }
302             }
303         }
304     }
305     else
306     {
307         m_reg_ctx.reset();
308         m_reg_info = NULL;
309     }
310 
311 
312     if (m_reg_ctx && m_reg_info)
313     {
314         if (m_reg_ctx->ReadRegisterBytes (m_reg_num, m_data))
315         {
316             m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)m_reg_info);
317             m_value.SetValueType(Value::eValueTypeHostAddress);
318             m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
319             SetValueIsValid (true);
320             return;
321         }
322     }
323     SetValueIsValid (false);
324 }
325 
326 
327