LLDB  mainline
ValueObjectRegister.cpp
Go to the documentation of this file.
1 //===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===//
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/Scalar.h"
22 #include "lldb/Utility/Status.h"
23 #include "lldb/Utility/Stream.h"
24 
25 #include "llvm/ADT/StringRef.h"
26 
27 #include <assert.h>
28 #include <memory>
29 
30 namespace lldb_private {
32 }
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 #pragma mark ValueObjectRegisterContext
38 
39 ValueObjectRegisterContext::ValueObjectRegisterContext(
40  ValueObject &parent, RegisterContextSP &reg_ctx)
41  : ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
42  assert(reg_ctx);
43  m_name.SetCString("Registers");
44  SetValueIsValid(true);
45 }
46 
48 
50  return CompilerType();
51 }
52 
54 
56  return ConstString();
57 }
58 
60  return ConstString();
61 }
62 
64  auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
65  return reg_set_count <= max ? reg_set_count : max;
66 }
67 
69 
71  m_error.Clear();
72  ExecutionContext exe_ctx(GetExecutionContextRef());
73  StackFrame *frame = exe_ctx.GetFramePtr();
74  if (frame)
75  m_reg_ctx_sp = frame->GetRegisterContext();
76  else
77  m_reg_ctx_sp.reset();
78 
79  if (m_reg_ctx_sp.get() == NULL) {
80  SetValueIsValid(false);
81  m_error.SetErrorToGenericError();
82  } else
83  SetValueIsValid(true);
84 
85  return m_error.Success();
86 }
87 
89  size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
90  ValueObject *new_valobj = NULL;
91 
92  const size_t num_children = GetNumChildren();
93  if (idx < num_children) {
94  ExecutionContext exe_ctx(GetExecutionContextRef());
95  new_valobj = new ValueObjectRegisterSet(
96  exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
97  }
98 
99  return new_valobj;
100 }
101 
102 #pragma mark -
103 #pragma mark ValueObjectRegisterSet
104 
105 ValueObjectSP
107  lldb::RegisterContextSP &reg_ctx_sp,
108  uint32_t set_idx) {
109  return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
110 }
111 
112 ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
113  lldb::RegisterContextSP &reg_ctx,
114  uint32_t reg_set_idx)
115  : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(NULL),
116  m_reg_set_idx(reg_set_idx) {
117  assert(reg_ctx);
118  m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
119  if (m_reg_set) {
120  m_name.SetCString(m_reg_set->name);
121  }
122 }
123 
125 
127  return CompilerType();
128 }
129 
131 
133  return ConstString();
134 }
135 
137  const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
138  if (reg_set) {
139  auto reg_count = reg_set->num_registers;
140  return reg_count <= max ? reg_count : max;
141  }
142  return 0;
143 }
144 
145 uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
146 
148  m_error.Clear();
149  SetValueDidChange(false);
150  ExecutionContext exe_ctx(GetExecutionContextRef());
151  StackFrame *frame = exe_ctx.GetFramePtr();
152  if (frame == NULL)
153  m_reg_ctx_sp.reset();
154  else {
155  m_reg_ctx_sp = frame->GetRegisterContext();
156  if (m_reg_ctx_sp) {
157  const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
158  if (reg_set == NULL)
159  m_reg_ctx_sp.reset();
160  else if (m_reg_set != reg_set) {
161  SetValueDidChange(true);
162  m_name.SetCString(reg_set->name);
163  }
164  }
165  }
166  if (m_reg_ctx_sp) {
167  SetValueIsValid(true);
168  } else {
169  SetValueIsValid(false);
170  m_error.SetErrorToGenericError();
171  m_children.Clear();
172  }
173  return m_error.Success();
174 }
175 
177  size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
178  ValueObject *valobj = NULL;
179  if (m_reg_ctx_sp && m_reg_set) {
180  const size_t num_children = GetNumChildren();
181  if (idx < num_children)
182  valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
183  m_reg_set->registers[idx]);
184  }
185  return valobj;
186 }
187 
188 lldb::ValueObjectSP
190  bool can_create) {
191  ValueObject *valobj = NULL;
192  if (m_reg_ctx_sp && m_reg_set) {
193  const RegisterInfo *reg_info =
194  m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
195  if (reg_info != NULL)
196  valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
197  reg_info->kinds[eRegisterKindLLDB]);
198  }
199  if (valobj)
200  return valobj->GetSP();
201  else
202  return ValueObjectSP();
203 }
204 
205 size_t
207  if (m_reg_ctx_sp && m_reg_set) {
208  const RegisterInfo *reg_info =
209  m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
210  if (reg_info != NULL)
211  return reg_info->kinds[eRegisterKindLLDB];
212  }
213  return UINT32_MAX;
214 }
215 
216 #pragma mark -
217 #pragma mark ValueObjectRegister
218 
219 void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
220  const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
221  if (reg_info) {
222  m_reg_info = *reg_info;
223  if (reg_info->name)
224  m_name.SetCString(reg_info->name);
225  else if (reg_info->alt_name)
226  m_name.SetCString(reg_info->alt_name);
227  }
228 }
229 
230 ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
231  lldb::RegisterContextSP &reg_ctx_sp,
232  uint32_t reg_num)
233  : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
234  m_reg_value(), m_type_name(), m_compiler_type() {
235  assert(reg_ctx_sp.get());
236  ConstructObject(reg_num);
237 }
238 
240  lldb::RegisterContextSP &reg_ctx_sp,
241  uint32_t reg_num) {
242  return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
243 }
244 
245 ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
246  lldb::RegisterContextSP &reg_ctx,
247  uint32_t reg_num)
248  : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
249  m_reg_value(), m_type_name(), m_compiler_type() {
250  assert(reg_ctx);
251  ConstructObject(reg_num);
252 }
253 
255 
257  if (!m_compiler_type.IsValid()) {
258  ExecutionContext exe_ctx(GetExecutionContextRef());
259  Target *target = exe_ctx.GetTargetPtr();
260  if (target) {
261  Module *exe_module = target->GetExecutableModulePointer();
262  if (exe_module) {
263  TypeSystem *type_system =
265  if (type_system)
266  m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
267  m_reg_info.encoding, m_reg_info.byte_size * 8);
268  }
269  }
270  }
271  return m_compiler_type;
272 }
273 
275  if (m_type_name.IsEmpty())
276  m_type_name = GetCompilerType().GetConstTypeName();
277  return m_type_name;
278 }
279 
281  ExecutionContext exe_ctx(GetExecutionContextRef());
282  auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
283  return children_count <= max ? children_count : max;
284 }
285 
286 uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
287 
289  m_error.Clear();
290  ExecutionContext exe_ctx(GetExecutionContextRef());
291  StackFrame *frame = exe_ctx.GetFramePtr();
292  if (frame == NULL) {
293  m_reg_ctx_sp.reset();
294  m_reg_value.Clear();
295  }
296 
297  if (m_reg_ctx_sp) {
298  RegisterValue m_old_reg_value(m_reg_value);
299  if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
300  if (m_reg_value.GetData(m_data)) {
301  Process *process = exe_ctx.GetProcessPtr();
302  if (process)
303  m_data.SetAddressByteSize(process->GetAddressByteSize());
304  m_value.SetContext(Value::eContextTypeRegisterInfo,
305  (void *)&m_reg_info);
306  m_value.SetValueType(Value::eValueTypeHostAddress);
307  m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
308  SetValueIsValid(true);
309  SetValueDidChange(!(m_old_reg_value == m_reg_value));
310  return true;
311  }
312  }
313  }
314 
315  SetValueIsValid(false);
316  m_error.SetErrorToGenericError();
317  return false;
318 }
319 
320 bool ValueObjectRegister::SetValueFromCString(const char *value_str,
321  Status &error) {
322  // The new value will be in the m_data. Copy that into our register value.
323  error =
324  m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
325  if (error.Success()) {
326  if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
327  SetNeedsUpdate();
328  return true;
329  } else
330  return false;
331  } else
332  return false;
333 }
334 
336  error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
337  if (error.Success()) {
338  if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
339  SetNeedsUpdate();
340  return true;
341  } else
342  return false;
343  } else
344  return false;
345 }
346 
348  if (UpdateValueIfNeeded(
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 
355  bool qualify_cxx_base_classes,
356  GetExpressionPathFormat epformat) {
357  s.Printf("$%s", m_reg_info.name);
358 }
An data extractor class.
Definition: DataExtractor.h:47
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat=eGetExpressionPathFormatDereferencePointers) override
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Module * GetExecutableModulePointer()
Definition: Target.cpp:1394
bool SetData(DataExtractor &data, Status &error) override
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
ValueObject * CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override
ValueObject * CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override
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.
TypeSystem * GetTypeSystemForLanguage(lldb::LanguageType language)
Definition: Module.cpp:355
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
size_t CalculateNumChildren(uint32_t max) override
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3370
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:353
Process * GetProcessPtr() const
Returns a pointer to the process object.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
virtual CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size)=0
bool Success() const
Test for success condition.
Definition: Status.cpp:287
bool SetValueFromCString(const char *value_str, Status &error) override
size_t CalculateNumChildren(uint32_t max) override
A uniqued constant string class.
Definition: ConstString.h:38
Non-standardized C, such as K&R.
Definition: SBAddress.h:15
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:565
CompilerType GetCompilerTypeImpl() override
size_t GetIndexOfChildWithName(ConstString name) override
size_t CalculateNumChildren(uint32_t max) override
ExecutionContextScope * GetBestExecutionContextScope() const
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
An error handling class.
Definition: Status.h:44