blob: 3de12e5a66f1ba78966203e8cdda46a2226447cb [file] [log] [blame]
Jim Ingham78a685a2011-04-16 00:01:13 +00001//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
2//
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
10
11#include "lldb/Core/ValueObjectDynamicValue.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
Enrico Granatad2284832012-10-17 22:23:56 +000017#include "lldb/Core/Log.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000018#include "lldb/Core/Module.h"
19#include "lldb/Core/ValueObjectList.h"
20#include "lldb/Core/Value.h"
21#include "lldb/Core/ValueObject.h"
22
Greg Claytona1e5dc82015-08-11 22:53:00 +000023#include "lldb/Symbol/CompilerType.h"
Jim Ingham78a685a2011-04-16 00:01:13 +000024#include "lldb/Symbol/ObjectFile.h"
25#include "lldb/Symbol/SymbolContext.h"
26#include "lldb/Symbol/Type.h"
27#include "lldb/Symbol/Variable.h"
28
29#include "lldb/Target/ExecutionContext.h"
30#include "lldb/Target/LanguageRuntime.h"
31#include "lldb/Target/Process.h"
32#include "lldb/Target/RegisterContext.h"
33#include "lldb/Target/Target.h"
34#include "lldb/Target/Thread.h"
35
Jim Ingham78a685a2011-04-16 00:01:13 +000036using namespace lldb_private;
37
Jim Ingham2837b762011-05-04 03:43:18 +000038ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
Jim Ingham78a685a2011-04-16 00:01:13 +000039 ValueObject(parent),
40 m_address (),
Enrico Granataf7b1a342013-01-23 01:17:27 +000041 m_dynamic_type_info(),
Jim Ingham2837b762011-05-04 03:43:18 +000042 m_use_dynamic (use_dynamic)
Jim Ingham78a685a2011-04-16 00:01:13 +000043{
Enrico Granata6f3533f2011-07-29 19:53:35 +000044 SetName (parent.GetName());
Jim Ingham78a685a2011-04-16 00:01:13 +000045}
46
47ValueObjectDynamicValue::~ValueObjectDynamicValue()
48{
49 m_owning_valobj_sp.reset();
50}
51
Greg Claytona1e5dc82015-08-11 22:53:00 +000052CompilerType
Greg Clayton99558cc42015-08-24 23:46:31 +000053ValueObjectDynamicValue::GetCompilerTypeImpl ()
Jim Ingham78a685a2011-04-16 00:01:13 +000054{
Enrico Granatadc4db5a2013-10-29 00:28:35 +000055 const bool success = UpdateValueIfNeeded(false);
56 if (success)
57 {
58 if (m_dynamic_type_info.HasType())
Greg Clayton99558cc42015-08-24 23:46:31 +000059 return m_value.GetCompilerType();
Enrico Granatadc4db5a2013-10-29 00:28:35 +000060 else
Greg Clayton99558cc42015-08-24 23:46:31 +000061 return m_parent->GetCompilerType();
Enrico Granatadc4db5a2013-10-29 00:28:35 +000062 }
Greg Clayton99558cc42015-08-24 23:46:31 +000063 return m_parent->GetCompilerType();
Jim Ingham78a685a2011-04-16 00:01:13 +000064}
65
66ConstString
67ValueObjectDynamicValue::GetTypeName()
68{
Enrico Granatac3e320a2011-08-02 17:27:39 +000069 const bool success = UpdateValueIfNeeded(false);
Enrico Granataf7b1a342013-01-23 01:17:27 +000070 if (success)
71 {
Enrico Granataf7b1a342013-01-23 01:17:27 +000072 if (m_dynamic_type_info.HasName())
73 return m_dynamic_type_info.GetName();
74 }
75 return m_parent->GetTypeName();
76}
77
Enrico Granatadc4db5a2013-10-29 00:28:35 +000078TypeImpl
79ValueObjectDynamicValue::GetTypeImpl ()
80{
81 const bool success = UpdateValueIfNeeded(false);
Enrico Granatadf7c7f92013-10-29 17:42:02 +000082 if (success && m_type_impl.IsValid())
Enrico Granatadc4db5a2013-10-29 00:28:35 +000083 {
84 return m_type_impl;
85 }
86 return m_parent->GetTypeImpl();
87}
88
Enrico Granataf7b1a342013-01-23 01:17:27 +000089ConstString
90ValueObjectDynamicValue::GetQualifiedTypeName()
91{
92 const bool success = UpdateValueIfNeeded(false);
93 if (success)
94 {
Enrico Granataf7b1a342013-01-23 01:17:27 +000095 if (m_dynamic_type_info.HasName())
96 return m_dynamic_type_info.GetName();
97 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +000098 return m_parent->GetQualifiedTypeName();
99}
100
101ConstString
102ValueObjectDynamicValue::GetDisplayTypeName()
103{
104 const bool success = UpdateValueIfNeeded(false);
105 if (success)
106 {
107 if (m_dynamic_type_info.HasType())
Greg Clayton99558cc42015-08-24 23:46:31 +0000108 return GetCompilerType().GetDisplayTypeName();
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000109 if (m_dynamic_type_info.HasName())
110 return m_dynamic_type_info.GetName();
111 }
112 return m_parent->GetDisplayTypeName();
Jim Ingham78a685a2011-04-16 00:01:13 +0000113}
114
Greg Claytonc7bece562013-01-25 18:06:21 +0000115size_t
Jim Ingham78a685a2011-04-16 00:01:13 +0000116ValueObjectDynamicValue::CalculateNumChildren()
117{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000118 const bool success = UpdateValueIfNeeded(false);
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000119 if (success && m_dynamic_type_info.HasType())
Greg Clayton99558cc42015-08-24 23:46:31 +0000120 return GetCompilerType().GetNumChildren (true);
Jim Ingham78a685a2011-04-16 00:01:13 +0000121 else
122 return m_parent->GetNumChildren();
123}
124
Greg Claytonfaac1112013-03-14 18:31:44 +0000125uint64_t
Jim Ingham78a685a2011-04-16 00:01:13 +0000126ValueObjectDynamicValue::GetByteSize()
127{
Enrico Granatac3e320a2011-08-02 17:27:39 +0000128 const bool success = UpdateValueIfNeeded(false);
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000129 if (success && m_dynamic_type_info.HasType())
Enrico Granata95438032015-10-14 22:44:30 +0000130 {
131 ExecutionContext exe_ctx (GetExecutionContextRef());
132 return m_value.GetValueByteSize(nullptr, &exe_ctx);
133 }
Jim Ingham78a685a2011-04-16 00:01:13 +0000134 else
135 return m_parent->GetByteSize();
136}
137
138lldb::ValueType
139ValueObjectDynamicValue::GetValueType() const
140{
141 return m_parent->GetValueType();
142}
143
144bool
145ValueObjectDynamicValue::UpdateValue ()
146{
147 SetValueIsValid (false);
148 m_error.Clear();
149
Enrico Granatac3e320a2011-08-02 17:27:39 +0000150 if (!m_parent->UpdateValueIfNeeded(false))
Jim Ingham78a685a2011-04-16 00:01:13 +0000151 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000152 // The dynamic value failed to get an error, pass the error along
153 if (m_error.Success() && m_parent->GetError().Fail())
154 m_error = m_parent->GetError();
Jim Ingham78a685a2011-04-16 00:01:13 +0000155 return false;
156 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000157
Jim Ingham2837b762011-05-04 03:43:18 +0000158 // Setting our type_sp to NULL will route everything back through our
159 // parent which is equivalent to not using dynamic values.
160 if (m_use_dynamic == lldb::eNoDynamicValues)
161 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000162 m_dynamic_type_info.Clear();
Jim Ingham2837b762011-05-04 03:43:18 +0000163 return true;
164 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000165
Greg Claytoncc4d0142012-02-17 07:49:44 +0000166 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Claytonc14ee322011-09-22 04:58:26 +0000167 Target *target = exe_ctx.GetTargetPtr();
168 if (target)
Jim Ingham78a685a2011-04-16 00:01:13 +0000169 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000170 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
171 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham78a685a2011-04-16 00:01:13 +0000172 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000173
Jim Ingham78a685a2011-04-16 00:01:13 +0000174 // First make sure our Type and/or Address haven't changed:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000175 Process *process = exe_ctx.GetProcessPtr();
Jim Ingham78a685a2011-04-16 00:01:13 +0000176 if (!process)
177 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000178
Jim Ingham61be0902011-05-02 18:13:59 +0000179 TypeAndOrName class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000180 Address dynamic_address;
181 bool found_dynamic_type = false;
Enrico Granata0b6003f2015-09-17 22:56:38 +0000182 Value::ValueType value_type;
Enrico Granatac74275b2015-09-22 19:45:52 +0000183
184 LanguageRuntime *runtime = nullptr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000185
Jim Ingham78a685a2011-04-16 00:01:13 +0000186 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
187 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
188 {
Enrico Granatac74275b2015-09-22 19:45:52 +0000189 runtime = process->GetLanguageRuntime (known_type);
Jim Ingham78a685a2011-04-16 00:01:13 +0000190 if (runtime)
Enrico Granata0b6003f2015-09-17 22:56:38 +0000191 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
Jim Ingham78a685a2011-04-16 00:01:13 +0000192 }
193 else
194 {
Enrico Granatac74275b2015-09-22 19:45:52 +0000195 runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
196 if (runtime)
197 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000198
Jim Ingham78a685a2011-04-16 00:01:13 +0000199 if (!found_dynamic_type)
200 {
Enrico Granatac74275b2015-09-22 19:45:52 +0000201 runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
202 if (runtime)
203 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
Jim Ingham78a685a2011-04-16 00:01:13 +0000204 }
205 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000206
Jim Ingham61be0902011-05-02 18:13:59 +0000207 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
208 // don't...
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000209
Jim Ingham61be0902011-05-02 18:13:59 +0000210 m_update_point.SetUpdated();
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000211
Enrico Granatac74275b2015-09-22 19:45:52 +0000212 if (runtime && found_dynamic_type)
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000213 {
Enrico Granatadf7c7f92013-10-29 17:42:02 +0000214 if (class_type_or_name.HasType())
215 {
Enrico Granatac74275b2015-09-22 19:45:52 +0000216 m_type_impl = TypeImpl(m_parent->GetCompilerType(),
Enrico Granata7eed4872015-09-22 19:58:02 +0000217 runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType());
Enrico Granatadf7c7f92013-10-29 17:42:02 +0000218 }
219 else
220 {
221 m_type_impl.Clear();
222 }
223 }
224 else
225 {
226 m_type_impl.Clear();
Enrico Granatadc4db5a2013-10-29 00:28:35 +0000227 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000228
Jim Ingham78a685a2011-04-16 00:01:13 +0000229 // If we don't have a dynamic type, then make ourselves just a echo of our parent.
230 // Or we could return false, and make ourselves an echo of our parent?
231 if (!found_dynamic_type)
232 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000233 if (m_dynamic_type_info)
Enrico Granata75badc42012-11-27 23:50:00 +0000234 SetValueDidChange(true);
Enrico Granatabd83b872012-11-27 23:28:32 +0000235 ClearDynamicTypeInformation();
Enrico Granataf7b1a342013-01-23 01:17:27 +0000236 m_dynamic_type_info.Clear();
Jim Ingham78a685a2011-04-16 00:01:13 +0000237 m_value = m_parent->GetValue();
Greg Clayton57ee3062013-07-11 22:46:58 +0000238 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000239 return m_error.Success();
240 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000241
Jim Ingham78a685a2011-04-16 00:01:13 +0000242 Value old_value(m_value);
243
Greg Clayton5160ce52013-03-27 23:08:40 +0000244 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000245
Enrico Granatae3e91512012-10-22 18:18:36 +0000246 bool has_changed_type = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000247
Enrico Granataf7b1a342013-01-23 01:17:27 +0000248 if (!m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000249 {
Enrico Granataf7b1a342013-01-23 01:17:27 +0000250 m_dynamic_type_info = class_type_or_name;
Enrico Granatae3e91512012-10-22 18:18:36 +0000251 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000252 }
Enrico Granataf7b1a342013-01-23 01:17:27 +0000253 else if (class_type_or_name != m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000254 {
255 // We are another type, we need to tear down our children...
Enrico Granataf7b1a342013-01-23 01:17:27 +0000256 m_dynamic_type_info = class_type_or_name;
Jim Ingham78a685a2011-04-16 00:01:13 +0000257 SetValueDidChange (true);
Enrico Granatae3e91512012-10-22 18:18:36 +0000258 has_changed_type = true;
Jim Ingham78a685a2011-04-16 00:01:13 +0000259 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000260
Enrico Granatae3e91512012-10-22 18:18:36 +0000261 if (has_changed_type)
262 ClearDynamicTypeInformation ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000263
Jim Ingham78a685a2011-04-16 00:01:13 +0000264 if (!m_address.IsValid() || m_address != dynamic_address)
265 {
266 if (m_address.IsValid())
267 SetValueDidChange (true);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000268
Jim Ingham78a685a2011-04-16 00:01:13 +0000269 // We've moved, so we should be fine...
270 m_address = dynamic_address;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000271 lldb::TargetSP target_sp (GetTargetSP());
272 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000273 m_value.GetScalar() = load_address;
274 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000275
Enrico Granatac74275b2015-09-22 19:45:52 +0000276 if (runtime)
Enrico Granata7eed4872015-09-22 19:58:02 +0000277 m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000278
Greg Clayton57ee3062013-07-11 22:46:58 +0000279 //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
Greg Clayton99558cc42015-08-24 23:46:31 +0000280 m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000281
Enrico Granata0b6003f2015-09-17 22:56:38 +0000282 m_value.SetValueType(value_type);
Jim Ingham78a685a2011-04-16 00:01:13 +0000283
Enrico Granatae3e91512012-10-22 18:18:36 +0000284 if (has_changed_type && log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000285 log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
286 static_cast<void*>(this), GetTypeName().GetCString());
287
Enrico Granataf7b1a342013-01-23 01:17:27 +0000288 if (m_address.IsValid() && m_dynamic_type_info)
Jim Ingham78a685a2011-04-16 00:01:13 +0000289 {
290 // The variable value is in the Scalar value inside the m_value.
291 // We can point our m_data right to it.
Greg Clayton57ee3062013-07-11 22:46:58 +0000292 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
Jim Ingham78a685a2011-04-16 00:01:13 +0000293 if (m_error.Success())
294 {
Enrico Granatad07cfd32014-10-08 18:27:36 +0000295 if (!CanProvideValue())
Jim Ingham78a685a2011-04-16 00:01:13 +0000296 {
297 // this value object represents an aggregate type whose
298 // children have values, but this object does not. So we
299 // say we are changed if our location has changed.
300 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
301 }
302
303 SetValueIsValid (true);
304 return true;
305 }
306 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000307
Jim Ingham78a685a2011-04-16 00:01:13 +0000308 // We get here if we've failed above...
309 SetValueIsValid (false);
310 return false;
311}
312
313
314
315bool
316ValueObjectDynamicValue::IsInScope ()
317{
318 return m_parent->IsInScope();
319}
320
Enrico Granata07a4ac22012-05-08 21:25:06 +0000321bool
322ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
323{
324 if (!UpdateValueIfNeeded(false))
325 {
326 error.SetErrorString("unable to read value");
327 return false;
328 }
329
330 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
331 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
332
333 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
334 {
335 error.SetErrorString("unable to read value");
336 return false;
337 }
338
339 // if we are at an offset from our parent, in order to set ourselves correctly we would need
340 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
341 // with that - if anything more than a value overwrite is required, you should be using the
342 // expression parser instead of the value editing facility
343 if (my_value != parent_value)
344 {
345 // but NULL'ing out a value should always be allowed
346 if (strcmp(value_str,"0"))
347 {
348 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
349 return false;
350 }
351 }
352
353 bool ret_val = m_parent->SetValueFromCString(value_str,error);
354 SetNeedsUpdate();
355 return ret_val;
356}
Sean Callanan389823e2013-04-13 01:21:23 +0000357
358bool
359ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
360{
361 if (!UpdateValueIfNeeded(false))
362 {
363 error.SetErrorString("unable to read value");
364 return false;
365 }
366
367 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
368 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
369
370 if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
371 {
372 error.SetErrorString("unable to read value");
373 return false;
374 }
375
376 // if we are at an offset from our parent, in order to set ourselves correctly we would need
377 // to change the new value so that it refers to the correct dynamic type. we choose not to deal
378 // with that - if anything more than a value overwrite is required, you should be using the
379 // expression parser instead of the value editing facility
380 if (my_value != parent_value)
381 {
382 // but NULL'ing out a value should always be allowed
383 lldb::offset_t offset = 0;
384
385 if (data.GetPointer(&offset) != 0)
386 {
387 error.SetErrorString("unable to modify dynamic value, use 'expression' command");
388 return false;
389 }
390 }
391
392 bool ret_val = m_parent->SetData(data, error);
393 SetNeedsUpdate();
394 return ret_val;
395}
Siva Chandra9851b1f2015-08-18 17:56:06 +0000396
Enrico Granata73e8c4d2015-10-07 02:36:35 +0000397void
398ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang)
399{
400 this->ValueObject::SetPreferredDisplayLanguage(lang);
401 if (m_parent)
402 m_parent->SetPreferredDisplayLanguage(lang);
403}
404
405lldb::LanguageType
406ValueObjectDynamicValue::GetPreferredDisplayLanguage ()
407{
408 if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
409 {
410 if (m_parent)
411 return m_parent->GetPreferredDisplayLanguage();
412 return lldb::eLanguageTypeUnknown;
413 }
414 else
415 return m_preferred_display_language;
416}
417
Siva Chandra9851b1f2015-08-18 17:56:06 +0000418bool
419ValueObjectDynamicValue::GetDeclaration (Declaration &decl)
420{
421 if (m_parent)
422 return m_parent->GetDeclaration(decl);
423
424 return ValueObject::GetDeclaration(decl);
425}