1 //===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/ValueObjectRegister.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Module.h"
17 #include "lldb/Symbol/ClangASTContext.h"
18 #include "lldb/Symbol/CompilerType.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"
27 using namespace lldb_private;
29 #pragma mark ValueObjectRegisterContext
31 ValueObjectRegisterContext::ValueObjectRegisterContext(
32 ValueObject &parent, RegisterContextSP ®_ctx)
33 : ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
35 m_name.SetCString("Registers");
36 SetValueIsValid(true);
39 ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
41 CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
42 return CompilerType();
45 ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
47 ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
51 ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
55 size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
56 auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
57 return reg_set_count <= max ? reg_set_count : max;
60 uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
62 bool ValueObjectRegisterContext::UpdateValue() {
64 ExecutionContext exe_ctx(GetExecutionContextRef());
65 StackFrame *frame = exe_ctx.GetFramePtr();
67 m_reg_ctx_sp = frame->GetRegisterContext();
71 if (m_reg_ctx_sp.get() == NULL) {
72 SetValueIsValid(false);
73 m_error.SetErrorToGenericError();
75 SetValueIsValid(true);
77 return m_error.Success();
80 ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
81 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
82 ValueObject *new_valobj = NULL;
84 const size_t num_children = GetNumChildren();
85 if (idx < num_children) {
86 ExecutionContext exe_ctx(GetExecutionContextRef());
87 new_valobj = new ValueObjectRegisterSet(
88 exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
95 #pragma mark ValueObjectRegisterSet
98 ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
99 lldb::RegisterContextSP ®_ctx_sp,
101 return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
104 ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
105 lldb::RegisterContextSP ®_ctx,
106 uint32_t reg_set_idx)
107 : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(NULL),
108 m_reg_set_idx(reg_set_idx) {
110 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
112 m_name.SetCString(m_reg_set->name);
116 ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
118 CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
119 return CompilerType();
122 ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
124 ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
125 return ConstString();
128 size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
129 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
131 auto reg_count = reg_set->num_registers;
132 return reg_count <= max ? reg_count : max;
137 uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
139 bool ValueObjectRegisterSet::UpdateValue() {
141 SetValueDidChange(false);
142 ExecutionContext exe_ctx(GetExecutionContextRef());
143 StackFrame *frame = exe_ctx.GetFramePtr();
145 m_reg_ctx_sp.reset();
147 m_reg_ctx_sp = frame->GetRegisterContext();
149 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
151 m_reg_ctx_sp.reset();
152 else if (m_reg_set != reg_set) {
153 SetValueDidChange(true);
154 m_name.SetCString(reg_set->name);
159 SetValueIsValid(true);
161 SetValueIsValid(false);
162 m_error.SetErrorToGenericError();
165 return m_error.Success();
168 ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
169 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
170 ValueObject *valobj = NULL;
171 if (m_reg_ctx_sp && m_reg_set) {
172 const size_t num_children = GetNumChildren();
173 if (idx < num_children)
174 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
175 m_reg_set->registers[idx]);
181 ValueObjectRegisterSet::GetChildMemberWithName(const ConstString &name,
183 ValueObject *valobj = NULL;
184 if (m_reg_ctx_sp && m_reg_set) {
185 const RegisterInfo *reg_info =
186 m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
187 if (reg_info != NULL)
188 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
189 reg_info->kinds[eRegisterKindLLDB]);
192 return valobj->GetSP();
194 return ValueObjectSP();
198 ValueObjectRegisterSet::GetIndexOfChildWithName(const ConstString &name) {
199 if (m_reg_ctx_sp && m_reg_set) {
200 const RegisterInfo *reg_info =
201 m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
202 if (reg_info != NULL)
203 return reg_info->kinds[eRegisterKindLLDB];
209 #pragma mark ValueObjectRegister
211 void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
212 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
214 m_reg_info = *reg_info;
216 m_name.SetCString(reg_info->name);
217 else if (reg_info->alt_name)
218 m_name.SetCString(reg_info->alt_name);
222 ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
223 lldb::RegisterContextSP ®_ctx_sp,
225 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
226 m_reg_value(), m_type_name(), m_compiler_type() {
227 assert(reg_ctx_sp.get());
228 ConstructObject(reg_num);
231 ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
232 lldb::RegisterContextSP ®_ctx_sp,
234 return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
237 ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
238 lldb::RegisterContextSP ®_ctx,
240 : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
241 m_reg_value(), m_type_name(), m_compiler_type() {
243 ConstructObject(reg_num);
246 ValueObjectRegister::~ValueObjectRegister() {}
248 CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
249 if (!m_compiler_type.IsValid()) {
250 ExecutionContext exe_ctx(GetExecutionContextRef());
251 Target *target = exe_ctx.GetTargetPtr();
253 Module *exe_module = target->GetExecutableModulePointer();
255 TypeSystem *type_system =
256 exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
258 m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
259 m_reg_info.encoding, m_reg_info.byte_size * 8);
263 return m_compiler_type;
266 ConstString ValueObjectRegister::GetTypeName() {
267 if (m_type_name.IsEmpty())
268 m_type_name = GetCompilerType().GetConstTypeName();
272 size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
273 auto children_count = GetCompilerType().GetNumChildren(true);
274 return children_count <= max ? children_count : max;
277 uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
279 bool ValueObjectRegister::UpdateValue() {
281 ExecutionContext exe_ctx(GetExecutionContextRef());
282 StackFrame *frame = exe_ctx.GetFramePtr();
284 m_reg_ctx_sp.reset();
289 RegisterValue m_old_reg_value(m_reg_value);
290 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
291 if (m_reg_value.GetData(m_data)) {
292 Process *process = exe_ctx.GetProcessPtr();
294 m_data.SetAddressByteSize(process->GetAddressByteSize());
295 m_value.SetContext(Value::eContextTypeRegisterInfo,
296 (void *)&m_reg_info);
297 m_value.SetValueType(Value::eValueTypeHostAddress);
298 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
299 SetValueIsValid(true);
300 SetValueDidChange(!(m_old_reg_value == m_reg_value));
306 SetValueIsValid(false);
307 m_error.SetErrorToGenericError();
311 bool ValueObjectRegister::SetValueFromCString(const char *value_str,
313 // The new value will be in the m_data. Copy that into our register value.
315 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
316 if (error.Success()) {
317 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
326 bool ValueObjectRegister::SetData(DataExtractor &data, Error &error) {
327 error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
328 if (error.Success()) {
329 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
338 bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
339 if (UpdateValueIfNeeded(
340 false)) // make sure that you are up to date before returning anything
341 return m_reg_value.GetScalarValue(scalar);
345 void ValueObjectRegister::GetExpressionPath(Stream &s,
346 bool qualify_cxx_base_classes,
347 GetExpressionPathFormat epformat) {
348 s.Printf("$%s", m_reg_info.name);