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"
24#include "lldb/Utility/Scalar.h"
25#include "lldb/Utility/Status.h"
26#include "lldb/Utility/Stream.h"
27
28#include "llvm/ADT/StringRef.h"
29#include "llvm/Support/ErrorExtras.h"
30
31#include <cassert>
32#include <memory>
33#include <optional>
34
35namespace lldb_private {
37}
38
39using namespace lldb;
40using namespace lldb_private;
41
42#pragma mark ValueObjectRegisterSet
43
46 lldb::RegisterContextSP &reg_ctx_sp,
47 uint32_t set_idx) {
48 auto manager_sp = ValueObjectManager::Create();
49 return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp,
50 set_idx))
51 ->GetSP();
52}
53
55 ValueObjectManager &manager,
57 uint32_t reg_set_idx)
58 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx),
59 m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) {
60 assert(reg_ctx);
61 m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
62 if (m_reg_set) {
63 m_name.SetCString(m_reg_set->name);
64 }
65}
66
68
72
74
78
79llvm::Expected<uint32_t>
81 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
82 if (reg_set) {
83 auto reg_count = reg_set->num_registers;
84 return reg_count <= max ? reg_count : max;
85 }
86 return 0;
87}
88
89llvm::Expected<uint64_t> ValueObjectRegisterSet::GetByteSize() { return 0; }
90
92 m_error.Clear();
93 SetValueDidChange(false);
95 StackFrame *frame = exe_ctx.GetFramePtr();
96 if (frame == nullptr)
97 m_reg_ctx_sp.reset();
98 else {
100 if (m_reg_ctx_sp) {
101 const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
102 if (reg_set == nullptr)
103 m_reg_ctx_sp.reset();
104 else if (m_reg_set != reg_set) {
105 SetValueDidChange(true);
106 m_name.SetCString(reg_set->name);
107 }
108 }
109 }
110 if (m_reg_ctx_sp) {
111 SetValueIsValid(true);
112 } else {
113 SetValueIsValid(false);
114 m_error = Status::FromErrorString("no register context");
115 m_children.Clear();
116 }
117 return m_error.Success();
118}
119
121 if (m_reg_ctx_sp && m_reg_set) {
122 return new ValueObjectRegister(
123 *this, m_reg_ctx_sp,
124 m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx]));
125 }
126 return nullptr;
127}
128
130 const RegisterInfo *b) {
131 return a && b && a->kinds[eRegisterKindLLDB] == b->kinds[eRegisterKindLLDB];
132}
133
134std::optional<std::pair<size_t, const RegisterInfo *>>
136 if (!m_reg_ctx_sp || !m_reg_set)
137 return {};
138
139 // See if the register exists at all in any set.
140 const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
141
142 // See if this register is in this register set, falling back to the name as
143 // written. The generic name may alias a register in another set while this
144 // set has a register of that exact name. A match on the name itself always
145 // wins over one on the alt name.
146 std::optional<std::pair<size_t, const RegisterInfo *>> match;
147 for (size_t i = 0; i < m_reg_set->num_registers; ++i) {
148 const RegisterInfo *contained_reg_info =
149 m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[i]);
150 if (!contained_reg_info)
151 continue;
152 if (IsSameRegister(contained_reg_info, reg_info))
153 return std::make_pair(i, reg_info);
154 if (name.equals_insensitive(contained_reg_info->name))
155 match = std::make_pair(i, contained_reg_info);
156 else if (!match && name.equals_insensitive(contained_reg_info->alt_name))
157 match = std::make_pair(i, contained_reg_info);
158 }
159
160 return match;
161}
162
165 bool can_create) {
166 if (auto maybe_child = LookupChildWithName(name))
167 return (new ValueObjectRegister(*this, m_reg_ctx_sp, maybe_child->second))
168 ->GetSP();
169
170 return {};
171}
172
173llvm::Expected<size_t>
175 if (auto maybe_child = LookupChildWithName(name))
176 return maybe_child->first;
177
178 return llvm::createStringErrorV("type has no child named '{0}'", name);
179}
180
181#pragma mark -
182#pragma mark ValueObjectRegister
183
185 if (reg_info) {
186 m_reg_info = *reg_info;
187 if (reg_info->name)
188 m_name.SetCString(reg_info->name);
189 else if (reg_info->alt_name)
190 m_name.SetCString(reg_info->alt_name);
191 }
192}
193
195 lldb::RegisterContextSP &reg_ctx_sp,
196 const RegisterInfo *reg_info)
197 : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
199 assert(reg_ctx_sp.get());
200 ConstructObject(reg_info);
201}
202
204 lldb::RegisterContextSP &reg_ctx_sp,
205 const RegisterInfo *reg_info) {
206 auto manager_sp = ValueObjectManager::Create();
207 return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info))
208 ->GetSP();
209}
210
212 ValueObjectManager &manager,
214 const RegisterInfo *reg_info)
215 : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
217 assert(reg_ctx);
218 ConstructObject(reg_info);
219}
220
222
224 if (m_compiler_type.IsValid())
225 return m_compiler_type;
226
228 Target *target = exe_ctx.GetTargetPtr();
229 if (!target)
230 return {};
231
232 if (llvm::isa_and_present<RegisterTypeBuiltin, RegisterTypeVector>(
233 m_reg_info.register_type)) {
235 if (m_compiler_type.IsValid())
236 return m_compiler_type;
237 }
238
239 auto *exe_module = target->GetExecutableModulePointer();
240 if (!exe_module)
241 return {};
242 auto type_system_or_err =
244 if (auto err = type_system_or_err.takeError()) {
245 LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err),
246 "Unable to get CompilerType from TypeSystem: {0}");
247 } else {
248 if (auto ts = *type_system_or_err)
249 m_compiler_type = ts->GetBuiltinTypeForEncodingAndBitSize(
250 m_reg_info.encoding, m_reg_info.byte_size * 8);
251 }
252 return m_compiler_type;
253}
254
260
261llvm::Expected<uint32_t>
264 auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
265 if (!children_count)
266 return children_count;
267 return *children_count <= max ? *children_count : max;
268}
269
270llvm::Expected<uint64_t> ValueObjectRegister::GetByteSize() {
271 return m_reg_info.byte_size;
272}
273
275 m_error.Clear();
277 StackFrame *frame = exe_ctx.GetFramePtr();
278 if (frame == nullptr) {
279 m_reg_ctx_sp.reset();
280 m_reg_value.Clear();
281 }
282
283 if (m_reg_ctx_sp) {
284 RegisterValue m_old_reg_value(m_reg_value);
285 if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
286 Target *target = exe_ctx.GetTargetPtr();
287 const bool has_vector_type =
288 llvm::isa_and_present<RegisterTypeVector>(m_reg_info.register_type);
289 // Scalar registers remain in host byte order, while CompilerType vector
290 // children need target-order bytes to interpret their layout.
291 const bool got_data =
292 has_vector_type && target
293 ? m_reg_value.GetData(m_data, m_reg_info.byte_size,
294 target->GetArchitecture().GetByteOrder())
295 : m_reg_value.GetData(m_data);
296 if (got_data) {
297 Process *process = exe_ctx.GetProcessPtr();
298 if (process)
299 m_data.SetAddressByteSize(process->GetAddressByteSize());
301 (void *)&m_reg_info);
303 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
304 SetValueIsValid(true);
305 SetValueDidChange(!(m_old_reg_value == m_reg_value));
306 return true;
307 }
308 }
309 }
310
311 SetValueIsValid(false);
312 m_error = Status::FromErrorString("no register context");
313 return false;
314}
315
317 Status &error) {
318 // The new value will be in the m_data. Copy that into our register value.
319 error =
320 m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
321 if (!error.Success())
322 return false;
323
324 if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
325 error = Status::FromErrorString("unable to write back to register");
326 return false;
327 }
328
330 return true;
331}
332
334 error = m_reg_value.SetValueFromData(m_reg_info, data, 0, false);
335 if (!error.Success())
336 return false;
337
338 if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
339 error = Status::FromErrorString("unable to write back to register");
340 return false;
341 }
342
344 return true;
345}
346
349 false)) // make sure that you are up to date before returning anything
350 return m_reg_value.GetScalarValue(scalar);
351 return false;
352}
353
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:940
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.
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language)
Definition Module.cpp:353
A plug-in interface definition class for debugging a process.
Definition Process.h:367
uint32_t GetAddressByteSize() const
Definition Process.cpp:3977
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual 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
Module * GetExecutableModulePointer()
Definition Target.cpp:1641
CompilerType GetRegisterType(const RegisterInfo &reg_info)
Definition Target.cpp:2742
const ArchSpec & GetArchitecture() const
Definition Target.h:1308
static bool IsSameRegister(const RegisterInfo *a, const RegisterInfo *b)
std::optional< std::pair< size_t, const RegisterInfo * > > LookupChildWithName(llvm::StringRef name)
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)
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".
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)
CompilerType GetCompilerType()
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:53
@ RegisterInfo
RegisterInfo * (can be a scalar or a vector register).
Definition Value.h:62
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:338
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.