1 //===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/ValueObjectMemory.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/Core/ValueObjectList.h"
21 #include "lldb/Symbol/ObjectFile.h"
22 #include "lldb/Symbol/SymbolContext.h"
23 #include "lldb/Symbol/Type.h"
24 #include "lldb/Symbol/Variable.h"
26 #include "lldb/Target/ExecutionContext.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Target/Target.h"
30 #include "lldb/Target/Thread.h"
33 using namespace lldb_private;
35 ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope,
37 const Address &address,
38 lldb::TypeSP &type_sp) {
39 return (new ValueObjectMemory(exe_scope, name, address, type_sp))->GetSP();
42 ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope,
44 const Address &address,
45 const CompilerType &ast_type) {
46 return (new ValueObjectMemory(exe_scope, name, address, ast_type))->GetSP();
49 ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
51 const Address &address,
52 lldb::TypeSP &type_sp)
53 : ValueObject(exe_scope), m_address(address), m_type_sp(type_sp),
55 // Do not attempt to construct one of these objects with no variable!
56 assert(m_type_sp.get() != NULL);
57 SetName(ConstString(name));
58 m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
59 TargetSP target_sp(GetTargetSP());
60 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
61 if (load_address != LLDB_INVALID_ADDRESS) {
62 m_value.SetValueType(Value::eValueTypeLoadAddress);
63 m_value.GetScalar() = load_address;
65 lldb::addr_t file_address = m_address.GetFileAddress();
66 if (file_address != LLDB_INVALID_ADDRESS) {
67 m_value.SetValueType(Value::eValueTypeFileAddress);
68 m_value.GetScalar() = file_address;
70 m_value.GetScalar() = m_address.GetOffset();
71 m_value.SetValueType(Value::eValueTypeScalar);
76 ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
78 const Address &address,
79 const CompilerType &ast_type)
80 : ValueObject(exe_scope), m_address(address), m_type_sp(),
81 m_compiler_type(ast_type) {
82 // Do not attempt to construct one of these objects with no variable!
83 assert(m_compiler_type.GetTypeSystem());
84 assert(m_compiler_type.GetOpaqueQualType());
86 TargetSP target_sp(GetTargetSP());
88 SetName(ConstString(name));
89 // m_value.SetContext(Value::eContextTypeClangType,
90 // m_compiler_type.GetOpaqueQualType());
91 m_value.SetCompilerType(m_compiler_type);
92 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
93 if (load_address != LLDB_INVALID_ADDRESS) {
94 m_value.SetValueType(Value::eValueTypeLoadAddress);
95 m_value.GetScalar() = load_address;
97 lldb::addr_t file_address = m_address.GetFileAddress();
98 if (file_address != LLDB_INVALID_ADDRESS) {
99 m_value.SetValueType(Value::eValueTypeFileAddress);
100 m_value.GetScalar() = file_address;
102 m_value.GetScalar() = m_address.GetOffset();
103 m_value.SetValueType(Value::eValueTypeScalar);
108 ValueObjectMemory::~ValueObjectMemory() {}
110 CompilerType ValueObjectMemory::GetCompilerTypeImpl() {
112 return m_type_sp->GetForwardCompilerType();
113 return m_compiler_type;
116 ConstString ValueObjectMemory::GetTypeName() {
118 return m_type_sp->GetName();
119 return m_compiler_type.GetConstTypeName();
122 ConstString ValueObjectMemory::GetDisplayTypeName() {
124 return m_type_sp->GetForwardCompilerType().GetDisplayTypeName();
125 return m_compiler_type.GetDisplayTypeName();
128 size_t ValueObjectMemory::CalculateNumChildren(uint32_t max) {
130 auto child_count = m_type_sp->GetNumChildren(true);
131 return child_count <= max ? child_count : max;
134 const bool omit_empty_base_classes = true;
135 auto child_count = m_compiler_type.GetNumChildren(omit_empty_base_classes);
136 return child_count <= max ? child_count : max;
139 uint64_t ValueObjectMemory::GetByteSize() {
141 return m_type_sp->GetByteSize();
142 return m_compiler_type.GetByteSize(nullptr);
145 lldb::ValueType ValueObjectMemory::GetValueType() const {
146 // RETHINK: Should this be inherited from somewhere?
147 return lldb::eValueTypeVariableGlobal;
150 bool ValueObjectMemory::UpdateValue() {
151 SetValueIsValid(false);
154 ExecutionContext exe_ctx(GetExecutionContextRef());
156 Target *target = exe_ctx.GetTargetPtr();
158 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
159 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
162 Value old_value(m_value);
163 if (m_address.IsValid()) {
164 Value::ValueType value_type = m_value.GetValueType();
166 switch (value_type) {
168 assert(!"Unhandled expression result value kind...");
171 case Value::eValueTypeScalar:
172 // The variable value is in the Scalar value inside the m_value.
173 // We can point our m_data right to it.
174 m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
177 case Value::eValueTypeFileAddress:
178 case Value::eValueTypeLoadAddress:
179 case Value::eValueTypeHostAddress:
180 // The DWARF expression result was an address in the inferior
181 // process. If this variable is an aggregate type, we just need
182 // the address as the main value as all child variable objects
183 // will rely upon this location and add an offset and then read
184 // their own values as needed. If this variable is a simple
185 // type, we read all data for it into m_data.
186 // Make sure this type has a value before we try and read it
188 // If we have a file address, convert it to a load address if we can.
189 if (value_type == Value::eValueTypeFileAddress &&
190 exe_ctx.GetProcessPtr()) {
191 lldb::addr_t load_addr = m_address.GetLoadAddress(target);
192 if (load_addr != LLDB_INVALID_ADDRESS) {
193 m_value.SetValueType(Value::eValueTypeLoadAddress);
194 m_value.GetScalar() = load_addr;
198 if (!CanProvideValue()) {
199 // this value object represents an aggregate type whose
200 // children have values, but this object does not. So we
201 // say we are changed if our location has changed.
202 SetValueDidChange(value_type != old_value.GetValueType() ||
203 m_value.GetScalar() != old_value.GetScalar());
205 // Copy the Value and set the context to use our Variable
206 // so it can extract read its value into m_data appropriately
207 Value value(m_value);
209 value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
211 // value.SetContext(Value::eContextTypeClangType,
212 // m_compiler_type.GetOpaqueQualType());
213 value.SetCompilerType(m_compiler_type);
216 m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
221 SetValueIsValid(m_error.Success());
223 return m_error.Success();
226 bool ValueObjectMemory::IsInScope() {
227 // FIXME: Maybe try to read the memory address, and if that works, then
232 lldb::ModuleSP ValueObjectMemory::GetModule() { return m_address.GetModule(); }