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
ValueObjectRegisterContext(ValueObject & parent,RegisterContextSP & reg_ctx)32 ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP ®_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
~ValueObjectRegisterContext()41 ValueObjectRegisterContext::~ValueObjectRegisterContext()
42 {
43 }
44
45 ClangASTType
GetClangTypeImpl()46 ValueObjectRegisterContext::GetClangTypeImpl ()
47 {
48 return ClangASTType();
49 }
50
51 ConstString
GetTypeName()52 ValueObjectRegisterContext::GetTypeName()
53 {
54 return ConstString();
55 }
56
57 ConstString
GetQualifiedTypeName()58 ValueObjectRegisterContext::GetQualifiedTypeName()
59 {
60 return ConstString();
61 }
62
63 size_t
CalculateNumChildren()64 ValueObjectRegisterContext::CalculateNumChildren()
65 {
66 return m_reg_ctx_sp->GetRegisterSetCount();
67 }
68
69 uint64_t
GetByteSize()70 ValueObjectRegisterContext::GetByteSize()
71 {
72 return 0;
73 }
74
75 bool
UpdateValue()76 ValueObjectRegisterContext::UpdateValue ()
77 {
78 m_error.Clear();
79 ExecutionContext exe_ctx(GetExecutionContextRef());
80 StackFrame *frame = exe_ctx.GetFramePtr();
81 if (frame)
82 m_reg_ctx_sp = frame->GetRegisterContext();
83 else
84 m_reg_ctx_sp.reset();
85
86 if (m_reg_ctx_sp.get() == NULL)
87 {
88 SetValueIsValid (false);
89 m_error.SetErrorToGenericError();
90 }
91 else
92 SetValueIsValid (true);
93
94 return m_error.Success();
95 }
96
97 ValueObject *
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)98 ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
99 {
100 ValueObject *new_valobj = NULL;
101
102 const size_t num_children = GetNumChildren();
103 if (idx < num_children)
104 {
105 ExecutionContext exe_ctx(GetExecutionContextRef());
106 new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
107 }
108
109 return new_valobj;
110 }
111
112
113 #pragma mark -
114 #pragma mark ValueObjectRegisterSet
115
116 ValueObjectSP
Create(ExecutionContextScope * exe_scope,lldb::RegisterContextSP & reg_ctx_sp,uint32_t set_idx)117 ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx)
118 {
119 return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
120 }
121
122
ValueObjectRegisterSet(ExecutionContextScope * exe_scope,lldb::RegisterContextSP & reg_ctx,uint32_t reg_set_idx)123 ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_set_idx) :
124 ValueObject (exe_scope),
125 m_reg_ctx_sp (reg_ctx),
126 m_reg_set (NULL),
127 m_reg_set_idx (reg_set_idx)
128 {
129 assert (reg_ctx);
130 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
131 if (m_reg_set)
132 {
133 m_name.SetCString (m_reg_set->name);
134 }
135 }
136
~ValueObjectRegisterSet()137 ValueObjectRegisterSet::~ValueObjectRegisterSet()
138 {
139 }
140
141 ClangASTType
GetClangTypeImpl()142 ValueObjectRegisterSet::GetClangTypeImpl ()
143 {
144 return ClangASTType();
145 }
146
147 ConstString
GetTypeName()148 ValueObjectRegisterSet::GetTypeName()
149 {
150 return ConstString();
151 }
152
153 ConstString
GetQualifiedTypeName()154 ValueObjectRegisterSet::GetQualifiedTypeName()
155 {
156 return ConstString();
157 }
158
159 size_t
CalculateNumChildren()160 ValueObjectRegisterSet::CalculateNumChildren()
161 {
162 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
163 if (reg_set)
164 return reg_set->num_registers;
165 return 0;
166 }
167
168 uint64_t
GetByteSize()169 ValueObjectRegisterSet::GetByteSize()
170 {
171 return 0;
172 }
173
174 bool
UpdateValue()175 ValueObjectRegisterSet::UpdateValue ()
176 {
177 m_error.Clear();
178 SetValueDidChange (false);
179 ExecutionContext exe_ctx(GetExecutionContextRef());
180 StackFrame *frame = exe_ctx.GetFramePtr();
181 if (frame == NULL)
182 m_reg_ctx_sp.reset();
183 else
184 {
185 m_reg_ctx_sp = frame->GetRegisterContext ();
186 if (m_reg_ctx_sp)
187 {
188 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
189 if (reg_set == NULL)
190 m_reg_ctx_sp.reset();
191 else if (m_reg_set != reg_set)
192 {
193 SetValueDidChange (true);
194 m_name.SetCString(reg_set->name);
195 }
196 }
197 }
198 if (m_reg_ctx_sp)
199 {
200 SetValueIsValid (true);
201 }
202 else
203 {
204 SetValueIsValid (false);
205 m_error.SetErrorToGenericError ();
206 m_children.Clear();
207 }
208 return m_error.Success();
209 }
210
211
212 ValueObject *
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)213 ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
214 {
215 ValueObject *valobj = NULL;
216 if (m_reg_ctx_sp && m_reg_set)
217 {
218 const size_t num_children = GetNumChildren();
219 if (idx < num_children)
220 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
221 }
222 return valobj;
223 }
224
225 lldb::ValueObjectSP
GetChildMemberWithName(const ConstString & name,bool can_create)226 ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
227 {
228 ValueObject *valobj = NULL;
229 if (m_reg_ctx_sp && m_reg_set)
230 {
231 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
232 if (reg_info != NULL)
233 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
234 }
235 if (valobj)
236 return valobj->GetSP();
237 else
238 return ValueObjectSP();
239 }
240
241 size_t
GetIndexOfChildWithName(const ConstString & name)242 ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
243 {
244 if (m_reg_ctx_sp && m_reg_set)
245 {
246 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
247 if (reg_info != NULL)
248 return reg_info->kinds[eRegisterKindLLDB];
249 }
250 return UINT32_MAX;
251 }
252
253 #pragma mark -
254 #pragma mark ValueObjectRegister
255
256 void
ConstructObject(uint32_t reg_num)257 ValueObjectRegister::ConstructObject (uint32_t reg_num)
258 {
259 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
260 if (reg_info)
261 {
262 m_reg_info = *reg_info;
263 if (reg_info->name)
264 m_name.SetCString(reg_info->name);
265 else if (reg_info->alt_name)
266 m_name.SetCString(reg_info->alt_name);
267 }
268 }
269
ValueObjectRegister(ValueObject & parent,lldb::RegisterContextSP & reg_ctx_sp,uint32_t reg_num)270 ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) :
271 ValueObject (parent),
272 m_reg_ctx_sp (reg_ctx_sp),
273 m_reg_info (),
274 m_reg_value (),
275 m_type_name (),
276 m_clang_type ()
277 {
278 assert (reg_ctx_sp.get());
279 ConstructObject(reg_num);
280 }
281
282 ValueObjectSP
Create(ExecutionContextScope * exe_scope,lldb::RegisterContextSP & reg_ctx_sp,uint32_t reg_num)283 ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num)
284 {
285 return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
286 }
287
ValueObjectRegister(ExecutionContextScope * exe_scope,lldb::RegisterContextSP & reg_ctx,uint32_t reg_num)288 ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) :
289 ValueObject (exe_scope),
290 m_reg_ctx_sp (reg_ctx),
291 m_reg_info (),
292 m_reg_value (),
293 m_type_name (),
294 m_clang_type ()
295 {
296 assert (reg_ctx);
297 ConstructObject(reg_num);
298 }
299
~ValueObjectRegister()300 ValueObjectRegister::~ValueObjectRegister()
301 {
302 }
303
304 ClangASTType
GetClangTypeImpl()305 ValueObjectRegister::GetClangTypeImpl ()
306 {
307 if (!m_clang_type.IsValid())
308 {
309 ExecutionContext exe_ctx (GetExecutionContextRef());
310 Target *target = exe_ctx.GetTargetPtr();
311 if (target)
312 {
313 Module *exe_module = target->GetExecutableModulePointer();
314 if (exe_module)
315 {
316 m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding,
317 m_reg_info.byte_size * 8);
318 }
319 }
320 }
321 return m_clang_type;
322 }
323
324 ConstString
GetTypeName()325 ValueObjectRegister::GetTypeName()
326 {
327 if (m_type_name.IsEmpty())
328 m_type_name = GetClangType().GetConstTypeName ();
329 return m_type_name;
330 }
331
332 size_t
CalculateNumChildren()333 ValueObjectRegister::CalculateNumChildren()
334 {
335 return GetClangType().GetNumChildren(true);
336 }
337
338 uint64_t
GetByteSize()339 ValueObjectRegister::GetByteSize()
340 {
341 return m_reg_info.byte_size;
342 }
343
344 bool
UpdateValue()345 ValueObjectRegister::UpdateValue ()
346 {
347 m_error.Clear();
348 ExecutionContext exe_ctx(GetExecutionContextRef());
349 StackFrame *frame = exe_ctx.GetFramePtr();
350 if (frame == NULL)
351 {
352 m_reg_ctx_sp.reset();
353 m_reg_value.Clear();
354 }
355
356
357 if (m_reg_ctx_sp)
358 {
359 if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
360 {
361 if (m_reg_value.GetData (m_data))
362 {
363 Process *process = exe_ctx.GetProcessPtr();
364 if (process)
365 m_data.SetAddressByteSize(process->GetAddressByteSize());
366 m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
367 m_value.SetValueType(Value::eValueTypeHostAddress);
368 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
369 SetValueIsValid (true);
370 return true;
371 }
372 }
373 }
374
375 SetValueIsValid (false);
376 m_error.SetErrorToGenericError ();
377 return false;
378 }
379
380 bool
SetValueFromCString(const char * value_str,Error & error)381 ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error)
382 {
383 // The new value will be in the m_data. Copy that into our register value.
384 error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
385 if (error.Success())
386 {
387 if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
388 {
389 SetNeedsUpdate();
390 return true;
391 }
392 else
393 return false;
394 }
395 else
396 return false;
397 }
398
399 bool
SetData(DataExtractor & data,Error & error)400 ValueObjectRegister::SetData (DataExtractor &data, Error &error)
401 {
402 error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
403 if (error.Success())
404 {
405 if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
406 {
407 SetNeedsUpdate();
408 return true;
409 }
410 else
411 return false;
412 }
413 else
414 return false;
415 }
416
417 bool
ResolveValue(Scalar & scalar)418 ValueObjectRegister::ResolveValue (Scalar &scalar)
419 {
420 if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
421 return m_reg_value.GetScalarValue(scalar);
422 return false;
423 }
424
425 void
GetExpressionPath(Stream & s,bool qualify_cxx_base_classes,GetExpressionPathFormat epformat)426 ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
427 {
428 s.Printf("$%s", m_reg_info.name);
429 }
430
431
432