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/Log.h"
22 #include "lldb/Utility/Scalar.h"
23 #include "lldb/Utility/Status.h"
24 #include "lldb/Utility/Stream.h"
26 #include "llvm/ADT/StringRef.h"
31 namespace lldb_private {
32 class ExecutionContextScope;
36 using namespace lldb_private;
38 #pragma mark ValueObjectRegisterContext
40 ValueObjectRegisterContext::ValueObjectRegisterContext(
41 ValueObject &parent, RegisterContextSP ®_ctx)
42 : ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
44 m_name.SetCString("Registers");
45 SetValueIsValid(true);
48 ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
50 CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
51 return CompilerType();
54 ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
56 ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
60 ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
64 size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
65 auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
66 return reg_set_count <= max ? reg_set_count : max;
69 uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
71 bool ValueObjectRegisterContext::UpdateValue() {
73 ExecutionContext exe_ctx(GetExecutionContextRef());
74 StackFrame *frame = exe_ctx.GetFramePtr();
76 m_reg_ctx_sp = frame->GetRegisterContext();
80 if (m_reg_ctx_sp.get() == nullptr) {
81 SetValueIsValid(false);
82 m_error.SetErrorToGenericError();
84 SetValueIsValid(true);
86 return m_error.Success();
89 ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
90 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
91 ValueObject *new_valobj = nullptr;
93 const size_t num_children = GetNumChildren();
94 if (idx < num_children) {
95 ExecutionContext exe_ctx(GetExecutionContextRef());
96 new_valobj = new ValueObjectRegisterSet(
97 exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
104 #pragma mark ValueObjectRegisterSet
107 ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
108 lldb::RegisterContextSP ®_ctx_sp,
110 return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
113 ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
114 lldb::RegisterContextSP ®_ctx,
115 uint32_t reg_set_idx)
116 : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(nullptr),
117 m_reg_set_idx(reg_set_idx) {
119 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
121 m_name.SetCString(m_reg_set->name);
125 ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
127 CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
128 return CompilerType();
131 ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
133 ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
134 return ConstString();
137 size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
138 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
140 auto reg_count = reg_set->num_registers;
141 return reg_count <= max ? reg_count : max;
146 uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
148 bool ValueObjectRegisterSet::UpdateValue() {
150 SetValueDidChange(false);
151 ExecutionContext exe_ctx(GetExecutionContextRef());
152 StackFrame *frame = exe_ctx.GetFramePtr();
153 if (frame == nullptr)
154 m_reg_ctx_sp.reset();
156 m_reg_ctx_sp = frame->GetRegisterContext();
158 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
159 if (reg_set == nullptr)
160 m_reg_ctx_sp.reset();
161 else if (m_reg_set != reg_set) {
162 SetValueDidChange(true);
163 m_name.SetCString(reg_set->name);
168 SetValueIsValid(true);
170 SetValueIsValid(false);
171 m_error.SetErrorToGenericError();
174 return m_error.Success();
177 ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
178 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
179 ValueObject *valobj = nullptr;
180 if (m_reg_ctx_sp && m_reg_set) {
181 const size_t num_children = GetNumChildren();
182 if (idx < num_children)
183 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
184 m_reg_set->registers[idx]);
190 ValueObjectRegisterSet::GetChildMemberWithName(ConstString name,
192 ValueObject *valobj = nullptr;
193 if (m_reg_ctx_sp && m_reg_set) {
194 const RegisterInfo *reg_info =
195 m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
196 if (reg_info != nullptr)
197 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
198 reg_info->kinds[eRegisterKindLLDB]);
201 return valobj->GetSP();
203 return ValueObjectSP();
207 ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) {
208 if (m_reg_ctx_sp && m_reg_set) {
209 const RegisterInfo *reg_info =
210 m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
211 if (reg_info != nullptr)
212 return reg_info->kinds[eRegisterKindLLDB];
218 #pragma mark ValueObjectRegister
220 void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
221 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
223 m_reg_info = *reg_info;
225 m_name.SetCString(reg_info->name);
226 else if (reg_info->alt_name)
227 m_name.SetCString(reg_info->alt_name);
231 ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
232 lldb::RegisterContextSP ®_ctx_sp,
234 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
235 m_reg_value(), m_type_name(), m_compiler_type() {
236 assert(reg_ctx_sp.get());
237 ConstructObject(reg_num);
240 ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
241 lldb::RegisterContextSP ®_ctx_sp,
243 return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
246 ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
247 lldb::RegisterContextSP ®_ctx,
249 : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
250 m_reg_value(), m_type_name(), m_compiler_type() {
252 ConstructObject(reg_num);
255 ValueObjectRegister::~ValueObjectRegister() {}
257 CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
258 if (!m_compiler_type.IsValid()) {
259 ExecutionContext exe_ctx(GetExecutionContextRef());
260 if (auto *target = exe_ctx.GetTargetPtr()) {
261 if (auto *exe_module = target->GetExecutableModulePointer()) {
262 auto type_system_or_err =
263 exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
264 if (auto err = type_system_or_err.takeError()) {
266 lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES),
267 std::move(err), "Unable to get CompilerType from TypeSystem");
270 type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
271 m_reg_info.encoding, m_reg_info.byte_size * 8);
276 return m_compiler_type;
279 ConstString ValueObjectRegister::GetTypeName() {
280 if (m_type_name.IsEmpty())
281 m_type_name = GetCompilerType().GetConstTypeName();
285 size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
286 ExecutionContext exe_ctx(GetExecutionContextRef());
287 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
288 return children_count <= max ? children_count : max;
291 uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
293 bool ValueObjectRegister::UpdateValue() {
295 ExecutionContext exe_ctx(GetExecutionContextRef());
296 StackFrame *frame = exe_ctx.GetFramePtr();
297 if (frame == nullptr) {
298 m_reg_ctx_sp.reset();
303 RegisterValue m_old_reg_value(m_reg_value);
304 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
305 if (m_reg_value.GetData(m_data)) {
306 Process *process = exe_ctx.GetProcessPtr();
308 m_data.SetAddressByteSize(process->GetAddressByteSize());
309 m_value.SetContext(Value::eContextTypeRegisterInfo,
310 (void *)&m_reg_info);
311 m_value.SetValueType(Value::eValueTypeHostAddress);
312 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
313 SetValueIsValid(true);
314 SetValueDidChange(!(m_old_reg_value == m_reg_value));
320 SetValueIsValid(false);
321 m_error.SetErrorToGenericError();
325 bool ValueObjectRegister::SetValueFromCString(const char *value_str,
327 // The new value will be in the m_data. Copy that into our register value.
329 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
330 if (error.Success()) {
331 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
340 bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) {
341 error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
342 if (error.Success()) {
343 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
352 bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
353 if (UpdateValueIfNeeded(
354 false)) // make sure that you are up to date before returning anything
355 return m_reg_value.GetScalarValue(scalar);
359 void ValueObjectRegister::GetExpressionPath(Stream &s,
360 bool qualify_cxx_base_classes,
361 GetExpressionPathFormat epformat) {
362 s.Printf("$%s", m_reg_info.name);