LLDB mainline
ValueObjectVariable.cpp
Go to the documentation of this file.
1//===-- ValueObjectVariable.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/Address.h"
14#include "lldb/Core/Module.h"
15#include "lldb/Core/Value.h"
21#include "lldb/Symbol/Type.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 <cassert>
37#include <memory>
38#include <optional>
39
40namespace lldb_private {
42}
43namespace lldb_private {
44class StackFrame;
45}
46namespace lldb_private {
47struct RegisterInfo;
48}
49using namespace lldb_private;
50
53 const lldb::VariableSP &var_sp) {
54 auto manager_sp = ValueObjectManager::Create();
55 return (new ValueObjectVariable(exe_scope, *manager_sp, var_sp))->GetSP();
56}
57
59 ValueObjectManager &manager,
60 const lldb::VariableSP &var_sp)
61 : ValueObject(exe_scope, manager), m_variable_sp(var_sp) {
62 // Do not attempt to construct one of these objects with no variable!
63 assert(m_variable_sp.get() != nullptr);
64 m_name = var_sp->GetName();
65}
66
68
70 Type *var_type = m_variable_sp->GetType();
71 if (var_type)
72 return var_type->GetForwardCompilerType();
73 return CompilerType();
74}
75
77 Type *var_type = m_variable_sp->GetType();
78 if (var_type)
79 return var_type->GetName();
80 return ConstString();
81}
82
84 Type *var_type = m_variable_sp->GetType();
85 if (var_type)
86 return var_type->GetForwardCompilerType().GetDisplayTypeName();
87 return ConstString();
88}
89
91 Type *var_type = m_variable_sp->GetType();
92 if (var_type)
93 return var_type->GetQualifiedName();
94 return ConstString();
95}
96
97llvm::Expected<uint32_t>
100
101 if (!type.IsValid())
102 return llvm::createStringError("invalid type");
103
105 const bool omit_empty_base_classes = true;
106 auto child_count = type.GetNumChildren(omit_empty_base_classes, &exe_ctx);
107 if (!child_count)
108 return child_count;
109 return *child_count <= max ? *child_count : max;
110}
111
112llvm::Expected<uint64_t> ValueObjectVariable::GetByteSize() {
114
116 return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
117}
118
124
126 SetValueIsValid(false);
127 m_error.Clear();
128
129 Variable *variable = m_variable_sp.get();
130 DWARFExpressionList &expr_list = variable->LocationExpressionList();
131
132 if (variable->GetLocationIsConstantValueData()) {
133 // expr doesn't contain DWARF bytes, it contains the constant variable
134 // value bytes themselves...
135 if (expr_list.GetExpressionData(m_data)) {
136 if (m_data.GetDataStart() && m_data.GetByteSize())
137 m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
138 m_value.SetContext(Value::ContextType::Variable, variable);
139 } else
140 m_error = Status::FromErrorString("empty constant data");
141 // constant bytes can't be edited - sorry
144 } else {
145 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
147
148 Target *target = exe_ctx.GetTargetPtr();
149 if (target) {
150 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
151 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
152 }
153
154 if (!expr_list.IsAlwaysValidSingleExpr()) {
155 SymbolContext sc;
156 variable->CalculateSymbolContext(&sc);
157 if (sc.function)
158 loclist_base_load_addr =
159 sc.function->GetAddress().GetLoadAddress(target);
160 }
161 Value old_value(m_value);
162 llvm::Expected<Value> maybe_value = expr_list.Evaluate(
163 &exe_ctx, nullptr, loclist_base_load_addr, nullptr, nullptr);
164
165 if (maybe_value) {
166 m_value = *maybe_value;
169 expr_list.IsImplicit(&exe_ctx, nullptr, loclist_base_load_addr);
170 m_value.SetContext(Value::ContextType::Variable, variable);
171
172 CompilerType compiler_type = GetCompilerType();
173 if (compiler_type.IsValid())
174 m_value.SetCompilerType(compiler_type);
175
176 Value::ValueType value_type = m_value.GetValueType();
177
178 // The size of the buffer within m_value can be less than the size
179 // prescribed by its type. E.g. this can happen when an expression only
180 // partially describes an object (say, because it contains DW_OP_piece).
181 //
182 // In this case, grow m_value to the expected size. An alternative way to
183 // handle this is to teach Value::GetValueAsData() and ValueObjectChild
184 // not to read past the end of a host buffer, but this gets impractically
185 // complicated as a Value's host buffer may be shared with a distant
186 // ancestor or sibling in the ValueObject hierarchy.
187 //
188 // FIXME: When we grow m_value, we should represent the added bits as
189 // undefined somehow instead of as 0's.
190 if (value_type == Value::ValueType::HostAddress &&
191 compiler_type.IsValid()) {
192 if (size_t value_buf_size = m_value.GetBuffer().GetByteSize()) {
193 size_t value_size = m_value.GetValueByteSize(&m_error, &exe_ctx);
194 if (m_error.Success() && value_buf_size < value_size)
195 m_value.ResizeData(value_size);
196 }
197 }
198
199 Process *process = exe_ctx.GetProcessPtr();
200 const bool process_is_alive = process && process->IsAlive();
201
202 switch (value_type) {
204 m_error = Status::FromErrorString("invalid value");
205 break;
207 // The variable value is in the Scalar value inside the m_value. We can
208 // point our m_data right to it.
209 m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
210 break;
211
215 // The DWARF expression result was an address in the inferior process.
216 // If this variable is an aggregate type, we just need the address as
217 // the main value as all child variable objects will rely upon this
218 // location and add an offset and then read their own values as needed.
219 // If this variable is a simple type, we read all data for it into
220 // m_data. Make sure this type has a value before we try and read it
221
222 // If we have a file address, convert it to a load address if we can.
223 if (value_type == Value::ValueType::FileAddress && process_is_alive)
224 m_value.ConvertToLoadAddress(GetModule().get(), target);
225
226 if (!CanProvideValue()) {
227 // this value object represents an aggregate type whose children have
228 // values, but this object does not. So we say we are changed if our
229 // location has changed.
230 SetValueDidChange(value_type != old_value.GetValueType() ||
231 m_value.GetScalar() != old_value.GetScalar());
232 } else {
233 // Copy the Value and set the context to use our Variable so it can
234 // extract read its value into m_data appropriately
235 Value value(m_value);
237 m_error = value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
238
239 SetValueDidChange(value_type != old_value.GetValueType() ||
240 m_value.GetScalar() != old_value.GetScalar());
241 }
242 break;
243 }
244
245 SetValueIsValid(m_error.Success());
246 } else {
247 m_error = Status::FromError(maybe_value.takeError());
248 // could not find location, won't allow editing
251 }
252 }
253
254 return m_error.Success();
255}
256
258 Value::ValueType value_type = valobj.GetValue().GetValueType();
260 Process *process = exe_ctx.GetProcessPtr();
261 const bool process_is_alive = process && process->IsAlive();
262 const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
263 const bool is_pointer_or_ref =
264 (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
265
266 switch (value_type) {
268 break;
270 // If this type is a pointer, then its children will be considered load
271 // addresses if the pointer or reference is dereferenced, but only if
272 // the process is alive.
273 //
274 // There could be global variables like in the following code:
275 // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
276 // Foo g_foo1;
277 // Foo g_foo2;
278 // LinkedListNode g_second_node = { &g_foo2, NULL };
279 // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
280 //
281 // When we aren't running, we should be able to look at these variables
282 // using the "target variable" command. Children of the "g_first_node"
283 // always will be of the same address type as the parent. But children
284 // of the "next" member of LinkedListNode will become load addresses if
285 // we have a live process, or remain a file address if it was a file
286 // address.
287 if (process_is_alive && is_pointer_or_ref)
289 else
291 break;
293 // Same as above for load addresses, except children of pointer or refs
294 // are always load addresses. Host addresses are used to store freeze
295 // dried variables. If this type is a struct, the entire struct
296 // contents will be copied into the heap of the
297 // LLDB process, but we do not currently follow any pointers.
298 if (is_pointer_or_ref)
300 else
302 break;
306 break;
307 }
308}
309
311 const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
312 if (exe_ctx_ref.HasFrameRef()) {
313 ExecutionContext exe_ctx(exe_ctx_ref);
314 StackFrame *frame = exe_ctx.GetFramePtr();
315 if (frame) {
316 return m_variable_sp->IsInScope(frame);
317 } else {
318 // This ValueObject had a frame at one time, but now we can't locate it,
319 // so return false since we probably aren't in scope.
320 return false;
321 }
322 }
323 // We have a variable that wasn't tied to a frame, which means it is a global
324 // and is always in scope.
325 return true;
326}
327
329 if (m_variable_sp) {
330 SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
331 if (sc_scope) {
332 return sc_scope->CalculateSymbolContextModule();
333 }
334 }
335 return lldb::ModuleSP();
336}
337
339 if (m_variable_sp)
340 return m_variable_sp->GetSymbolContextScope();
341 return nullptr;
342}
343
345 if (m_variable_sp) {
346 decl = m_variable_sp->GetDeclaration();
347 return true;
348 }
349 return false;
350}
351
358
360 // Refresh the resolved location so m_resolved_value_is_implicit is current.
363}
364
366 Status &error) {
367 if (!UpdateValueIfNeeded()) {
368 error = Status::FromErrorString("unable to update value before writing");
369 return false;
370 }
371
373 error = Status::FromErrorString("Cannot change the value of a constant");
374 return false;
375 }
376
377 if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) {
378 RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
380 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
381 RegisterValue reg_value;
382 if (!reg_info || !reg_ctx) {
383 error = Status::FromErrorString("unable to retrieve register info");
384 return false;
385 }
386 error = reg_value.SetValueFromString(reg_info, llvm::StringRef(value_str));
387 if (error.Fail())
388 return false;
389 if (reg_ctx->WriteRegister(reg_info, reg_value)) {
391 return true;
392 } else {
393 error = Status::FromErrorString("unable to write back to register");
394 return false;
395 }
396 } else
397 return ValueObject::SetValueFromCString(value_str, error);
398}
399
401 if (!UpdateValueIfNeeded()) {
402 error = Status::FromErrorString("unable to update value before writing");
403 return false;
404 }
405
407 error = Status::FromErrorString("Cannot change the value of a constant");
408 return false;
409 }
410
411 if (m_resolved_value.GetContextType() == Value::ContextType::RegisterInfo) {
412 RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
414 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
415 RegisterValue reg_value;
416 if (!reg_info || !reg_ctx) {
417 error = Status::FromErrorString("unable to retrieve register info");
418 return false;
419 }
420 error = reg_value.SetValueFromData(*reg_info, data, 0, true);
421 if (error.Fail())
422 return false;
423 if (reg_ctx->WriteRegister(reg_info, reg_value)) {
425 return true;
426 } else {
427 error = Status::FromErrorString("unable to write back to register");
428 return false;
429 }
430 } else
431 return ValueObject::SetData(data, error);
432}
static llvm::raw_ostream & error(Stream &strm)
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:889
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:938
static std::shared_ptr< ClusterManager > Create()
Generic representation of a type in a programming language.
ConstString GetDisplayTypeName() const
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) 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
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool IsImplicit(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr) const
Return true if the expression in scope at the current PC produces an implicit location,...
llvm::Expected< Value > Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr) const
bool GetExpressionData(DataExtractor &data, lldb::addr_t func_load_addr=LLDB_INVALID_ADDRESS, lldb::addr_t file_addr=0) const
Get the expression data at the file address.
An data extractor class.
A class that describes the declaration location of a lldb object.
Definition Declaration.h:24
Execution context objects refer to objects in the execution of the program that is being debugged.
bool HasFrameRef() const
Returns true if this object has a weak reference to a frame.
"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.
ExecutionContextScope * GetBestExecutionContextScope() const
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.
RegisterContext * GetRegisterContext() const
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition Function.h:429
A plug-in interface definition class for debugging a process.
Definition Process.h:359
virtual bool IsAlive()
Check if a process is still alive.
Definition Process.cpp:1106
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
Status SetValueFromString(const RegisterInfo *reg_info, llvm::StringRef value_str)
Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
This base class provides an interface to stack frames.
Definition StackFrame.h:44
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
virtual lldb::ModuleSP CalculateSymbolContextModule()
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
const ArchSpec & GetArchitecture() const
Definition Target.h:1285
CompilerType GetForwardCompilerType()
Definition Type.cpp:791
ConstString GetName()
Definition Type.cpp:442
ConstString GetQualifiedName()
Definition Type.cpp:796
ValueObjectVariable(ExecutionContextScope *exe_scope, ValueObjectManager &manager, const lldb::VariableSP &var_sp)
bool CanSetValue() override
Returns false when this value cannot be modified through SetValueFromCString() or SetData() because i...
lldb::ValueType GetValueType() const override
SymbolContextScope * GetSymbolContextScope() override
lldb::ModuleSP GetModule() override
Return the module associated with this value object in case the value is from an executable file and ...
void DoUpdateChildrenAddressType(ValueObject &valobj) override
bool SetData(DataExtractor &data, Status &error) override
const char * GetLocationAsCString() override
bool m_resolved_value_is_implicit
True when the resolved value has no writable storage in the inferior (an implicit location,...
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
Value m_resolved_value
The value that DWARFExpression resolves this variable to before we patch it up.
ConstString GetQualifiedTypeName() override
bool SetValueFromCString(const char *value_str, Status &error) override
lldb::VariableSP m_variable_sp
The variable that this value object is based upon.
llvm::Expected< uint32_t > CalculateNumChildren(uint32_t max) override
Should only be called by ValueObject::GetNumChildren().
llvm::Expected< uint64_t > GetByteSize() override
bool GetDeclaration(Declaration &decl) override
CompilerType GetCompilerTypeImpl() 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".
Status m_error
An error object that can describe any errors that occur when updating values.
virtual bool CanSetValue()
Returns false when this value cannot be modified through SetValueFromCString() or SetData() because i...
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()
virtual const char * GetLocationAsCString()
virtual bool SetValueFromCString(const char *value_str, Status &error)
virtual bool SetData(DataExtractor &data, Status &error)
ConstString m_name
The name of this object.
const char * GetLocationAsCStringImpl(const Value &value, const DataExtractor &data)
const ExecutionContextRef & GetExecutionContextRef() const
const Value & GetValue() const
void SetAddressTypeOfChildren(AddressType at)
const Scalar & GetScalar() const
See comment on m_scalar to understand what GetScalar returns.
Definition Value.h:114
Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, Module *module)
Definition Value.cpp:323
ValueType
Type that describes Value::m_value.
Definition Value.h:42
@ HostAddress
A host address value (for memory in the process that < A is using liblldb).
Definition Value.h:53
@ FileAddress
A file address value.
Definition Value.h:48
@ LoadAddress
A load address value.
Definition Value.h:50
@ Scalar
A raw scalar value.
Definition Value.h:46
ValueType GetValueType() const
Definition Value.cpp:111
void SetContext(ContextType context_type, void *p)
Definition Value.h:97
@ Variable
lldb_private::Variable *.
Definition Value.h:66
@ RegisterInfo
RegisterInfo * (can be a scalar or a vector register).
Definition Value.h:62
DWARFExpressionList & LocationExpressionList()
Definition Variable.h:77
void CalculateSymbolContext(SymbolContext *sc)
Definition Variable.cpp:215
bool GetLocationIsConstantValueData() const
Definition Variable.h:102
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
@ eAddressTypeFile
Address is an address as found in an object or symbol file.
@ eAddressTypeLoad
Address is an address as in the current target inferior process.
@ eAddressTypeHost
Address is an address in the process that is running this code.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Variable > VariableSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
Every register is described in detail including its name, alternate name (optional),...