1 //===-- ValueObjectConstResult.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 
9 #include "lldb/Core/ValueObjectConstResult.h"
10 
11 #include "lldb/Core/ValueObjectDynamicValue.h"
12 #include "lldb/Symbol/CompilerType.h"
13 #include "lldb/Target/ExecutionContext.h"
14 #include "lldb/Target/ExecutionContextScope.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Utility/DataBuffer.h"
17 #include "lldb/Utility/DataBufferHeap.h"
18 #include "lldb/Utility/DataExtractor.h"
19 #include "lldb/Utility/Scalar.h"
20 
21 namespace lldb_private {
22 class Module;
23 }
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
29                                              ByteOrder byte_order,
30                                              uint32_t addr_byte_size,
31                                              lldb::addr_t address) {
32   return (new ValueObjectConstResult(exe_scope, byte_order, addr_byte_size,
33                                      address))
34       ->GetSP();
35 }
36 
37 ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
38                                                ByteOrder byte_order,
39                                                uint32_t addr_byte_size,
40                                                lldb::addr_t address)
41     : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
42       m_impl(this, address) {
43   SetIsConstant();
44   SetValueIsValid(true);
45   m_data.SetByteOrder(byte_order);
46   m_data.SetAddressByteSize(addr_byte_size);
47   SetAddressTypeOfChildren(eAddressTypeLoad);
48 }
49 
50 ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
51                                              const CompilerType &compiler_type,
52                                              ConstString name,
53                                              const DataExtractor &data,
54                                              lldb::addr_t address) {
55   return (new ValueObjectConstResult(exe_scope, compiler_type, name, data,
56                                      address))
57       ->GetSP();
58 }
59 
60 ValueObjectConstResult::ValueObjectConstResult(
61     ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
62     ConstString name, const DataExtractor &data, lldb::addr_t address)
63     : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
64       m_impl(this, address) {
65   m_data = data;
66 
67   if (!m_data.GetSharedDataBuffer()) {
68     DataBufferSP shared_data_buffer(
69         new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
70     m_data.SetData(shared_data_buffer);
71   }
72 
73   m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
74   m_value.SetValueType(Value::eValueTypeHostAddress);
75   m_value.SetCompilerType(compiler_type);
76   m_name = name;
77   SetIsConstant();
78   SetValueIsValid(true);
79   SetAddressTypeOfChildren(eAddressTypeLoad);
80 }
81 
82 ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
83                                              const CompilerType &compiler_type,
84                                              ConstString name,
85                                              const lldb::DataBufferSP &data_sp,
86                                              lldb::ByteOrder data_byte_order,
87                                              uint32_t data_addr_size,
88                                              lldb::addr_t address) {
89   return (new ValueObjectConstResult(exe_scope, compiler_type, name, data_sp,
90                                      data_byte_order, data_addr_size, address))
91       ->GetSP();
92 }
93 
94 ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
95                                              Value &value,
96                                              ConstString name,
97                                              Module *module) {
98   return (new ValueObjectConstResult(exe_scope, value, name, module))->GetSP();
99 }
100 
101 ValueObjectConstResult::ValueObjectConstResult(
102     ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
103     ConstString name, const lldb::DataBufferSP &data_sp,
104     lldb::ByteOrder data_byte_order, uint32_t data_addr_size,
105     lldb::addr_t address)
106     : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
107       m_impl(this, address) {
108   m_data.SetByteOrder(data_byte_order);
109   m_data.SetAddressByteSize(data_addr_size);
110   m_data.SetData(data_sp);
111   m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
112   m_value.SetValueType(Value::eValueTypeHostAddress);
113   m_value.SetCompilerType(compiler_type);
114   m_name = name;
115   SetIsConstant();
116   SetValueIsValid(true);
117   SetAddressTypeOfChildren(eAddressTypeLoad);
118 }
119 
120 ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
121                                              const CompilerType &compiler_type,
122                                              ConstString name,
123                                              lldb::addr_t address,
124                                              AddressType address_type,
125                                              uint32_t addr_byte_size) {
126   return (new ValueObjectConstResult(exe_scope, compiler_type, name, address,
127                                      address_type, addr_byte_size))
128       ->GetSP();
129 }
130 
131 ValueObjectConstResult::ValueObjectConstResult(
132     ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
133     ConstString name, lldb::addr_t address, AddressType address_type,
134     uint32_t addr_byte_size)
135     : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
136       m_impl(this, address) {
137   m_value.GetScalar() = address;
138   m_data.SetAddressByteSize(addr_byte_size);
139   m_value.GetScalar().GetData(m_data, addr_byte_size);
140   // m_value.SetValueType(Value::eValueTypeHostAddress);
141   switch (address_type) {
142   case eAddressTypeInvalid:
143     m_value.SetValueType(Value::eValueTypeScalar);
144     break;
145   case eAddressTypeFile:
146     m_value.SetValueType(Value::eValueTypeFileAddress);
147     break;
148   case eAddressTypeLoad:
149     m_value.SetValueType(Value::eValueTypeLoadAddress);
150     break;
151   case eAddressTypeHost:
152     m_value.SetValueType(Value::eValueTypeHostAddress);
153     break;
154   }
155   m_value.SetCompilerType(compiler_type);
156   m_name = name;
157   SetIsConstant();
158   SetValueIsValid(true);
159   SetAddressTypeOfChildren(eAddressTypeLoad);
160 }
161 
162 ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
163                                              const Status &error) {
164   return (new ValueObjectConstResult(exe_scope, error))->GetSP();
165 }
166 
167 ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
168                                                const Status &error)
169     : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) {
170   m_error = error;
171   SetIsConstant();
172 }
173 
174 ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
175                                                const Value &value,
176                                                ConstString name,
177                                                Module *module)
178     : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) {
179   m_value = value;
180   m_name = name;
181   ExecutionContext exe_ctx;
182   exe_scope->CalculateExecutionContext(exe_ctx);
183   m_error = m_value.GetValueAsData(&exe_ctx, m_data, module);
184 }
185 
186 ValueObjectConstResult::~ValueObjectConstResult() {}
187 
188 CompilerType ValueObjectConstResult::GetCompilerTypeImpl() {
189   return m_value.GetCompilerType();
190 }
191 
192 lldb::ValueType ValueObjectConstResult::GetValueType() const {
193   return eValueTypeConstResult;
194 }
195 
196 uint64_t ValueObjectConstResult::GetByteSize() {
197   ExecutionContext exe_ctx(GetExecutionContextRef());
198   if (m_byte_size == 0) {
199     if (auto size =
200         GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()))
201       SetByteSize(*size);
202   }
203   return m_byte_size;
204 }
205 
206 void ValueObjectConstResult::SetByteSize(size_t size) { m_byte_size = size; }
207 
208 size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) {
209   ExecutionContext exe_ctx(GetExecutionContextRef());
210   auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
211   return children_count <= max ? children_count : max;
212 }
213 
214 ConstString ValueObjectConstResult::GetTypeName() {
215   if (m_type_name.IsEmpty())
216     m_type_name = GetCompilerType().GetConstTypeName();
217   return m_type_name;
218 }
219 
220 ConstString ValueObjectConstResult::GetDisplayTypeName() {
221   return GetCompilerType().GetDisplayTypeName();
222 }
223 
224 bool ValueObjectConstResult::UpdateValue() {
225   // Const value is always valid
226   SetValueIsValid(true);
227   return true;
228 }
229 
230 bool ValueObjectConstResult::IsInScope() {
231   // A const result value is always in scope since it serializes all
232   // information needed to contain the constant value.
233   return true;
234 }
235 
236 lldb::ValueObjectSP ValueObjectConstResult::Dereference(Status &error) {
237   return m_impl.Dereference(error);
238 }
239 
240 lldb::ValueObjectSP ValueObjectConstResult::GetSyntheticChildAtOffset(
241     uint32_t offset, const CompilerType &type, bool can_create,
242     ConstString name_const_str) {
243   return m_impl.GetSyntheticChildAtOffset(offset, type, can_create,
244                                           name_const_str);
245 }
246 
247 lldb::ValueObjectSP ValueObjectConstResult::AddressOf(Status &error) {
248   return m_impl.AddressOf(error);
249 }
250 
251 lldb::addr_t ValueObjectConstResult::GetAddressOf(bool scalar_is_load_address,
252                                                   AddressType *address_type) {
253   return m_impl.GetAddressOf(scalar_is_load_address, address_type);
254 }
255 
256 ValueObject *ValueObjectConstResult::CreateChildAtIndex(
257     size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
258   return m_impl.CreateChildAtIndex(idx, synthetic_array_member,
259                                    synthetic_index);
260 }
261 
262 size_t ValueObjectConstResult::GetPointeeData(DataExtractor &data,
263                                               uint32_t item_idx,
264                                               uint32_t item_count) {
265   return m_impl.GetPointeeData(data, item_idx, item_count);
266 }
267 
268 lldb::ValueObjectSP
269 ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
270   // Always recalculate dynamic values for const results as the memory that
271   // they might point to might have changed at any time.
272   if (use_dynamic != eNoDynamicValues) {
273     if (!IsDynamic()) {
274       ExecutionContext exe_ctx(GetExecutionContextRef());
275       Process *process = exe_ctx.GetProcessPtr();
276       if (process && process->IsPossibleDynamicValue(*this))
277         m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
278     }
279     if (m_dynamic_value)
280       return m_dynamic_value->GetSP();
281   }
282   return ValueObjectSP();
283 }
284 
285 lldb::ValueObjectSP
286 ValueObjectConstResult::Cast(const CompilerType &compiler_type) {
287   return m_impl.Cast(compiler_type);
288 }
289 
290 lldb::LanguageType ValueObjectConstResult::GetPreferredDisplayLanguage() {
291   if (m_preferred_display_language != lldb::eLanguageTypeUnknown)
292     return m_preferred_display_language;
293   return GetCompilerTypeImpl().GetMinimumLanguage();
294 }
295