178a685aaSJim Ingham //===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===// 278a685aaSJim Ingham // 378a685aaSJim Ingham // The LLVM Compiler Infrastructure 478a685aaSJim Ingham // 578a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source 678a685aaSJim Ingham // License. See LICENSE.TXT for details. 778a685aaSJim Ingham // 878a685aaSJim Ingham //===----------------------------------------------------------------------===// 978a685aaSJim Ingham 1078a685aaSJim Ingham 1178a685aaSJim Ingham #include "lldb/Core/ValueObjectDynamicValue.h" 1278a685aaSJim Ingham 1378a685aaSJim Ingham // C Includes 1478a685aaSJim Ingham // C++ Includes 1578a685aaSJim Ingham // Other libraries and framework includes 1678a685aaSJim Ingham // Project includes 17d228483dSEnrico Granata #include "lldb/Core/Log.h" 1878a685aaSJim Ingham #include "lldb/Core/Module.h" 1978a685aaSJim Ingham #include "lldb/Core/ValueObjectList.h" 2078a685aaSJim Ingham #include "lldb/Core/Value.h" 2178a685aaSJim Ingham #include "lldb/Core/ValueObject.h" 2278a685aaSJim Ingham 2321fd13f9SEnrico Granata #include "lldb/Symbol/ClangASTType.h" 2478a685aaSJim Ingham #include "lldb/Symbol/ObjectFile.h" 2578a685aaSJim Ingham #include "lldb/Symbol/SymbolContext.h" 2678a685aaSJim Ingham #include "lldb/Symbol/Type.h" 2778a685aaSJim Ingham #include "lldb/Symbol/Variable.h" 2878a685aaSJim Ingham 2978a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h" 3078a685aaSJim Ingham #include "lldb/Target/LanguageRuntime.h" 3178a685aaSJim Ingham #include "lldb/Target/Process.h" 3278a685aaSJim Ingham #include "lldb/Target/RegisterContext.h" 3378a685aaSJim Ingham #include "lldb/Target/Target.h" 3478a685aaSJim Ingham #include "lldb/Target/Thread.h" 3578a685aaSJim Ingham 3678a685aaSJim Ingham using namespace lldb_private; 3778a685aaSJim Ingham 382837b766SJim Ingham ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) : 3978a685aaSJim Ingham ValueObject(parent), 4078a685aaSJim Ingham m_address (), 41f7b1a34eSEnrico Granata m_dynamic_type_info(), 422837b766SJim Ingham m_use_dynamic (use_dynamic) 4378a685aaSJim Ingham { 446f3533fbSEnrico Granata SetName (parent.GetName()); 4578a685aaSJim Ingham } 4678a685aaSJim Ingham 4778a685aaSJim Ingham ValueObjectDynamicValue::~ValueObjectDynamicValue() 4878a685aaSJim Ingham { 4978a685aaSJim Ingham m_owning_valobj_sp.reset(); 5078a685aaSJim Ingham } 5178a685aaSJim Ingham 52*57ee3067SGreg Clayton ClangASTType 537277284fSSean Callanan ValueObjectDynamicValue::GetClangTypeImpl () 5478a685aaSJim Ingham { 55f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasTypeSP()) 5678a685aaSJim Ingham return m_value.GetClangType(); 5778a685aaSJim Ingham else 5878a685aaSJim Ingham return m_parent->GetClangType(); 5978a685aaSJim Ingham } 6078a685aaSJim Ingham 6178a685aaSJim Ingham ConstString 6278a685aaSJim Ingham ValueObjectDynamicValue::GetTypeName() 6378a685aaSJim Ingham { 64c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 65f7b1a34eSEnrico Granata if (success) 66f7b1a34eSEnrico Granata { 67f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasTypeSP()) 68*57ee3067SGreg Clayton return GetClangType().GetConstTypeName(); 69f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasName()) 70f7b1a34eSEnrico Granata return m_dynamic_type_info.GetName(); 71f7b1a34eSEnrico Granata } 72f7b1a34eSEnrico Granata return m_parent->GetTypeName(); 73f7b1a34eSEnrico Granata } 74f7b1a34eSEnrico Granata 75f7b1a34eSEnrico Granata ConstString 76f7b1a34eSEnrico Granata ValueObjectDynamicValue::GetQualifiedTypeName() 77f7b1a34eSEnrico Granata { 78f7b1a34eSEnrico Granata const bool success = UpdateValueIfNeeded(false); 79f7b1a34eSEnrico Granata if (success) 80f7b1a34eSEnrico Granata { 81f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasTypeSP()) 82*57ee3067SGreg Clayton return GetClangType().GetConstQualifiedTypeName (); 83f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasName()) 84f7b1a34eSEnrico Granata return m_dynamic_type_info.GetName(); 85f7b1a34eSEnrico Granata } 8678a685aaSJim Ingham return m_parent->GetTypeName(); 8778a685aaSJim Ingham } 8878a685aaSJim Ingham 89c7bece56SGreg Clayton size_t 9078a685aaSJim Ingham ValueObjectDynamicValue::CalculateNumChildren() 9178a685aaSJim Ingham { 92c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 93f7b1a34eSEnrico Granata if (success && m_dynamic_type_info.HasTypeSP()) 94*57ee3067SGreg Clayton return GetClangType().GetNumChildren (true); 9578a685aaSJim Ingham else 9678a685aaSJim Ingham return m_parent->GetNumChildren(); 9778a685aaSJim Ingham } 9878a685aaSJim Ingham 99faac1118SGreg Clayton uint64_t 10078a685aaSJim Ingham ValueObjectDynamicValue::GetByteSize() 10178a685aaSJim Ingham { 102c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 103f7b1a34eSEnrico Granata if (success && m_dynamic_type_info.HasTypeSP()) 104*57ee3067SGreg Clayton return m_value.GetValueByteSize(NULL); 10578a685aaSJim Ingham else 10678a685aaSJim Ingham return m_parent->GetByteSize(); 10778a685aaSJim Ingham } 10878a685aaSJim Ingham 10978a685aaSJim Ingham lldb::ValueType 11078a685aaSJim Ingham ValueObjectDynamicValue::GetValueType() const 11178a685aaSJim Ingham { 11278a685aaSJim Ingham return m_parent->GetValueType(); 11378a685aaSJim Ingham } 11478a685aaSJim Ingham 11578a685aaSJim Ingham bool 11678a685aaSJim Ingham ValueObjectDynamicValue::UpdateValue () 11778a685aaSJim Ingham { 11878a685aaSJim Ingham SetValueIsValid (false); 11978a685aaSJim Ingham m_error.Clear(); 12078a685aaSJim Ingham 121c3e320a7SEnrico Granata if (!m_parent->UpdateValueIfNeeded(false)) 12278a685aaSJim Ingham { 123007d5be6SGreg Clayton // The dynamic value failed to get an error, pass the error along 124007d5be6SGreg Clayton if (m_error.Success() && m_parent->GetError().Fail()) 125007d5be6SGreg Clayton m_error = m_parent->GetError(); 12678a685aaSJim Ingham return false; 12778a685aaSJim Ingham } 12878a685aaSJim Ingham 1292837b766SJim Ingham // Setting our type_sp to NULL will route everything back through our 1302837b766SJim Ingham // parent which is equivalent to not using dynamic values. 1312837b766SJim Ingham if (m_use_dynamic == lldb::eNoDynamicValues) 1322837b766SJim Ingham { 133f7b1a34eSEnrico Granata m_dynamic_type_info.Clear(); 1342837b766SJim Ingham return true; 1352837b766SJim Ingham } 1362837b766SJim Ingham 137cc4d0146SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextRef()); 138c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 139c14ee32dSGreg Clayton if (target) 14078a685aaSJim Ingham { 141c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 142c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 14378a685aaSJim Ingham } 14478a685aaSJim Ingham 14578a685aaSJim Ingham // First make sure our Type and/or Address haven't changed: 146cc4d0146SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 14778a685aaSJim Ingham if (!process) 14878a685aaSJim Ingham return false; 14978a685aaSJim Ingham 15061be0903SJim Ingham TypeAndOrName class_type_or_name; 15178a685aaSJim Ingham Address dynamic_address; 15278a685aaSJim Ingham bool found_dynamic_type = false; 15378a685aaSJim Ingham 15478a685aaSJim Ingham lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 15578a685aaSJim Ingham if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 15678a685aaSJim Ingham { 15778a685aaSJim Ingham LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); 15878a685aaSJim Ingham if (runtime) 1592837b766SJim Ingham found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 16078a685aaSJim Ingham } 16178a685aaSJim Ingham else 16278a685aaSJim Ingham { 16378a685aaSJim Ingham LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); 16478a685aaSJim Ingham if (cpp_runtime) 1652837b766SJim Ingham found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 16678a685aaSJim Ingham 16778a685aaSJim Ingham if (!found_dynamic_type) 16878a685aaSJim Ingham { 16978a685aaSJim Ingham LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); 17078a685aaSJim Ingham if (objc_runtime) 1719910bc85SEnrico Granata found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 17278a685aaSJim Ingham } 17378a685aaSJim Ingham } 17478a685aaSJim Ingham 17561be0903SJim Ingham // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really 17661be0903SJim Ingham // don't... 17761be0903SJim Ingham 17861be0903SJim Ingham m_update_point.SetUpdated(); 17961be0903SJim Ingham 18078a685aaSJim Ingham // If we don't have a dynamic type, then make ourselves just a echo of our parent. 18178a685aaSJim Ingham // Or we could return false, and make ourselves an echo of our parent? 18278a685aaSJim Ingham if (!found_dynamic_type) 18378a685aaSJim Ingham { 184f7b1a34eSEnrico Granata if (m_dynamic_type_info) 18575badc46SEnrico Granata SetValueDidChange(true); 186bd83b87dSEnrico Granata ClearDynamicTypeInformation(); 187f7b1a34eSEnrico Granata m_dynamic_type_info.Clear(); 18878a685aaSJim Ingham m_value = m_parent->GetValue(); 189*57ee3067SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 19078a685aaSJim Ingham return m_error.Success(); 19178a685aaSJim Ingham } 19278a685aaSJim Ingham 19378a685aaSJim Ingham Value old_value(m_value); 19478a685aaSJim Ingham 1955160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 196d228483dSEnrico Granata 197e3e91517SEnrico Granata bool has_changed_type = false; 198e3e91517SEnrico Granata 199f7b1a34eSEnrico Granata if (!m_dynamic_type_info) 20078a685aaSJim Ingham { 201f7b1a34eSEnrico Granata m_dynamic_type_info = class_type_or_name; 202e3e91517SEnrico Granata has_changed_type = true; 20378a685aaSJim Ingham } 204f7b1a34eSEnrico Granata else if (class_type_or_name != m_dynamic_type_info) 20578a685aaSJim Ingham { 20678a685aaSJim Ingham // We are another type, we need to tear down our children... 207f7b1a34eSEnrico Granata m_dynamic_type_info = class_type_or_name; 20878a685aaSJim Ingham SetValueDidChange (true); 209e3e91517SEnrico Granata has_changed_type = true; 21078a685aaSJim Ingham } 21178a685aaSJim Ingham 212e3e91517SEnrico Granata if (has_changed_type) 213e3e91517SEnrico Granata ClearDynamicTypeInformation (); 214e3e91517SEnrico Granata 21578a685aaSJim Ingham if (!m_address.IsValid() || m_address != dynamic_address) 21678a685aaSJim Ingham { 21778a685aaSJim Ingham if (m_address.IsValid()) 21878a685aaSJim Ingham SetValueDidChange (true); 21978a685aaSJim Ingham 22078a685aaSJim Ingham // We've moved, so we should be fine... 22178a685aaSJim Ingham m_address = dynamic_address; 222cc4d0146SGreg Clayton lldb::TargetSP target_sp (GetTargetSP()); 223cc4d0146SGreg Clayton lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 22478a685aaSJim Ingham m_value.GetScalar() = load_address; 22578a685aaSJim Ingham } 22678a685aaSJim Ingham 227*57ee3067SGreg Clayton ClangASTType corrected_type; 228f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasTypeSP()) 229f7b1a34eSEnrico Granata { 23078a685aaSJim Ingham // The type will always be the type of the dynamic object. If our parent's type was a pointer, 23178a685aaSJim Ingham // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type 23278a685aaSJim Ingham // should be okay... 233*57ee3067SGreg Clayton ClangASTType orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType(); 234f7b1a34eSEnrico Granata corrected_type = orig_type; 23578a685aaSJim Ingham if (m_parent->IsPointerType()) 236*57ee3067SGreg Clayton corrected_type = orig_type.GetPointerType (); 23778a685aaSJim Ingham else if (m_parent->IsPointerOrReferenceType()) 238*57ee3067SGreg Clayton corrected_type = orig_type.GetLValueReferenceType (); 239f7b1a34eSEnrico Granata } 240f7b1a34eSEnrico Granata else /*if (m_dynamic_type_info.HasName())*/ 241f7b1a34eSEnrico Granata { 242f7b1a34eSEnrico Granata // If we are here we need to adjust our dynamic type name to include the correct & or * symbol 243f7b1a34eSEnrico Granata std::string type_name_buf (m_dynamic_type_info.GetName().GetCString()); 244f7b1a34eSEnrico Granata if (m_parent->IsPointerType()) 245f7b1a34eSEnrico Granata type_name_buf.append(" *"); 246f7b1a34eSEnrico Granata else if (m_parent->IsPointerOrReferenceType()) 247f7b1a34eSEnrico Granata type_name_buf.append(" &"); 248f7b1a34eSEnrico Granata corrected_type = m_parent->GetClangType(); 249f7b1a34eSEnrico Granata m_dynamic_type_info.SetName(type_name_buf.c_str()); 250f7b1a34eSEnrico Granata } 25178a685aaSJim Ingham 252*57ee3067SGreg Clayton //m_value.SetContext (Value::eContextTypeClangType, corrected_type); 253*57ee3067SGreg Clayton m_value.SetClangType (corrected_type); 25478a685aaSJim Ingham 25578a685aaSJim Ingham // Our address is the location of the dynamic type stored in memory. It isn't a load address, 25678a685aaSJim Ingham // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... 25778a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeScalar); 25878a685aaSJim Ingham 259e3e91517SEnrico Granata if (has_changed_type && log) 260e3e91517SEnrico Granata log->Printf("[%s %p] has a new dynamic type %s", 261e3e91517SEnrico Granata GetName().GetCString(), 262e3e91517SEnrico Granata this, 263e3e91517SEnrico Granata GetTypeName().GetCString()); 264e3e91517SEnrico Granata 265f7b1a34eSEnrico Granata if (m_address.IsValid() && m_dynamic_type_info) 26678a685aaSJim Ingham { 26778a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 26878a685aaSJim Ingham // We can point our m_data right to it. 269*57ee3067SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 27078a685aaSJim Ingham if (m_error.Success()) 27178a685aaSJim Ingham { 272*57ee3067SGreg Clayton if (GetClangType().IsAggregateType ()) 27378a685aaSJim Ingham { 27478a685aaSJim Ingham // this value object represents an aggregate type whose 27578a685aaSJim Ingham // children have values, but this object does not. So we 27678a685aaSJim Ingham // say we are changed if our location has changed. 27778a685aaSJim Ingham SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 27878a685aaSJim Ingham } 27978a685aaSJim Ingham 28078a685aaSJim Ingham SetValueIsValid (true); 28178a685aaSJim Ingham return true; 28278a685aaSJim Ingham } 28378a685aaSJim Ingham } 28478a685aaSJim Ingham 28578a685aaSJim Ingham // We get here if we've failed above... 28678a685aaSJim Ingham SetValueIsValid (false); 28778a685aaSJim Ingham return false; 28878a685aaSJim Ingham } 28978a685aaSJim Ingham 29078a685aaSJim Ingham 29178a685aaSJim Ingham 29278a685aaSJim Ingham bool 29378a685aaSJim Ingham ValueObjectDynamicValue::IsInScope () 29478a685aaSJim Ingham { 29578a685aaSJim Ingham return m_parent->IsInScope(); 29678a685aaSJim Ingham } 29778a685aaSJim Ingham 29807a4ac22SEnrico Granata bool 29907a4ac22SEnrico Granata ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error) 30007a4ac22SEnrico Granata { 30107a4ac22SEnrico Granata if (!UpdateValueIfNeeded(false)) 30207a4ac22SEnrico Granata { 30307a4ac22SEnrico Granata error.SetErrorString("unable to read value"); 30407a4ac22SEnrico Granata return false; 30507a4ac22SEnrico Granata } 30607a4ac22SEnrico Granata 30707a4ac22SEnrico Granata uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 30807a4ac22SEnrico Granata uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 30907a4ac22SEnrico Granata 31007a4ac22SEnrico Granata if (my_value == UINT64_MAX || parent_value == UINT64_MAX) 31107a4ac22SEnrico Granata { 31207a4ac22SEnrico Granata error.SetErrorString("unable to read value"); 31307a4ac22SEnrico Granata return false; 31407a4ac22SEnrico Granata } 31507a4ac22SEnrico Granata 31607a4ac22SEnrico Granata // if we are at an offset from our parent, in order to set ourselves correctly we would need 31707a4ac22SEnrico Granata // to change the new value so that it refers to the correct dynamic type. we choose not to deal 31807a4ac22SEnrico Granata // with that - if anything more than a value overwrite is required, you should be using the 31907a4ac22SEnrico Granata // expression parser instead of the value editing facility 32007a4ac22SEnrico Granata if (my_value != parent_value) 32107a4ac22SEnrico Granata { 32207a4ac22SEnrico Granata // but NULL'ing out a value should always be allowed 32307a4ac22SEnrico Granata if (strcmp(value_str,"0")) 32407a4ac22SEnrico Granata { 32507a4ac22SEnrico Granata error.SetErrorString("unable to modify dynamic value, use 'expression' command"); 32607a4ac22SEnrico Granata return false; 32707a4ac22SEnrico Granata } 32807a4ac22SEnrico Granata } 32907a4ac22SEnrico Granata 33007a4ac22SEnrico Granata bool ret_val = m_parent->SetValueFromCString(value_str,error); 33107a4ac22SEnrico Granata SetNeedsUpdate(); 33207a4ac22SEnrico Granata return ret_val; 33307a4ac22SEnrico Granata } 334389823e9SSean Callanan 335389823e9SSean Callanan bool 336389823e9SSean Callanan ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error) 337389823e9SSean Callanan { 338389823e9SSean Callanan if (!UpdateValueIfNeeded(false)) 339389823e9SSean Callanan { 340389823e9SSean Callanan error.SetErrorString("unable to read value"); 341389823e9SSean Callanan return false; 342389823e9SSean Callanan } 343389823e9SSean Callanan 344389823e9SSean Callanan uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 345389823e9SSean Callanan uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 346389823e9SSean Callanan 347389823e9SSean Callanan if (my_value == UINT64_MAX || parent_value == UINT64_MAX) 348389823e9SSean Callanan { 349389823e9SSean Callanan error.SetErrorString("unable to read value"); 350389823e9SSean Callanan return false; 351389823e9SSean Callanan } 352389823e9SSean Callanan 353389823e9SSean Callanan // if we are at an offset from our parent, in order to set ourselves correctly we would need 354389823e9SSean Callanan // to change the new value so that it refers to the correct dynamic type. we choose not to deal 355389823e9SSean Callanan // with that - if anything more than a value overwrite is required, you should be using the 356389823e9SSean Callanan // expression parser instead of the value editing facility 357389823e9SSean Callanan if (my_value != parent_value) 358389823e9SSean Callanan { 359389823e9SSean Callanan // but NULL'ing out a value should always be allowed 360389823e9SSean Callanan lldb::offset_t offset = 0; 361389823e9SSean Callanan 362389823e9SSean Callanan if (data.GetPointer(&offset) != 0) 363389823e9SSean Callanan { 364389823e9SSean Callanan error.SetErrorString("unable to modify dynamic value, use 'expression' command"); 365389823e9SSean Callanan return false; 366389823e9SSean Callanan } 367389823e9SSean Callanan } 368389823e9SSean Callanan 369389823e9SSean Callanan bool ret_val = m_parent->SetData(data, error); 370389823e9SSean Callanan SetNeedsUpdate(); 371389823e9SSean Callanan return ret_val; 372389823e9SSean Callanan } 373