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) {
61 m_name.SetCString(m_reg_set->name);
62 }
63}
64
66
70
72
76
77llvm::Expected<uint32_t>
79 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
80 if (reg_set) {
81 auto reg_count = reg_set->num_registers;
82 return reg_count <= max ? reg_count : max;
83 }
84 return 0;
85}
86
87llvm::Expected<uint64_t> ValueObjectRegisterSet::GetByteSize() { return 0; }
88
90 m_error.Clear();
91 SetValueDidChange(false);
93 StackFrame *frame = exe_ctx.GetFramePtr();
94 if (frame == nullptr)
95 m_reg_ctx_sp.reset();
96 else {
98 if (m_reg_ctx_sp) {
99 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
100 if (reg_set == nullptr)
101 m_reg_ctx_sp.reset();
102 else if (m_reg_set != reg_set) {
103 SetValueDidChange(true);
104 m_name.SetCString(reg_set->name);
105 }
106 }
107 }
108 if (m_reg_ctx_sp) {
109 SetValueIsValid(true);
110 } else {
111 SetValueIsValid(false);
112 m_error = Status::FromErrorString("no register context");
113 m_children.Clear();
114 }
115 return m_error.Success();
116}
117
119 if (m_reg_ctx_sp && m_reg_set) {
120 return new ValueObjectRegister(
121 *this, m_reg_ctx_sp,
122 m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx]));
123 }
124 return nullptr;
125}
126
129 bool can_create) {
130 ValueObject *valobj = nullptr;
131 if (m_reg_ctx_sp && m_reg_set) {
132 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
133 if (reg_info != nullptr)
134 valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info);
135 }
136 if (valobj)
137 return valobj->GetSP();
138 else
139 return ValueObjectSP();
140}
141
142llvm::Expected<size_t>
144 if (m_reg_ctx_sp && m_reg_set) {
145 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
146 if (reg_info != nullptr)
147 return reg_info->kinds[eRegisterKindLLDB];
148 }
149 return llvm::createStringError("Type has no child named '%s'",
150 name.str().c_str());
151}
152
153#pragma mark -
154#pragma mark ValueObjectRegister
155
157 if (reg_info) {
158 m_reg_info = *reg_info;
159 if (reg_info->name)
160 m_name.SetCString(reg_info->name);
161 else if (reg_info->alt_name)
162 m_name.SetCString(reg_info->alt_name);
163 }
164}
165
167 lldb::RegisterContextSP &reg_ctx_sp,
168 const RegisterInfo *reg_info)
169 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
171 assert(reg_ctx_sp.get());
172 ConstructObject(reg_info);
173}
174
176 lldb::RegisterContextSP &reg_ctx_sp,
177 const RegisterInfo *reg_info) {
178 auto manager_sp = ValueObjectManager::Create();
179 return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info))
180 ->GetSP();
181}
182
184 ValueObjectManager &manager,
186 const RegisterInfo *reg_info)
187 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
189 assert(reg_ctx);
190 ConstructObject(reg_info);
191}
192
194
196 if (!m_compiler_type.IsValid()) {
198 if (auto *target = exe_ctx.GetTargetPtr()) {
199 if (auto *exe_module = target->GetExecutableModulePointer()) {
200 auto type_system_or_err =
201 exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
202 if (auto err = type_system_or_err.takeError()) {
203 LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err),
204 "Unable to get CompilerType from TypeSystem: {0}");
205 } else {
206 if (auto ts = *type_system_or_err)
207 m_compiler_type = ts->GetBuiltinTypeForEncodingAndBitSize(
208 m_reg_info.encoding, m_reg_info.byte_size * 8);
209 }
210 }
211 }
212 }
213 return m_compiler_type;
214}
215
221
222llvm::Expected<uint32_t>
225 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
226 if (!children_count)
227 return children_count;
228 return *children_count <= max ? *children_count : max;
229}
230
231llvm::Expected<uint64_t> ValueObjectRegister::GetByteSize() {
232 return m_reg_info.byte_size;
233}
234
236 m_error.Clear();
238 StackFrame *frame = exe_ctx.GetFramePtr();
239 if (frame == nullptr) {
240 m_reg_ctx_sp.reset();
241 m_reg_value.Clear();
242 }
243
244 if (m_reg_ctx_sp) {
245 RegisterValue m_old_reg_value(m_reg_value);
246 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
247 if (m_reg_value.GetData(m_data)) {
248 Process *process = exe_ctx.GetProcessPtr();
249 if (process)
250 m_data.SetAddressByteSize(process->GetAddressByteSize());
252 (void *)&m_reg_info);
254 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
255 SetValueIsValid(true);
256 SetValueDidChange(!(m_old_reg_value == m_reg_value));
257 return true;
258 }
259 }
260 }
261
262 SetValueIsValid(false);
263 m_error = Status::FromErrorString("no register context");
264 return false;
265}
266
268 Status &error) {
269 // The new value will be in the m_data. Copy that into our register value.
270 error =
271 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
272 if (!error.Success())
273 return false;
274
275 if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
276 error = Status::FromErrorString("unable to write back to register");
277 return false;
278 }
279
281 return true;
282}
283
285 error = m_reg_value.SetValueFromData(m_reg_info, data, 0, false);
286 if (!error.Success())
287 return false;
288
289 if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
290 error = Status::FromErrorString("unable to write back to register");
291 return false;
292 }
293
295 return true;
296}
297
300 false)) // make sure that you are up to date before returning anything
301 return m_reg_value.GetScalarValue(scalar);
302 return false;
303}
304
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
static std::shared_ptr< ClusterManager > Create()
Generic representation of a type in a programming language.
ConstString GetTypeName(bool BaseOnly=false) const
llvm::Expected< uint32_t > GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const
A uniqued constant string class.
Definition ConstString.h:40
An data extractor class.
"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:357
uint32_t GetAddressByteSize() const
Definition Process.cpp:3620
This base class provides an interface to stack frames.
Definition StackFrame.h:44
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
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)
llvm::Expected< size_t > GetIndexOfChildWithName(llvm::StringRef name) override
lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true) override
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
llvm::Expected< uint32_t > CalculateNumChildren(uint32_t max) override
Should only be called by ValueObject::GetNumChildren().
llvm::Expected< uint64_t > GetByteSize() override
ValueObject * CreateChildAtIndex(size_t idx) override
Should only be called by ValueObject::GetChildAtIndex().
bool SetValueFromCString(const char *value_str, Status &error) override
bool SetData(DataExtractor &data, Status &error) override
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, const RegisterInfo *reg_info)
llvm::Expected< uint32_t > CalculateNumChildren(uint32_t max) override
Should only be called by ValueObject::GetNumChildren().
ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, const RegisterInfo *reg_info)
llvm ::Expected< uint64_t > GetByteSize() override
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)
CompilerType GetCompilerType()
ClusterManager< ValueObject > ValueObjectManager
ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type=eAddressTypeLoad)
Use this constructor to create a "root variable object".
lldb::ValueObjectSP GetSP()
ChildrenManager m_children
Status m_error
An error object that can describe any errors that occur when updating values.
DataExtractor m_data
A data extractor that can be used to extract the value.
void SetValueDidChange(bool value_changed)
bool UpdateValueIfNeeded(bool update_format=true)
ConstString m_name
The name of this object.
const ExecutionContextRef & GetExecutionContextRef() const
@ HostAddress
A host address value (for memory in the process that < A is using liblldb).
Definition Value.h:52
@ RegisterInfo
RegisterInfo * (can be a scalar or a vector register).
Definition Value.h:61
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
const char * alt_name
Alternate name of this register, can be NULL.
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 char * name
Name of this register set.