LLDB mainline
ValueObjectRegister.cpp
Go to the documentation of this file.
1//===-- ValueObjectRegister.cpp -------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Core/Module.h"
12#include "lldb/Core/Value.h"
16#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
22#include "lldb/Utility/Log.h"
23#include "lldb/Utility/Scalar.h"
24#include "lldb/Utility/Status.h"
25#include "lldb/Utility/Stream.h"
26
27#include "llvm/ADT/StringRef.h"
28
29#include <cassert>
30#include <memory>
31#include <optional>
32
33namespace lldb_private {
35}
36
37using namespace lldb;
38using namespace lldb_private;
39
40#pragma mark ValueObjectRegisterSet
41
44 lldb::RegisterContextSP &reg_ctx_sp,
45 uint32_t set_idx) {
46 auto manager_sp = ValueObjectManager::Create();
47 return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp,
48 set_idx))
49 ->GetSP();
50}
51
53 ValueObjectManager &manager,
55 uint32_t reg_set_idx)
56 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx),
57 m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) {
58 assert(reg_ctx);
59 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
60 if (m_reg_set) {
62 }
63}
64
66
68 return CompilerType();
69}
70
72
74 return ConstString();
75}
76
78 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
79 if (reg_set) {
80 auto reg_count = reg_set->num_registers;
81 return reg_count <= max ? reg_count : max;
82 }
83 return 0;
84}
85
86std::optional<uint64_t> ValueObjectRegisterSet::GetByteSize() { return 0; }
87
89 m_error.Clear();
90 SetValueDidChange(false);
92 StackFrame *frame = exe_ctx.GetFramePtr();
93 if (frame == nullptr)
94 m_reg_ctx_sp.reset();
95 else {
97 if (m_reg_ctx_sp) {
98 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
99 if (reg_set == nullptr)
100 m_reg_ctx_sp.reset();
101 else if (m_reg_set != reg_set) {
102 SetValueDidChange(true);
103 m_name.SetCString(reg_set->name);
104 }
105 }
106 }
107 if (m_reg_ctx_sp) {
108 SetValueIsValid(true);
109 } else {
110 SetValueIsValid(false);
113 }
114 return m_error.Success();
115}
116
118 size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
119 ValueObject *valobj = nullptr;
120 if (m_reg_ctx_sp && m_reg_set) {
121 const size_t num_children = GetNumChildren();
122 if (idx < num_children)
123 valobj = new ValueObjectRegister(
124 *this, m_reg_ctx_sp,
125 m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx]));
126 }
127 return valobj;
128}
129
132 bool can_create) {
133 ValueObject *valobj = nullptr;
134 if (m_reg_ctx_sp && m_reg_set) {
135 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
136 if (reg_info != nullptr)
137 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info);
138 }
139 if (valobj)
140 return valobj->GetSP();
141 else
142 return ValueObjectSP();
143}
144
146 if (m_reg_ctx_sp && m_reg_set) {
147 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
148 if (reg_info != nullptr)
149 return reg_info->kinds[eRegisterKindLLDB];
150 }
151 return UINT32_MAX;
152}
153
154#pragma mark -
155#pragma mark ValueObjectRegister
156
158 if (reg_info) {
159 m_reg_info = *reg_info;
160 if (reg_info->name)
161 m_name.SetCString(reg_info->name);
162 else if (reg_info->alt_name)
163 m_name.SetCString(reg_info->alt_name);
164 }
165}
166
168 lldb::RegisterContextSP &reg_ctx_sp,
169 const RegisterInfo *reg_info)
170 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
171 m_reg_value(), m_type_name(), m_compiler_type() {
172 assert(reg_ctx_sp.get());
173 ConstructObject(reg_info);
174}
175
177 lldb::RegisterContextSP &reg_ctx_sp,
178 const RegisterInfo *reg_info) {
179 auto manager_sp = ValueObjectManager::Create();
180 return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info))
181 ->GetSP();
182}
183
185 ValueObjectManager &manager,
187 const RegisterInfo *reg_info)
188 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
189 m_reg_value(), m_type_name(), m_compiler_type() {
190 assert(reg_ctx);
191 ConstructObject(reg_info);
192}
193
195
197 if (!m_compiler_type.IsValid()) {
199 if (auto *target = exe_ctx.GetTargetPtr()) {
200 if (auto *exe_module = target->GetExecutableModulePointer()) {
201 auto type_system_or_err =
202 exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
203 if (auto err = type_system_or_err.takeError()) {
204 LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err),
205 "Unable to get CompilerType from TypeSystem: {0}");
206 } else {
207 if (auto ts = *type_system_or_err)
208 m_compiler_type = ts->GetBuiltinTypeForEncodingAndBitSize(
210 }
211 }
212 }
213 }
214 return m_compiler_type;
215}
216
218 if (m_type_name.IsEmpty())
220 return m_type_name;
221}
222
225 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
226 return children_count <= max ? children_count : max;
227}
228
229std::optional<uint64_t> ValueObjectRegister::GetByteSize() {
230 return m_reg_info.byte_size;
231}
232
234 m_error.Clear();
236 StackFrame *frame = exe_ctx.GetFramePtr();
237 if (frame == nullptr) {
238 m_reg_ctx_sp.reset();
240 }
241
242 if (m_reg_ctx_sp) {
243 RegisterValue m_old_reg_value(m_reg_value);
244 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
246 Process *process = exe_ctx.GetProcessPtr();
247 if (process)
250 (void *)&m_reg_info);
252 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
253 SetValueIsValid(true);
254 SetValueDidChange(!(m_old_reg_value == m_reg_value));
255 return true;
256 }
257 }
258 }
259
260 SetValueIsValid(false);
262 return false;
263}
264
266 Status &error) {
267 // The new value will be in the m_data. Copy that into our register value.
268 error =
269 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
270 if (!error.Success())
271 return false;
272
273 if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
274 error.SetErrorString("unable to write back to register");
275 return false;
276 }
277
279 return true;
280}
281
283 error = m_reg_value.SetValueFromData(m_reg_info, data, 0, false);
284 if (!error.Success())
285 return false;
286
287 if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
288 error.SetErrorString("unable to write back to register");
289 return false;
290 }
291
293 return true;
294}
295
298 false)) // make sure that you are up to date before returning anything
299 return m_reg_value.GetScalarValue(scalar);
300 return false;
301}
302
304 GetExpressionPathFormat epformat) {
305 s.Printf("$%s", m_reg_info.name);
306}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:365
static std::shared_ptr< ClusterManager > Create()
Definition: SharedCluster.h:24
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
uint32_t GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const
ConstString GetTypeName(bool BaseOnly=false) const
A uniqued constant string class.
Definition: ConstString.h:40
void SetCString(const char *cstr)
Set the C string value.
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:302
An data extractor class.
Definition: DataExtractor.h:48
const uint8_t * GetDataStart() const
Get the data start pointer.
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
A plug-in interface definition class for debugging a process.
Definition: Process.h:340
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3406
bool GetData(DataExtractor &data) const
Status SetValueFromString(const RegisterInfo *reg_info, llvm::StringRef value_str)
bool GetScalarValue(Scalar &scalar) const
Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
This base class provides an interface to stack frames.
Definition: StackFrame.h:42
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
An error handling class.
Definition: Status.h:44
void Clear()
Clear the object state.
Definition: Status.cpp:167
void SetErrorToGenericError()
Set the current error to a generic error.
Definition: Status.cpp:223
bool Success() const
Test for success condition.
Definition: Status.cpp:279
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
ValueObjectRegisterSet(ExecutionContextScope *exe_scope, ValueObjectManager &manager, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
std::optional< uint64_t > GetByteSize() override
size_t GetIndexOfChildWithName(llvm::StringRef name) override
lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true) override
ValueObject * CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override
Should only be called by ValueObject::GetChildAtIndex().
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
size_t CalculateNumChildren(uint32_t max) override
Should only be called by ValueObject::GetNumChildren().
bool SetValueFromCString(const char *value_str, Status &error) override
size_t CalculateNumChildren(uint32_t max) override
Should only be called by ValueObject::GetNumChildren().
bool SetData(DataExtractor &data, Status &error) override
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, const RegisterInfo *reg_info)
std::optional< uint64_t > GetByteSize() override
ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, const RegisterInfo *reg_info)
lldb::RegisterContextSP m_reg_ctx_sp
CompilerType GetCompilerTypeImpl() override
void ConstructObject(const RegisterInfo *reg_info)
void GetExpressionPath(Stream &s, GetExpressionPathFormat epformat=eGetExpressionPathFormatDereferencePointers) override
bool ResolveValue(Scalar &scalar) override
void SetValueIsValid(bool valid)
Definition: ValueObject.h:969
size_t GetNumChildren(uint32_t max=UINT32_MAX)
CompilerType GetCompilerType()
Definition: ValueObject.h:352
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:539
ChildrenManager m_children
Definition: ValueObject.h:867
Status m_error
An error object that can describe any errors that occur when updating values.
Definition: ValueObject.h:844
DataExtractor m_data
A data extractor that can be used to extract the value.
Definition: ValueObject.h:840
void SetValueDidChange(bool value_changed)
Definition: ValueObject.h:965
bool UpdateValueIfNeeded(bool update_format=true)
ConstString m_name
The name of this object.
Definition: ValueObject.h:838
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:330
const Scalar & GetScalar() const
Definition: Value.h:112
@ HostAddress
A host address value (for memory in the process that < A is using liblldb).
void SetContext(ContextType context_type, void *p)
Definition: Value.h:96
void SetValueType(ValueType value_type)
Definition: Value.h:89
@ RegisterInfo
RegisterInfo * (can be a scalar or a vector register).
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:472
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
Definition: lldb-forward.h:386
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
const char * alt_name
Alternate name of this register, can be NULL.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.
const uint32_t * registers
An array of register indices in this set.
const char * name
Name of this register set.