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"
14 #include "lldb/Symbol/TypeSystem.h"
16 #include "lldb/Target/Process.h"
18 #include "lldb/Target/StackFrame.h"
19 #include "lldb/Target/Target.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"
25 
26 #include "llvm/ADT/StringRef.h"
27 
28 #include <assert.h>
29 #include <memory>
30 
31 namespace lldb_private {
33 }
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 #pragma mark ValueObjectRegisterSet
39 
40 ValueObjectSP
42  lldb::RegisterContextSP &reg_ctx_sp,
43  uint32_t set_idx) {
44  auto manager_sp = ValueObjectManager::Create();
45  return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp,
46  set_idx))
47  ->GetSP();
48 }
49 
51  ValueObjectManager &manager,
52  lldb::RegisterContextSP &reg_ctx,
53  uint32_t reg_set_idx)
54  : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx),
55  m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) {
56  assert(reg_ctx);
57  m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
58  if (m_reg_set) {
60  }
61 }
62 
64 
66  return CompilerType();
67 }
68 
70 
72  return ConstString();
73 }
74 
76  const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
77  if (reg_set) {
78  auto reg_count = reg_set->num_registers;
79  return reg_count <= max ? reg_count : max;
80  }
81  return 0;
82 }
83 
84 uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
85 
87  m_error.Clear();
88  SetValueDidChange(false);
90  StackFrame *frame = exe_ctx.GetFramePtr();
91  if (frame == nullptr)
92  m_reg_ctx_sp.reset();
93  else {
95  if (m_reg_ctx_sp) {
96  const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
97  if (reg_set == nullptr)
98  m_reg_ctx_sp.reset();
99  else if (m_reg_set != reg_set) {
100  SetValueDidChange(true);
101  m_name.SetCString(reg_set->name);
102  }
103  }
104  }
105  if (m_reg_ctx_sp) {
106  SetValueIsValid(true);
107  } else {
108  SetValueIsValid(false);
110  m_children.Clear();
111  }
112  return m_error.Success();
113 }
114 
116  size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
117  ValueObject *valobj = nullptr;
118  if (m_reg_ctx_sp && m_reg_set) {
119  const size_t num_children = GetNumChildren();
120  if (idx < num_children)
121  valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
122  m_reg_set->registers[idx]);
123  }
124  return valobj;
125 }
126 
127 lldb::ValueObjectSP
129  bool can_create) {
130  ValueObject *valobj = nullptr;
131  if (m_reg_ctx_sp && m_reg_set) {
132  const RegisterInfo *reg_info =
133  m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef());
134  if (reg_info != nullptr)
135  valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
136  reg_info->kinds[eRegisterKindLLDB]);
137  }
138  if (valobj)
139  return valobj->GetSP();
140  else
141  return ValueObjectSP();
142 }
143 
144 size_t
146  if (m_reg_ctx_sp && m_reg_set) {
147  const RegisterInfo *reg_info =
148  m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef());
149  if (reg_info != nullptr)
150  return reg_info->kinds[eRegisterKindLLDB];
151  }
152  return UINT32_MAX;
153 }
154 
155 #pragma mark -
156 #pragma mark ValueObjectRegister
157 
159  const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
160  if (reg_info) {
161  m_reg_info = *reg_info;
162  if (reg_info->name)
163  m_name.SetCString(reg_info->name);
164  else if (reg_info->alt_name)
165  m_name.SetCString(reg_info->alt_name);
166  }
167 }
168 
170  lldb::RegisterContextSP &reg_ctx_sp,
171  uint32_t reg_num)
172  : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
173  m_reg_value(), m_type_name(), m_compiler_type() {
174  assert(reg_ctx_sp.get());
175  ConstructObject(reg_num);
176 }
177 
179  lldb::RegisterContextSP &reg_ctx_sp,
180  uint32_t reg_num) {
181  auto manager_sp = ValueObjectManager::Create();
182  return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_num))
183  ->GetSP();
184 }
185 
187  ValueObjectManager &manager,
188  lldb::RegisterContextSP &reg_ctx,
189  uint32_t reg_num)
190  : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
192  assert(reg_ctx);
193  ConstructObject(reg_num);
194 }
195 
197 
199  if (!m_compiler_type.IsValid()) {
201  if (auto *target = exe_ctx.GetTargetPtr()) {
202  if (auto *exe_module = target->GetExecutableModulePointer()) {
203  auto type_system_or_err =
204  exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
205  if (auto err = type_system_or_err.takeError()) {
208  std::move(err), "Unable to get CompilerType from TypeSystem");
209  } else {
211  type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
212  m_reg_info.encoding, m_reg_info.byte_size * 8);
213  }
214  }
215  }
216  }
217  return m_compiler_type;
218 }
219 
221  if (m_type_name.IsEmpty())
223  return m_type_name;
224 }
225 
228  auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
229  return children_count <= max ? children_count : max;
230 }
231 
232 uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
233 
235  m_error.Clear();
237  StackFrame *frame = exe_ctx.GetFramePtr();
238  if (frame == nullptr) {
239  m_reg_ctx_sp.reset();
240  m_reg_value.Clear();
241  }
242 
243  if (m_reg_ctx_sp) {
244  RegisterValue m_old_reg_value(m_reg_value);
245  if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
246  if (m_reg_value.GetData(m_data)) {
247  Process *process = exe_ctx.GetProcessPtr();
248  if (process)
251  (void *)&m_reg_info);
253  m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
254  SetValueIsValid(true);
255  SetValueDidChange(!(m_old_reg_value == m_reg_value));
256  return true;
257  }
258  }
259  }
260 
261  SetValueIsValid(false);
263  return false;
264 }
265 
266 bool ValueObjectRegister::SetValueFromCString(const char *value_str,
267  Status &error) {
268  // The new value will be in the m_data. Copy that into our register value.
269  error =
270  m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
271  if (error.Success()) {
272  if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
273  SetNeedsUpdate();
274  return true;
275  } else
276  return false;
277  } else
278  return false;
279 }
280 
282  error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
283  if (error.Success()) {
284  if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
285  SetNeedsUpdate();
286  return true;
287  } else
288  return false;
289  } else
290  return false;
291 }
292 
295  false)) // make sure that you are up to date before returning anything
296  return m_reg_value.GetScalarValue(scalar);
297  return false;
298 }
299 
301  GetExpressionPathFormat epformat) {
302  s.Printf("$%s", m_reg_info.name);
303 }
An data extractor class.
Definition: DataExtractor.h:46
CompilerType GetCompilerType()
A class that represents a running process on the host machine.
static std::shared_ptr< ClusterManager > Create()
Definition: SharedCluster.h:24
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void SetValueDidChange(bool value_changed)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
void SetValueType(ValueType value_type)
Definition: Value.h:144
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
bool SetData(DataExtractor &data, Status &error) override
uint32_t GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:265
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
ValueObject * CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override
Status SetValueFromString(const RegisterInfo *reg_info, llvm::StringRef value_str)
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
#define UINT32_MAX
Definition: lldb-defines.h:31
Target * GetTargetPtr() const
Returns a pointer to the target object.
void SetErrorToGenericError()
Set the current error to a generic error.
Definition: Status.cpp:232
lldb&#39;s internal register numbers
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
void Clear()
Clear the object state.
Definition: Status.cpp:168
size_t CalculateNumChildren(uint32_t max) override
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3431
bool ResolveValue(Scalar &scalar) override
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
lldb::ValueObjectSP GetChildMemberWithName(ConstString name, bool can_create) override
A plug-in interface definition class for debugging a process.
Definition: Process.h:362
Status SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
Process * GetProcessPtr() const
Returns a pointer to the process object.
ValueObjectRegisterSet(ExecutionContextScope *exe_scope, ValueObjectManager &manager, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:232
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:331
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:288
bool SetValueFromCString(const char *value_str, Status &error) override
void SetValueIsValid(bool valid)
ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
bool UpdateValueIfNeeded(bool update_format=true)
size_t CalculateNumChildren(uint32_t max) override
bool GetData(DataExtractor &data) const
const uint8_t * GetDataStart() const
Get the data start pointer.
A uniqued constant string class.
Definition: ConstString.h:40
void SetContext(ContextType context_type, void *p)
Definition: Value.h:151
Non-standardized C, such as K&R.
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:62
lldb::RegisterContextSP m_reg_ctx_sp
Definition: SBAddress.h:15
Represents a generic type in a programming language.
Definition: CompilerType.h:33
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:539
CompilerType GetCompilerTypeImpl() override
bool GetScalarValue(Scalar &scalar) const
size_t GetNumChildren(uint32_t max=UINT32_MAX)
ChildrenManager m_children
Definition: ValueObject.h:855
#define LIBLLDB_LOG_TYPES
Definition: Logging.h:33
const Scalar & GetScalar() const
Definition: Value.h:168
ConstString GetTypeName() const
size_t GetIndexOfChildWithName(ConstString name) override
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:334
void GetExpressionPath(Stream &s, GetExpressionPathFormat epformat=eGetExpressionPathFormatDereferencePointers) override
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
An error handling class.
Definition: Status.h:44
void SetCString(const char *cstr)
Set the C string value.