blob: bb39caa767eb93f5566fdbf78fdca52bb9b0a910 [file] [log] [blame]
Zachary Turner2f3df612017-04-06 21:28:29 +00001//===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===//
Jim Ingham78a685a2011-04-16 00:01:13 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jim Ingham78a685a2011-04-16 00:01:13 +000010#include "lldb/Core/ValueObjectDynamicValue.h"
11
Zachary Turner2f3df612017-04-06 21:28:29 +000012#include "lldb/Core/ArchSpec.h" // for ArchSpec
13#include "lldb/Core/Scalar.h" // for Scalar, operator!=
Jim Ingham78a685a2011-04-16 00:01:13 +000014#include "lldb/Core/Value.h"
15#include "lldb/Core/ValueObject.h"
Greg Claytona1e5dc82015-08-11 22:53:00 +000016#include "lldb/Symbol/CompilerType.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000017#include "lldb/Symbol/Type.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000018#include "lldb/Target/ExecutionContext.h"
19#include "lldb/Target/LanguageRuntime.h"
20#include "lldb/Target/Process.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000021#include "lldb/Target/Target.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000022#include "lldb/Utility/DataExtractor.h" // for DataExtractor
Zachary Turner2f3df612017-04-06 21:28:29 +000023#include "lldb/Utility/Log.h"
24#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet
Zachary Turner97206d52017-05-12 04:51:55 +000025#include "lldb/Utility/Status.h" // for Status
Zachary Turner2f3df612017-04-06 21:28:29 +000026#include "lldb/lldb-types.h" // for addr_t, offset_t
27
28#include <string.h> // for strcmp, size_t
29namespace lldb_private {
30class Declaration;
31}
Jim Ingham78a685a2011-04-16 00:01:13 +000032
Jim Ingham78a685a2011-04-16 00:01:13 +000033using namespace lldb_private;
34
Kate Stoneb9c1b512016-09-06 20:57:50 +000035ValueObjectDynamicValue::ValueObjectDynamicValue(
36 ValueObject &parent, lldb::DynamicValueType use_dynamic)
37 : ValueObject(parent), m_address(), m_dynamic_type_info(),
38 m_use_dynamic(use_dynamic) {
39 SetName(parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +000040}
41
Kate Stoneb9c1b512016-09-06 20:57:50 +000042ValueObjectDynamicValue::~ValueObjectDynamicValue() {
43 m_owning_valobj_sp.reset();
Jim Ingham78a685a2011-04-16 00:01:13 +000044}
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
47 const bool success = UpdateValueIfNeeded(false);
48 if (success) {
49 if (m_dynamic_type_info.HasType())
50 return m_value.GetCompilerType();
Jim Ingham78a685a2011-04-16 00:01:13 +000051 else
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 return m_parent->GetCompilerType();
53 }
54 return m_parent->GetCompilerType();
Jim Ingham78a685a2011-04-16 00:01:13 +000055}
56
Kate Stoneb9c1b512016-09-06 20:57:50 +000057ConstString ValueObjectDynamicValue::GetTypeName() {
58 const bool success = UpdateValueIfNeeded(false);
59 if (success) {
60 if (m_dynamic_type_info.HasName())
61 return m_dynamic_type_info.GetName();
62 }
63 return m_parent->GetTypeName();
Jim Ingham78a685a2011-04-16 00:01:13 +000064}
65
Kate Stoneb9c1b512016-09-06 20:57:50 +000066TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
67 const bool success = UpdateValueIfNeeded(false);
68 if (success && m_type_impl.IsValid()) {
69 return m_type_impl;
70 }
71 return m_parent->GetTypeImpl();
Jim Ingham78a685a2011-04-16 00:01:13 +000072}
73
Kate Stoneb9c1b512016-09-06 20:57:50 +000074ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
75 const bool success = UpdateValueIfNeeded(false);
76 if (success) {
77 if (m_dynamic_type_info.HasName())
78 return m_dynamic_type_info.GetName();
79 }
80 return m_parent->GetQualifiedTypeName();
81}
Jim Ingham78a685a2011-04-16 00:01:13 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
84 const bool success = UpdateValueIfNeeded(false);
85 if (success) {
86 if (m_dynamic_type_info.HasType())
87 return GetCompilerType().GetDisplayTypeName();
88 if (m_dynamic_type_info.HasName())
89 return m_dynamic_type_info.GetName();
90 }
91 return m_parent->GetDisplayTypeName();
92}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000093
Kate Stoneb9c1b512016-09-06 20:57:50 +000094size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
95 const bool success = UpdateValueIfNeeded(false);
96 if (success && m_dynamic_type_info.HasType()) {
97 auto children_count = GetCompilerType().GetNumChildren(true);
98 return children_count <= max ? children_count : max;
99 } else
100 return m_parent->GetNumChildren(max);
101}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103uint64_t ValueObjectDynamicValue::GetByteSize() {
104 const bool success = UpdateValueIfNeeded(false);
105 if (success && m_dynamic_type_info.HasType()) {
106 ExecutionContext exe_ctx(GetExecutionContextRef());
107 return m_value.GetValueByteSize(nullptr, &exe_ctx);
108 } else
109 return m_parent->GetByteSize();
110}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
113 return m_parent->GetValueType();
114}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116bool ValueObjectDynamicValue::UpdateValue() {
117 SetValueIsValid(false);
118 m_error.Clear();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 if (!m_parent->UpdateValueIfNeeded(false)) {
121 // The dynamic value failed to get an error, pass the error along
122 if (m_error.Success() && m_parent->GetError().Fail())
123 m_error = m_parent->GetError();
124 return false;
125 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 // Setting our type_sp to NULL will route everything back through our
128 // parent which is equivalent to not using dynamic values.
129 if (m_use_dynamic == lldb::eNoDynamicValues) {
130 m_dynamic_type_info.Clear();
131 return true;
132 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 ExecutionContext exe_ctx(GetExecutionContextRef());
135 Target *target = exe_ctx.GetTargetPtr();
136 if (target) {
137 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
138 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
139 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000140
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 // First make sure our Type and/or Address haven't changed:
142 Process *process = exe_ctx.GetProcessPtr();
143 if (!process)
144 return false;
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 TypeAndOrName class_type_or_name;
147 Address dynamic_address;
148 bool found_dynamic_type = false;
149 Value::ValueType value_type;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000150
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 LanguageRuntime *runtime = nullptr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000152
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
154 if (known_type != lldb::eLanguageTypeUnknown &&
155 known_type != lldb::eLanguageTypeC) {
156 runtime = process->GetLanguageRuntime(known_type);
Enrico Granatac74275b2015-09-22 19:45:52 +0000157 if (runtime)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 found_dynamic_type = runtime->GetDynamicTypeAndAddress(
159 *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
160 value_type);
161 } else {
162 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
163 if (runtime)
164 found_dynamic_type = runtime->GetDynamicTypeAndAddress(
165 *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
166 value_type);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 if (!found_dynamic_type) {
169 runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
170 if (runtime)
171 found_dynamic_type = runtime->GetDynamicTypeAndAddress(
172 *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
173 value_type);
Jim Ingham78a685a2011-04-16 00:01:13 +0000174 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000176
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 // Getting the dynamic value may have run the program a bit, and so marked us
178 // as needing updating, but we really
179 // don't...
180
181 m_update_point.SetUpdated();
182
183 if (runtime && found_dynamic_type) {
184 if (class_type_or_name.HasType()) {
185 m_type_impl =
186 TypeImpl(m_parent->GetCompilerType(),
187 runtime->FixUpDynamicType(class_type_or_name, *m_parent)
188 .GetCompilerType());
189 } else {
190 m_type_impl.Clear();
191 }
192 } else {
193 m_type_impl.Clear();
194 }
195
196 // If we don't have a dynamic type, then make ourselves just a echo of our
197 // parent.
198 // Or we could return false, and make ourselves an echo of our parent?
199 if (!found_dynamic_type) {
200 if (m_dynamic_type_info)
201 SetValueDidChange(true);
202 ClearDynamicTypeInformation();
203 m_dynamic_type_info.Clear();
204 m_value = m_parent->GetValue();
205 m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
206 return m_error.Success();
207 }
208
209 Value old_value(m_value);
210
211 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
212
213 bool has_changed_type = false;
214
215 if (!m_dynamic_type_info) {
216 m_dynamic_type_info = class_type_or_name;
217 has_changed_type = true;
218 } else if (class_type_or_name != m_dynamic_type_info) {
219 // We are another type, we need to tear down our children...
220 m_dynamic_type_info = class_type_or_name;
221 SetValueDidChange(true);
222 has_changed_type = true;
223 }
224
225 if (has_changed_type)
226 ClearDynamicTypeInformation();
227
228 if (!m_address.IsValid() || m_address != dynamic_address) {
229 if (m_address.IsValid())
230 SetValueDidChange(true);
231
232 // We've moved, so we should be fine...
233 m_address = dynamic_address;
234 lldb::TargetSP target_sp(GetTargetSP());
235 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
236 m_value.GetScalar() = load_address;
237 }
238
239 if (runtime)
240 m_dynamic_type_info =
241 runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
242
243 // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
244 m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
245
246 m_value.SetValueType(value_type);
247
248 if (has_changed_type && log)
249 log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
250 static_cast<void *>(this), GetTypeName().GetCString());
251
252 if (m_address.IsValid() && m_dynamic_type_info) {
253 // The variable value is in the Scalar value inside the m_value.
254 // We can point our m_data right to it.
255 m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
256 if (m_error.Success()) {
257 if (!CanProvideValue()) {
258 // this value object represents an aggregate type whose
259 // children have values, but this object does not. So we
260 // say we are changed if our location has changed.
261 SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
262 m_value.GetScalar() != old_value.GetScalar());
263 }
264
265 SetValueIsValid(true);
266 return true;
267 }
268 }
269
270 // We get here if we've failed above...
271 SetValueIsValid(false);
272 return false;
273}
274
275bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
276
277bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
Zachary Turner97206d52017-05-12 04:51:55 +0000278 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 if (!UpdateValueIfNeeded(false)) {
280 error.SetErrorString("unable to read value");
Jim Ingham78a685a2011-04-16 00:01:13 +0000281 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
285 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
Jim Ingham78a685a2011-04-16 00:01:13 +0000286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
288 error.SetErrorString("unable to read value");
Enrico Granata3b207c62016-07-08 18:39:36 +0000289 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290 }
291
292 // if we are at an offset from our parent, in order to set ourselves correctly
293 // we would need
294 // to change the new value so that it refers to the correct dynamic type. we
295 // choose not to deal
296 // with that - if anything more than a value overwrite is required, you should
297 // be using the
298 // expression parser instead of the value editing facility
299 if (my_value != parent_value) {
300 // but NULL'ing out a value should always be allowed
301 if (strcmp(value_str, "0")) {
302 error.SetErrorString(
303 "unable to modify dynamic value, use 'expression' command");
304 return false;
305 }
306 }
307
308 bool ret_val = m_parent->SetValueFromCString(value_str, error);
309 SetNeedsUpdate();
310 return ret_val;
Enrico Granata3b207c62016-07-08 18:39:36 +0000311}
312
Zachary Turner97206d52017-05-12 04:51:55 +0000313bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000314 if (!UpdateValueIfNeeded(false)) {
315 error.SetErrorString("unable to read value");
316 return false;
317 }
318
319 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
320 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
321
322 if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
323 error.SetErrorString("unable to read value");
324 return false;
325 }
326
327 // if we are at an offset from our parent, in order to set ourselves correctly
328 // we would need
329 // to change the new value so that it refers to the correct dynamic type. we
330 // choose not to deal
331 // with that - if anything more than a value overwrite is required, you should
332 // be using the
333 // expression parser instead of the value editing facility
334 if (my_value != parent_value) {
335 // but NULL'ing out a value should always be allowed
336 lldb::offset_t offset = 0;
337
338 if (data.GetPointer(&offset) != 0) {
339 error.SetErrorString(
340 "unable to modify dynamic value, use 'expression' command");
341 return false;
342 }
343 }
344
345 bool ret_val = m_parent->SetData(data, error);
346 SetNeedsUpdate();
347 return ret_val;
Enrico Granata3b207c62016-07-08 18:39:36 +0000348}
349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
351 lldb::LanguageType lang) {
352 this->ValueObject::SetPreferredDisplayLanguage(lang);
353 if (m_parent)
354 m_parent->SetPreferredDisplayLanguage(lang);
Siva Chandra9851b1f2015-08-18 17:56:06 +0000355}
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000356
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
358 if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000359 if (m_parent)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 return m_parent->GetPreferredDisplayLanguage();
361 return lldb::eLanguageTypeUnknown;
362 } else
363 return m_preferred_display_language;
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000364}
365
Kate Stoneb9c1b512016-09-06 20:57:50 +0000366bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
367 if (m_parent)
368 return m_parent->IsSyntheticChildrenGenerated();
369 return false;
370}
371
372void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
373 if (m_parent)
374 m_parent->SetSyntheticChildrenGenerated(b);
375 this->ValueObject::SetSyntheticChildrenGenerated(b);
376}
377
378bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
379 if (m_parent)
380 return m_parent->GetDeclaration(decl);
381
382 return ValueObject::GetDeclaration(decl);
383}
384
385uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
386 if (m_parent)
387 return m_parent->GetLanguageFlags();
388 return this->ValueObject::GetLanguageFlags();
389}
390
391void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
392 if (m_parent)
393 m_parent->SetLanguageFlags(flags);
394 else
395 this->ValueObject::SetLanguageFlags(flags);
Enrico Granatadc62ffd2015-11-09 19:27:34 +0000396}