LLDB  mainline
ValueObjectVariable.cpp
Go to the documentation of this file.
1 //===-- ValueObjectVariable.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/Address.h"
12 #include "lldb/Core/AddressRange.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/Value.h"
17 #include "lldb/Symbol/Function.h"
18 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/Type.h"
22 #include "lldb/Symbol/Variable.h"
24 #include "lldb/Target/Process.h"
26 #include "lldb/Target/Target.h"
29 #include "lldb/Utility/Scalar.h"
30 #include "lldb/Utility/Status.h"
32 #include "lldb/lldb-types.h"
33 
34 #include "llvm/ADT/StringRef.h"
35 
36 #include <assert.h>
37 #include <memory>
38 
39 namespace lldb_private {
41 }
42 namespace lldb_private {
43 class StackFrame;
44 }
45 namespace lldb_private {
46 struct RegisterInfo;
47 }
48 using namespace lldb_private;
49 
50 lldb::ValueObjectSP
52  const lldb::VariableSP &var_sp) {
53  return (new ValueObjectVariable(exe_scope, var_sp))->GetSP();
54 }
55 
56 ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope,
57  const lldb::VariableSP &var_sp)
58  : ValueObject(exe_scope), m_variable_sp(var_sp) {
59  // Do not attempt to construct one of these objects with no variable!
60  assert(m_variable_sp.get() != NULL);
61  m_name = var_sp->GetName();
62 }
63 
65 
67  Type *var_type = m_variable_sp->GetType();
68  if (var_type)
69  return var_type->GetForwardCompilerType();
70  return CompilerType();
71 }
72 
74  Type *var_type = m_variable_sp->GetType();
75  if (var_type)
76  return var_type->GetName();
77  return ConstString();
78 }
79 
81  Type *var_type = m_variable_sp->GetType();
82  if (var_type)
83  return var_type->GetForwardCompilerType().GetDisplayTypeName();
84  return ConstString();
85 }
86 
88  Type *var_type = m_variable_sp->GetType();
89  if (var_type)
90  return var_type->GetQualifiedName();
91  return ConstString();
92 }
93 
96 
97  if (!type.IsValid())
98  return 0;
99 
101  const bool omit_empty_base_classes = true;
102  auto child_count = type.GetNumChildren(omit_empty_base_classes, &exe_ctx);
103  return child_count <= max ? child_count : max;
104 }
105 
108 
110 
111  if (!type.IsValid())
112  return 0;
113 
114  return type.GetByteSize(exe_ctx.GetBestExecutionContextScope()).getValueOr(0);
115 }
116 
118  if (m_variable_sp)
119  return m_variable_sp->GetScope();
121 }
122 
124  SetValueIsValid(false);
125  m_error.Clear();
126 
127  Variable *variable = m_variable_sp.get();
128  DWARFExpression &expr = variable->LocationExpression();
129 
130  if (variable->GetLocationIsConstantValueData()) {
131  // expr doesn't contain DWARF bytes, it contains the constant variable
132  // value bytes themselves...
133  if (expr.GetExpressionData(m_data))
135  else
136  m_error.SetErrorString("empty constant data");
137  // constant bytes can't be edited - sorry
139  } else {
140  lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
142 
143  Target *target = exe_ctx.GetTargetPtr();
144  if (target) {
147  }
148 
149  if (expr.IsLocationList()) {
150  SymbolContext sc;
151  variable->CalculateSymbolContext(&sc);
152  if (sc.function)
153  loclist_base_load_addr =
155  target);
156  }
157  Value old_value(m_value);
158  if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
159  nullptr, m_value, &m_error)) {
162 
163  CompilerType compiler_type = GetCompilerType();
164  if (compiler_type.IsValid())
165  m_value.SetCompilerType(compiler_type);
166 
167  Value::ValueType value_type = m_value.GetValueType();
168 
169  Process *process = exe_ctx.GetProcessPtr();
170  const bool process_is_alive = process && process->IsAlive();
171  const uint32_t type_info = compiler_type.GetTypeInfo();
172  const bool is_pointer_or_ref =
173  (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
174 
175  switch (value_type) {
177  // If this type is a pointer, then its children will be considered load
178  // addresses if the pointer or reference is dereferenced, but only if
179  // the process is alive.
180  //
181  // There could be global variables like in the following code:
182  // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
183  // Foo g_foo1;
184  // Foo g_foo2;
185  // LinkedListNode g_second_node = { &g_foo2, NULL };
186  // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
187  //
188  // When we aren't running, we should be able to look at these variables
189  // using the "target variable" command. Children of the "g_first_node"
190  // always will be of the same address type as the parent. But children
191  // of the "next" member of LinkedListNode will become load addresses if
192  // we have a live process, or remain what a file address if it what a
193  // file address.
194  if (process_is_alive && is_pointer_or_ref)
196  else
198  break;
200  // Same as above for load addresses, except children of pointer or refs
201  // are always load addresses. Host addresses are used to store freeze
202  // dried variables. If this type is a struct, the entire struct
203  // contents will be copied into the heap of the
204  // LLDB process, but we do not currently follow any pointers.
205  if (is_pointer_or_ref)
207  else
209  break;
214  break;
215  }
216 
217  switch (value_type) {
219  // fall through
221  // The variable value is in the Scalar value inside the m_value. We can
222  // point our m_data right to it.
223  m_error =
224  m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
225  break;
226 
230  // The DWARF expression result was an address in the inferior process.
231  // If this variable is an aggregate type, we just need the address as
232  // the main value as all child variable objects will rely upon this
233  // location and add an offset and then read their own values as needed.
234  // If this variable is a simple type, we read all data for it into
235  // m_data. Make sure this type has a value before we try and read it
236 
237  // If we have a file address, convert it to a load address if we can.
238  if (value_type == Value::eValueTypeFileAddress && process_is_alive)
239  m_value.ConvertToLoadAddress(GetModule().get(), target);
240 
241  if (!CanProvideValue()) {
242  // this value object represents an aggregate type whose children have
243  // values, but this object does not. So we say we are changed if our
244  // location has changed.
245  SetValueDidChange(value_type != old_value.GetValueType() ||
246  m_value.GetScalar() != old_value.GetScalar());
247  } else {
248  // Copy the Value and set the context to use our Variable so it can
249  // extract read its value into m_data appropriately
250  Value value(m_value);
251  value.SetContext(Value::eContextTypeVariable, variable);
252  m_error =
253  value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
254 
255  SetValueDidChange(value_type != old_value.GetValueType() ||
256  m_value.GetScalar() != old_value.GetScalar());
257  }
258  break;
259  }
260 
262  } else {
263  // could not find location, won't allow editing
265  }
266  }
267  return m_error.Success();
268 }
269 
271  const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
272  if (exe_ctx_ref.HasFrameRef()) {
273  ExecutionContext exe_ctx(exe_ctx_ref);
274  StackFrame *frame = exe_ctx.GetFramePtr();
275  if (frame) {
276  return m_variable_sp->IsInScope(frame);
277  } else {
278  // This ValueObject had a frame at one time, but now we can't locate it,
279  // so return false since we probably aren't in scope.
280  return false;
281  }
282  }
283  // We have a variable that wasn't tied to a frame, which means it is a global
284  // and is always in scope.
285  return true;
286 }
287 
289  if (m_variable_sp) {
290  SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
291  if (sc_scope) {
292  return sc_scope->CalculateSymbolContextModule();
293  }
294  }
295  return lldb::ModuleSP();
296 }
297 
299  if (m_variable_sp)
300  return m_variable_sp->GetSymbolContextScope();
301  return NULL;
302 }
303 
305  if (m_variable_sp) {
306  decl = m_variable_sp->GetDeclaration();
307  return true;
308  }
309  return false;
310 }
311 
315  else
317 }
318 
319 bool ValueObjectVariable::SetValueFromCString(const char *value_str,
320  Status &error) {
321  if (!UpdateValueIfNeeded()) {
322  error.SetErrorString("unable to update value before writing");
323  return false;
324  }
325 
327  RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
329  RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
330  RegisterValue reg_value;
331  if (!reg_info || !reg_ctx) {
332  error.SetErrorString("unable to retrieve register info");
333  return false;
334  }
335  error = reg_value.SetValueFromString(reg_info, llvm::StringRef(value_str));
336  if (error.Fail())
337  return false;
338  if (reg_ctx->WriteRegister(reg_info, reg_value)) {
339  SetNeedsUpdate();
340  return true;
341  } else {
342  error.SetErrorString("unable to write back to register");
343  return false;
344  }
345  } else
346  return ValueObject::SetValueFromCString(value_str, error);
347 }
348 
350  if (!UpdateValueIfNeeded()) {
351  error.SetErrorString("unable to update value before writing");
352  return false;
353  }
354 
356  RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
358  RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
359  RegisterValue reg_value;
360  if (!reg_info || !reg_ctx) {
361  error.SetErrorString("unable to retrieve register info");
362  return false;
363  }
364  error = reg_value.SetValueFromData(reg_info, data, 0, true);
365  if (error.Fail())
366  return false;
367  if (reg_ctx->WriteRegister(reg_info, reg_value)) {
368  SetNeedsUpdate();
369  return true;
370  } else {
371  error.SetErrorString("unable to write back to register");
372  return false;
373  }
374  } else
375  return ValueObject::SetData(data, error);
376 }
lldb::VariableSP m_variable_sp
The variable that this value object is based upon.
An data extractor class.
Definition: DataExtractor.h:47
CompilerType GetCompilerType()
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool SetValueFromCString(const char *value_str, Status &error) override
const ArchSpec & GetArchitecture() const
Definition: Target.h:941
Address is an address as found in an object or symbol file.
ConstString GetDisplayTypeName() override
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:742
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:292
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it...
SymbolContextScope * GetSymbolContextScope() override
virtual bool SetValueFromCString(const char *value_str, Status &error)
RegisterInfo * GetRegisterInfo() const
Definition: Value.cpp:131
void SetValueDidChange(bool value_changed)
Value m_resolved_value
The value that DWARFExpression resolves this variable to before we patch it up.
Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, uint32_t data_offset, Module *module)
Definition: Value.cpp:316
void ConvertToLoadAddress(Module *module, Target *target)
Convert this value&#39;s file address to a load address, if possible.
Definition: Value.cpp:671
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
const char * GetLocationAsCStringImpl(const Value &value, const DataExtractor &data)
bool GetLocationIsConstantValueData() const
Definition: Variable.h:90
size_t CalculateNumChildren(uint32_t max) override
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
uint32_t GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
void SetAddressTypeOfChildren(AddressType at)
Definition: ValueObject.h:777
Status SetValueFromString(const RegisterInfo *reg_info, llvm::StringRef value_str)
Function * function
The Function for a given query.
virtual const char * GetLocationAsCString()
DWARFExpression & LocationExpression()
Definition: Variable.h:74
virtual bool SetData(DataExtractor &data, Status &error)
ConstString GetName()
Definition: Type.cpp:275
ValueType GetValueType() const
Definition: Value.cpp:114
Target * GetTargetPtr() const
Returns a pointer to the target object.
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
virtual bool CanProvideValue()
Address is an address in the process that is running this code.
bool SetData(DataExtractor &data, Status &error) override
void Clear()
Clear the object state.
Definition: Status.cpp:167
virtual lldb::ModuleSP CalculateSymbolContextModule()
RegisterContext * GetRegisterContext() const
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
ContextType GetContextType() const
Definition: Value.h:152
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
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.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:788
void CalculateSymbolContext(SymbolContext *sc)
Definition: Variable.cpp:212
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:353
lldb::ValueType GetValueType() const override
ConstString GetDisplayTypeName() const
bool Success() const
Test for success condition.
Definition: Status.cpp:287
Execution context objects refer to objects in the execution of the program that is being debugged...
ConstString GetQualifiedName()
Definition: Type.cpp:626
CompilerType GetForwardCompilerType()
Definition: Type.cpp:610
void SetValueIsValid(bool valid)
bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t loclist_base_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) const
Wrapper for the static evaluate function that accepts an ExecutionContextScope instead of an Executio...
uint64_t addr_t
Definition: lldb-types.h:83
bool UpdateValueIfNeeded(bool update_format=true)
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
void SetContext(ContextType context_type, void *p)
Definition: Value.h:161
virtual bool IsAlive()
Check if a process is still alive.
Definition: Process.cpp:1182
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:220
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:268
bool HasFrameRef() const
Returns true if this object has a weak reference to a frame.
CompilerType GetCompilerTypeImpl() override
const Scalar & GetScalar() const
Definition: Value.h:178
ConstString GetQualifiedTypeName() override
Address is an address as in the current target inferior process.
const AddressRange & GetAddressRange()
Definition: Function.h:371
ExecutionContextScope * GetBestExecutionContextScope() const
A class that describes the declaration location of a lldb object.
Definition: Declaration.h:24
bool IsLocationList() const
Return true if a location list was provided.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
bool GetExpressionData(DataExtractor &data) const
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
const char * GetLocationAsCString() override
bool GetDeclaration(Declaration &decl) override
An error handling class.
Definition: Status.h:44
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.