1 //===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/ValueObjectRegister.h"
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/Value.h"
13 #include "lldb/Symbol/CompilerType.h"
14 #include "lldb/Symbol/TypeSystem.h"
15 #include "lldb/Target/ExecutionContext.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/RegisterContext.h"
18 #include "lldb/Target/StackFrame.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/DataExtractor.h"
21 #include "lldb/Utility/Scalar.h"
22 #include "lldb/Utility/Status.h"
23 #include "lldb/Utility/Stream.h"
25 #include "llvm/ADT/StringRef.h"
30 namespace lldb_private {
31 class ExecutionContextScope;
35 using namespace lldb_private;
37 #pragma mark ValueObjectRegisterContext
39 ValueObjectRegisterContext::ValueObjectRegisterContext(
40 ValueObject &parent, RegisterContextSP ®_ctx)
41 : ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
43 m_name.SetCString("Registers");
44 SetValueIsValid(true);
47 ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
49 CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
50 return CompilerType();
53 ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
55 ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
59 ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
63 size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
64 auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
65 return reg_set_count <= max ? reg_set_count : max;
68 uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
70 bool ValueObjectRegisterContext::UpdateValue() {
72 ExecutionContext exe_ctx(GetExecutionContextRef());
73 StackFrame *frame = exe_ctx.GetFramePtr();
75 m_reg_ctx_sp = frame->GetRegisterContext();
79 if (m_reg_ctx_sp.get() == nullptr) {
80 SetValueIsValid(false);
81 m_error.SetErrorToGenericError();
83 SetValueIsValid(true);
85 return m_error.Success();
88 ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
89 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
90 ValueObject *new_valobj = nullptr;
92 const size_t num_children = GetNumChildren();
93 if (idx < num_children) {
94 ExecutionContext exe_ctx(GetExecutionContextRef());
95 new_valobj = new ValueObjectRegisterSet(
96 exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
103 #pragma mark ValueObjectRegisterSet
106 ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
107 lldb::RegisterContextSP ®_ctx_sp,
109 return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
112 ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
113 lldb::RegisterContextSP ®_ctx,
114 uint32_t reg_set_idx)
115 : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(nullptr),
116 m_reg_set_idx(reg_set_idx) {
118 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
120 m_name.SetCString(m_reg_set->name);
124 ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
126 CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
127 return CompilerType();
130 ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
132 ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
133 return ConstString();
136 size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
137 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
139 auto reg_count = reg_set->num_registers;
140 return reg_count <= max ? reg_count : max;
145 uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
147 bool ValueObjectRegisterSet::UpdateValue() {
149 SetValueDidChange(false);
150 ExecutionContext exe_ctx(GetExecutionContextRef());
151 StackFrame *frame = exe_ctx.GetFramePtr();
152 if (frame == nullptr)
153 m_reg_ctx_sp.reset();
155 m_reg_ctx_sp = frame->GetRegisterContext();
157 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
158 if (reg_set == nullptr)
159 m_reg_ctx_sp.reset();
160 else if (m_reg_set != reg_set) {
161 SetValueDidChange(true);
162 m_name.SetCString(reg_set->name);
167 SetValueIsValid(true);
169 SetValueIsValid(false);
170 m_error.SetErrorToGenericError();
173 return m_error.Success();
176 ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
177 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
178 ValueObject *valobj = nullptr;
179 if (m_reg_ctx_sp && m_reg_set) {
180 const size_t num_children = GetNumChildren();
181 if (idx < num_children)
182 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
183 m_reg_set->registers[idx]);
189 ValueObjectRegisterSet::GetChildMemberWithName(ConstString name,
191 ValueObject *valobj = nullptr;
192 if (m_reg_ctx_sp && m_reg_set) {
193 const RegisterInfo *reg_info =
194 m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
195 if (reg_info != nullptr)
196 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
197 reg_info->kinds[eRegisterKindLLDB]);
200 return valobj->GetSP();
202 return ValueObjectSP();
206 ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) {
207 if (m_reg_ctx_sp && m_reg_set) {
208 const RegisterInfo *reg_info =
209 m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
210 if (reg_info != nullptr)
211 return reg_info->kinds[eRegisterKindLLDB];
217 #pragma mark ValueObjectRegister
219 void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
220 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
222 m_reg_info = *reg_info;
224 m_name.SetCString(reg_info->name);
225 else if (reg_info->alt_name)
226 m_name.SetCString(reg_info->alt_name);
230 ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
231 lldb::RegisterContextSP ®_ctx_sp,
233 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
234 m_reg_value(), m_type_name(), m_compiler_type() {
235 assert(reg_ctx_sp.get());
236 ConstructObject(reg_num);
239 ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
240 lldb::RegisterContextSP ®_ctx_sp,
242 return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
245 ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
246 lldb::RegisterContextSP ®_ctx,
248 : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
249 m_reg_value(), m_type_name(), m_compiler_type() {
251 ConstructObject(reg_num);
254 ValueObjectRegister::~ValueObjectRegister() {}
256 CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
257 if (!m_compiler_type.IsValid()) {
258 ExecutionContext exe_ctx(GetExecutionContextRef());
259 Target *target = exe_ctx.GetTargetPtr();
261 Module *exe_module = target->GetExecutableModulePointer();
263 TypeSystem *type_system =
264 exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
266 m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
267 m_reg_info.encoding, m_reg_info.byte_size * 8);
271 return m_compiler_type;
274 ConstString ValueObjectRegister::GetTypeName() {
275 if (m_type_name.IsEmpty())
276 m_type_name = GetCompilerType().GetConstTypeName();
280 size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
281 ExecutionContext exe_ctx(GetExecutionContextRef());
282 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
283 return children_count <= max ? children_count : max;
286 uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
288 bool ValueObjectRegister::UpdateValue() {
290 ExecutionContext exe_ctx(GetExecutionContextRef());
291 StackFrame *frame = exe_ctx.GetFramePtr();
292 if (frame == nullptr) {
293 m_reg_ctx_sp.reset();
298 RegisterValue m_old_reg_value(m_reg_value);
299 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
300 if (m_reg_value.GetData(m_data)) {
301 Process *process = exe_ctx.GetProcessPtr();
303 m_data.SetAddressByteSize(process->GetAddressByteSize());
304 m_value.SetContext(Value::eContextTypeRegisterInfo,
305 (void *)&m_reg_info);
306 m_value.SetValueType(Value::eValueTypeHostAddress);
307 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
308 SetValueIsValid(true);
309 SetValueDidChange(!(m_old_reg_value == m_reg_value));
315 SetValueIsValid(false);
316 m_error.SetErrorToGenericError();
320 bool ValueObjectRegister::SetValueFromCString(const char *value_str,
322 // The new value will be in the m_data. Copy that into our register value.
324 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
325 if (error.Success()) {
326 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
335 bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) {
336 error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
337 if (error.Success()) {
338 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
347 bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
348 if (UpdateValueIfNeeded(
349 false)) // make sure that you are up to date before returning anything
350 return m_reg_value.GetScalarValue(scalar);
354 void ValueObjectRegister::GetExpressionPath(Stream &s,
355 bool qualify_cxx_base_classes,
356 GetExpressionPathFormat epformat) {
357 s.Printf("$%s", m_reg_info.name);