]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp
MFV: r313101
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectDynamicValue.cpp
1 //===-- 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
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ValueObjectList.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObject.h"
22
23 #include "lldb/Symbol/CompilerType.h"
24 #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
36 using namespace lldb_private;
37
38 ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
39     ValueObject(parent),
40     m_address (),
41     m_dynamic_type_info(),
42     m_use_dynamic (use_dynamic)
43 {
44     SetName (parent.GetName());
45 }
46
47 ValueObjectDynamicValue::~ValueObjectDynamicValue()
48 {
49     m_owning_valobj_sp.reset();
50 }
51
52 CompilerType
53 ValueObjectDynamicValue::GetCompilerTypeImpl ()
54 {
55     const bool success = UpdateValueIfNeeded(false);
56     if (success)
57     {
58         if (m_dynamic_type_info.HasType())
59             return m_value.GetCompilerType();
60         else
61             return m_parent->GetCompilerType();
62     }
63     return m_parent->GetCompilerType();
64 }
65
66 ConstString
67 ValueObjectDynamicValue::GetTypeName()
68 {
69     const bool success = UpdateValueIfNeeded(false);
70     if (success)
71     {
72         if (m_dynamic_type_info.HasName())
73             return m_dynamic_type_info.GetName();
74     }
75     return m_parent->GetTypeName();
76 }
77
78 TypeImpl
79 ValueObjectDynamicValue::GetTypeImpl ()
80 {
81     const bool success = UpdateValueIfNeeded(false);
82     if (success && m_type_impl.IsValid())
83     {
84         return m_type_impl;
85     }
86     return m_parent->GetTypeImpl();
87 }
88
89 ConstString
90 ValueObjectDynamicValue::GetQualifiedTypeName()
91 {
92     const bool success = UpdateValueIfNeeded(false);
93     if (success)
94     {
95         if (m_dynamic_type_info.HasName())
96             return m_dynamic_type_info.GetName();
97     }
98     return m_parent->GetQualifiedTypeName();
99 }
100
101 ConstString
102 ValueObjectDynamicValue::GetDisplayTypeName()
103 {
104     const bool success = UpdateValueIfNeeded(false);
105     if (success)
106     {
107         if (m_dynamic_type_info.HasType())
108             return GetCompilerType().GetDisplayTypeName();
109         if (m_dynamic_type_info.HasName())
110             return m_dynamic_type_info.GetName();
111     }
112     return m_parent->GetDisplayTypeName();
113 }
114
115 size_t
116 ValueObjectDynamicValue::CalculateNumChildren(uint32_t max)
117 {
118     const bool success = UpdateValueIfNeeded(false);
119     if (success && m_dynamic_type_info.HasType())
120     {
121         auto children_count = GetCompilerType().GetNumChildren (true);
122         return children_count <= max ? children_count : max;
123     }
124     else
125         return m_parent->GetNumChildren(max);
126 }
127
128 uint64_t
129 ValueObjectDynamicValue::GetByteSize()
130 {
131     const bool success = UpdateValueIfNeeded(false);
132     if (success && m_dynamic_type_info.HasType())
133     {
134         ExecutionContext exe_ctx (GetExecutionContextRef());
135         return m_value.GetValueByteSize(nullptr, &exe_ctx);
136     }
137     else
138         return m_parent->GetByteSize();
139 }
140
141 lldb::ValueType
142 ValueObjectDynamicValue::GetValueType() const
143 {
144     return m_parent->GetValueType();
145 }
146
147 bool
148 ValueObjectDynamicValue::UpdateValue ()
149 {
150     SetValueIsValid (false);
151     m_error.Clear();
152
153     if (!m_parent->UpdateValueIfNeeded(false))
154     {
155         // The dynamic value failed to get an error, pass the error along
156         if (m_error.Success() && m_parent->GetError().Fail())
157             m_error = m_parent->GetError();
158         return false;
159     }
160
161     // Setting our type_sp to NULL will route everything back through our
162     // parent which is equivalent to not using dynamic values.
163     if (m_use_dynamic == lldb::eNoDynamicValues)
164     {
165         m_dynamic_type_info.Clear();
166         return true;
167     }
168
169     ExecutionContext exe_ctx (GetExecutionContextRef());
170     Target *target = exe_ctx.GetTargetPtr();
171     if (target)
172     {
173         m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
174         m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
175     }
176
177     // First make sure our Type and/or Address haven't changed:
178     Process *process = exe_ctx.GetProcessPtr();
179     if (!process)
180         return false;
181
182     TypeAndOrName class_type_or_name;
183     Address dynamic_address;
184     bool found_dynamic_type = false;
185     Value::ValueType value_type;
186     
187     LanguageRuntime *runtime = nullptr;
188
189     lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
190     if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
191     {
192         runtime = process->GetLanguageRuntime (known_type);
193         if (runtime)
194             found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
195     }
196     else
197     {
198         runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
199         if (runtime)
200             found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
201
202         if (!found_dynamic_type)
203         {
204             runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
205             if (runtime)
206                 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
207         }
208     }
209
210     // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
211     // don't...
212
213     m_update_point.SetUpdated();
214
215     if (runtime && found_dynamic_type)
216     {
217         if (class_type_or_name.HasType())
218         {
219             m_type_impl = TypeImpl(m_parent->GetCompilerType(),
220                                    runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType());
221         }
222         else
223         {
224             m_type_impl.Clear();
225         }
226     }
227     else
228     {
229         m_type_impl.Clear();
230     }
231
232     // If we don't have a dynamic type, then make ourselves just a echo of our parent.
233     // Or we could return false, and make ourselves an echo of our parent?
234     if (!found_dynamic_type)
235     {
236         if (m_dynamic_type_info)
237             SetValueDidChange(true);
238         ClearDynamicTypeInformation();
239         m_dynamic_type_info.Clear();
240         m_value = m_parent->GetValue();
241         m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
242         return m_error.Success();
243     }
244
245     Value old_value(m_value);
246
247     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
248
249     bool has_changed_type = false;
250
251     if (!m_dynamic_type_info)
252     {
253         m_dynamic_type_info = class_type_or_name;
254         has_changed_type = true;
255     }
256     else if (class_type_or_name != m_dynamic_type_info)
257     {
258         // We are another type, we need to tear down our children...
259         m_dynamic_type_info = class_type_or_name;
260         SetValueDidChange (true);
261         has_changed_type = true;
262     }
263
264     if (has_changed_type)
265         ClearDynamicTypeInformation ();
266
267     if (!m_address.IsValid() || m_address != dynamic_address)
268     {
269         if (m_address.IsValid())
270             SetValueDidChange (true);
271
272         // We've moved, so we should be fine...
273         m_address = dynamic_address;
274         lldb::TargetSP target_sp (GetTargetSP());
275         lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
276         m_value.GetScalar() = load_address;
277     }
278
279     if (runtime)
280         m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
281
282     //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
283     m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType());
284
285     m_value.SetValueType(value_type);
286
287     if (has_changed_type && log)
288         log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
289                     static_cast<void*>(this), GetTypeName().GetCString());
290
291     if (m_address.IsValid() && m_dynamic_type_info)
292     {
293         // The variable value is in the Scalar value inside the m_value.
294         // We can point our m_data right to it.
295         m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
296         if (m_error.Success())
297         {
298             if (!CanProvideValue())
299             {
300                 // this value object represents an aggregate type whose
301                 // children have values, but this object does not. So we
302                 // say we are changed if our location has changed.
303                 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
304             }
305
306             SetValueIsValid (true);
307             return true;
308         }
309     }
310
311     // We get here if we've failed above...
312     SetValueIsValid (false);
313     return false;
314 }
315
316
317
318 bool
319 ValueObjectDynamicValue::IsInScope ()
320 {
321     return m_parent->IsInScope();
322 }
323
324 bool
325 ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
326 {
327     if (!UpdateValueIfNeeded(false))
328     {
329         error.SetErrorString("unable to read value");
330         return false;
331     }
332     
333     uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
334     uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
335     
336     if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
337     {
338         error.SetErrorString("unable to read value");
339         return false;
340     }
341     
342     // if we are at an offset from our parent, in order to set ourselves correctly we would need
343     // to change the new value so that it refers to the correct dynamic type. we choose not to deal
344     // with that - if anything more than a value overwrite is required, you should be using the
345     // expression parser instead of the value editing facility
346     if (my_value != parent_value)
347     {
348         // but NULL'ing out a value should always be allowed
349         if (strcmp(value_str,"0"))
350         {
351             error.SetErrorString("unable to modify dynamic value, use 'expression' command");
352             return false;
353         }
354     }
355     
356     bool ret_val = m_parent->SetValueFromCString(value_str,error);
357     SetNeedsUpdate();
358     return ret_val;
359 }
360
361 bool
362 ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
363 {
364     if (!UpdateValueIfNeeded(false))
365     {
366         error.SetErrorString("unable to read value");
367         return false;
368     }
369     
370     uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
371     uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
372     
373     if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
374     {
375         error.SetErrorString("unable to read value");
376         return false;
377     }
378     
379     // if we are at an offset from our parent, in order to set ourselves correctly we would need
380     // to change the new value so that it refers to the correct dynamic type. we choose not to deal
381     // with that - if anything more than a value overwrite is required, you should be using the
382     // expression parser instead of the value editing facility
383     if (my_value != parent_value)
384     {
385         // but NULL'ing out a value should always be allowed
386         lldb::offset_t offset = 0;
387         
388         if (data.GetPointer(&offset) != 0)
389         {
390             error.SetErrorString("unable to modify dynamic value, use 'expression' command");
391             return false;
392         }
393     }
394     
395     bool ret_val = m_parent->SetData(data, error);
396     SetNeedsUpdate();
397     return ret_val;
398 }
399
400 void
401 ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang)
402 {
403     this->ValueObject::SetPreferredDisplayLanguage(lang);
404     if (m_parent)
405         m_parent->SetPreferredDisplayLanguage(lang);
406 }
407
408 lldb::LanguageType
409 ValueObjectDynamicValue::GetPreferredDisplayLanguage ()
410 {
411     if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
412     {
413         if (m_parent)
414             return m_parent->GetPreferredDisplayLanguage();
415         return lldb::eLanguageTypeUnknown;
416     }
417     else
418         return m_preferred_display_language;
419 }
420
421 bool
422 ValueObjectDynamicValue::IsSyntheticChildrenGenerated ()
423 {
424     if (m_parent)
425         return m_parent->IsSyntheticChildrenGenerated();
426     return false;
427 }
428
429 void
430 ValueObjectDynamicValue::SetSyntheticChildrenGenerated (bool b)
431 {
432     if (m_parent)
433         m_parent->SetSyntheticChildrenGenerated(b);
434     this->ValueObject::SetSyntheticChildrenGenerated(b);
435 }
436
437 bool
438 ValueObjectDynamicValue::GetDeclaration (Declaration &decl)
439 {
440     if (m_parent)
441         return m_parent->GetDeclaration(decl);
442
443     return ValueObject::GetDeclaration(decl);
444 }
445
446 uint64_t
447 ValueObjectDynamicValue::GetLanguageFlags ()
448 {
449     if (m_parent)
450         return m_parent->GetLanguageFlags();
451     return this->ValueObject::GetLanguageFlags();
452 }
453
454 void
455 ValueObjectDynamicValue::SetLanguageFlags (uint64_t flags)
456 {
457     if (m_parent)
458         m_parent->SetLanguageFlags(flags);
459     else
460         this->ValueObject::SetLanguageFlags(flags);
461 }