1254721Semaste//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste 11254721Semaste#include "lldb/Core/ValueObjectDynamicValue.h" 12254721Semaste 13254721Semaste// C Includes 14254721Semaste// C++ Includes 15254721Semaste// Other libraries and framework includes 16254721Semaste// Project includes 17254721Semaste#include "lldb/Core/Log.h" 18254721Semaste#include "lldb/Core/Module.h" 19254721Semaste#include "lldb/Core/ValueObjectList.h" 20254721Semaste#include "lldb/Core/Value.h" 21254721Semaste#include "lldb/Core/ValueObject.h" 22254721Semaste 23254721Semaste#include "lldb/Symbol/ClangASTType.h" 24254721Semaste#include "lldb/Symbol/ObjectFile.h" 25254721Semaste#include "lldb/Symbol/SymbolContext.h" 26254721Semaste#include "lldb/Symbol/Type.h" 27254721Semaste#include "lldb/Symbol/Variable.h" 28254721Semaste 29254721Semaste#include "lldb/Target/ExecutionContext.h" 30254721Semaste#include "lldb/Target/LanguageRuntime.h" 31254721Semaste#include "lldb/Target/Process.h" 32254721Semaste#include "lldb/Target/RegisterContext.h" 33254721Semaste#include "lldb/Target/Target.h" 34254721Semaste#include "lldb/Target/Thread.h" 35254721Semaste 36254721Semasteusing namespace lldb_private; 37254721Semaste 38254721SemasteValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) : 39254721Semaste ValueObject(parent), 40254721Semaste m_address (), 41254721Semaste m_dynamic_type_info(), 42254721Semaste m_use_dynamic (use_dynamic) 43254721Semaste{ 44254721Semaste SetName (parent.GetName()); 45254721Semaste} 46254721Semaste 47254721SemasteValueObjectDynamicValue::~ValueObjectDynamicValue() 48254721Semaste{ 49254721Semaste m_owning_valobj_sp.reset(); 50254721Semaste} 51254721Semaste 52254721SemasteClangASTType 53254721SemasteValueObjectDynamicValue::GetClangTypeImpl () 54254721Semaste{ 55263363Semaste const bool success = UpdateValueIfNeeded(false); 56263363Semaste if (success) 57263363Semaste { 58263363Semaste if (m_dynamic_type_info.HasType()) 59263363Semaste return m_value.GetClangType(); 60263363Semaste else 61263363Semaste return m_parent->GetClangType(); 62263363Semaste } 63263363Semaste return m_parent->GetClangType(); 64254721Semaste} 65254721Semaste 66254721SemasteConstString 67254721SemasteValueObjectDynamicValue::GetTypeName() 68254721Semaste{ 69254721Semaste const bool success = UpdateValueIfNeeded(false); 70254721Semaste if (success) 71254721Semaste { 72254721Semaste if (m_dynamic_type_info.HasName()) 73254721Semaste return m_dynamic_type_info.GetName(); 74263363Semaste if (m_dynamic_type_info.HasType()) 75263363Semaste return GetClangType().GetConstTypeName(); 76254721Semaste } 77254721Semaste return m_parent->GetTypeName(); 78254721Semaste} 79254721Semaste 80263363SemasteTypeImpl 81263363SemasteValueObjectDynamicValue::GetTypeImpl () 82263363Semaste{ 83263363Semaste const bool success = UpdateValueIfNeeded(false); 84263363Semaste if (success && m_type_impl.IsValid()) 85263363Semaste { 86263363Semaste return m_type_impl; 87263363Semaste } 88263363Semaste return m_parent->GetTypeImpl(); 89263363Semaste} 90263363Semaste 91254721SemasteConstString 92254721SemasteValueObjectDynamicValue::GetQualifiedTypeName() 93254721Semaste{ 94254721Semaste const bool success = UpdateValueIfNeeded(false); 95254721Semaste if (success) 96254721Semaste { 97254721Semaste if (m_dynamic_type_info.HasName()) 98254721Semaste return m_dynamic_type_info.GetName(); 99263363Semaste if (m_dynamic_type_info.HasType()) 100263363Semaste return GetClangType().GetConstQualifiedTypeName (); 101254721Semaste } 102254721Semaste return m_parent->GetTypeName(); 103254721Semaste} 104254721Semaste 105254721Semastesize_t 106254721SemasteValueObjectDynamicValue::CalculateNumChildren() 107254721Semaste{ 108254721Semaste const bool success = UpdateValueIfNeeded(false); 109263363Semaste if (success && m_dynamic_type_info.HasType()) 110254721Semaste return GetClangType().GetNumChildren (true); 111254721Semaste else 112254721Semaste return m_parent->GetNumChildren(); 113254721Semaste} 114254721Semaste 115254721Semasteuint64_t 116254721SemasteValueObjectDynamicValue::GetByteSize() 117254721Semaste{ 118254721Semaste const bool success = UpdateValueIfNeeded(false); 119263363Semaste if (success && m_dynamic_type_info.HasType()) 120254721Semaste return m_value.GetValueByteSize(NULL); 121254721Semaste else 122254721Semaste return m_parent->GetByteSize(); 123254721Semaste} 124254721Semaste 125254721Semastelldb::ValueType 126254721SemasteValueObjectDynamicValue::GetValueType() const 127254721Semaste{ 128254721Semaste return m_parent->GetValueType(); 129254721Semaste} 130254721Semaste 131263363Semaste 132263363Semastestatic TypeAndOrName 133263363SemasteFixupTypeAndOrName (const TypeAndOrName& type_andor_name, 134263363Semaste ValueObject& parent) 135263363Semaste{ 136263363Semaste TypeAndOrName ret(type_andor_name); 137263363Semaste if (type_andor_name.HasType()) 138263363Semaste { 139263363Semaste // The type will always be the type of the dynamic object. If our parent's type was a pointer, 140263363Semaste // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type 141263363Semaste // should be okay... 142263363Semaste ClangASTType orig_type = type_andor_name.GetClangASTType(); 143263363Semaste ClangASTType corrected_type = orig_type; 144263363Semaste if (parent.IsPointerType()) 145263363Semaste corrected_type = orig_type.GetPointerType (); 146263363Semaste else if (parent.IsPointerOrReferenceType()) 147263363Semaste corrected_type = orig_type.GetLValueReferenceType (); 148263363Semaste ret.SetClangASTType(corrected_type); 149263363Semaste } 150263363Semaste else /*if (m_dynamic_type_info.HasName())*/ 151263363Semaste { 152263363Semaste // If we are here we need to adjust our dynamic type name to include the correct & or * symbol 153263363Semaste std::string corrected_name (type_andor_name.GetName().GetCString()); 154263363Semaste if (parent.IsPointerType()) 155263363Semaste corrected_name.append(" *"); 156263363Semaste else if (parent.IsPointerOrReferenceType()) 157263363Semaste corrected_name.append(" &"); 158263363Semaste // the parent type should be a correctly pointer'ed or referenc'ed type 159263363Semaste ret.SetClangASTType(parent.GetClangType()); 160263363Semaste ret.SetName(corrected_name.c_str()); 161263363Semaste } 162263363Semaste return ret; 163263363Semaste} 164263363Semaste 165254721Semastebool 166254721SemasteValueObjectDynamicValue::UpdateValue () 167254721Semaste{ 168254721Semaste SetValueIsValid (false); 169254721Semaste m_error.Clear(); 170254721Semaste 171254721Semaste if (!m_parent->UpdateValueIfNeeded(false)) 172254721Semaste { 173254721Semaste // The dynamic value failed to get an error, pass the error along 174254721Semaste if (m_error.Success() && m_parent->GetError().Fail()) 175254721Semaste m_error = m_parent->GetError(); 176254721Semaste return false; 177254721Semaste } 178254721Semaste 179254721Semaste // Setting our type_sp to NULL will route everything back through our 180254721Semaste // parent which is equivalent to not using dynamic values. 181254721Semaste if (m_use_dynamic == lldb::eNoDynamicValues) 182254721Semaste { 183254721Semaste m_dynamic_type_info.Clear(); 184254721Semaste return true; 185254721Semaste } 186254721Semaste 187254721Semaste ExecutionContext exe_ctx (GetExecutionContextRef()); 188254721Semaste Target *target = exe_ctx.GetTargetPtr(); 189254721Semaste if (target) 190254721Semaste { 191254721Semaste m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 192254721Semaste m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 193254721Semaste } 194254721Semaste 195254721Semaste // First make sure our Type and/or Address haven't changed: 196254721Semaste Process *process = exe_ctx.GetProcessPtr(); 197254721Semaste if (!process) 198254721Semaste return false; 199254721Semaste 200254721Semaste TypeAndOrName class_type_or_name; 201254721Semaste Address dynamic_address; 202254721Semaste bool found_dynamic_type = false; 203254721Semaste 204254721Semaste lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 205254721Semaste if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 206254721Semaste { 207254721Semaste LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); 208254721Semaste if (runtime) 209254721Semaste found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 210254721Semaste } 211254721Semaste else 212254721Semaste { 213254721Semaste LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); 214254721Semaste if (cpp_runtime) 215254721Semaste found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 216254721Semaste 217254721Semaste if (!found_dynamic_type) 218254721Semaste { 219254721Semaste LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); 220254721Semaste if (objc_runtime) 221254721Semaste found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 222254721Semaste } 223254721Semaste } 224254721Semaste 225254721Semaste // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really 226254721Semaste // don't... 227254721Semaste 228254721Semaste m_update_point.SetUpdated(); 229263363Semaste 230263363Semaste if (found_dynamic_type) 231263363Semaste { 232263363Semaste if (class_type_or_name.HasType()) 233263363Semaste { 234263363Semaste // TypeSP are always generated from debug info 235263363Semaste if (!class_type_or_name.HasTypeSP() && class_type_or_name.GetClangASTType().IsRuntimeGeneratedType()) 236263363Semaste { 237263363Semaste m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType()); 238263363Semaste class_type_or_name.SetClangASTType(ClangASTType()); 239263363Semaste } 240263363Semaste else 241263363Semaste { 242263363Semaste m_type_impl = TypeImpl(FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType()); 243263363Semaste } 244263363Semaste } 245263363Semaste else 246263363Semaste { 247263363Semaste m_type_impl.Clear(); 248263363Semaste } 249263363Semaste } 250263363Semaste else 251263363Semaste { 252263363Semaste m_type_impl.Clear(); 253263363Semaste } 254254721Semaste 255254721Semaste // If we don't have a dynamic type, then make ourselves just a echo of our parent. 256254721Semaste // Or we could return false, and make ourselves an echo of our parent? 257254721Semaste if (!found_dynamic_type) 258254721Semaste { 259254721Semaste if (m_dynamic_type_info) 260254721Semaste SetValueDidChange(true); 261254721Semaste ClearDynamicTypeInformation(); 262254721Semaste m_dynamic_type_info.Clear(); 263254721Semaste m_value = m_parent->GetValue(); 264254721Semaste m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 265254721Semaste return m_error.Success(); 266254721Semaste } 267254721Semaste 268254721Semaste Value old_value(m_value); 269254721Semaste 270254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 271254721Semaste 272254721Semaste bool has_changed_type = false; 273254721Semaste 274254721Semaste if (!m_dynamic_type_info) 275254721Semaste { 276254721Semaste m_dynamic_type_info = class_type_or_name; 277254721Semaste has_changed_type = true; 278254721Semaste } 279254721Semaste else if (class_type_or_name != m_dynamic_type_info) 280254721Semaste { 281254721Semaste // We are another type, we need to tear down our children... 282254721Semaste m_dynamic_type_info = class_type_or_name; 283254721Semaste SetValueDidChange (true); 284254721Semaste has_changed_type = true; 285254721Semaste } 286254721Semaste 287254721Semaste if (has_changed_type) 288254721Semaste ClearDynamicTypeInformation (); 289254721Semaste 290254721Semaste if (!m_address.IsValid() || m_address != dynamic_address) 291254721Semaste { 292254721Semaste if (m_address.IsValid()) 293254721Semaste SetValueDidChange (true); 294254721Semaste 295254721Semaste // We've moved, so we should be fine... 296254721Semaste m_address = dynamic_address; 297254721Semaste lldb::TargetSP target_sp (GetTargetSP()); 298254721Semaste lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 299254721Semaste m_value.GetScalar() = load_address; 300254721Semaste } 301254721Semaste 302263363Semaste m_dynamic_type_info = FixupTypeAndOrName(m_dynamic_type_info, *m_parent); 303254721Semaste 304254721Semaste //m_value.SetContext (Value::eContextTypeClangType, corrected_type); 305263363Semaste m_value.SetClangType (m_dynamic_type_info.GetClangASTType()); 306254721Semaste 307254721Semaste // Our address is the location of the dynamic type stored in memory. It isn't a load address, 308254721Semaste // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... 309254721Semaste m_value.SetValueType(Value::eValueTypeScalar); 310254721Semaste 311254721Semaste if (has_changed_type && log) 312254721Semaste log->Printf("[%s %p] has a new dynamic type %s", 313254721Semaste GetName().GetCString(), 314254721Semaste this, 315254721Semaste GetTypeName().GetCString()); 316254721Semaste 317254721Semaste if (m_address.IsValid() && m_dynamic_type_info) 318254721Semaste { 319254721Semaste // The variable value is in the Scalar value inside the m_value. 320254721Semaste // We can point our m_data right to it. 321254721Semaste m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 322254721Semaste if (m_error.Success()) 323254721Semaste { 324254721Semaste if (GetClangType().IsAggregateType ()) 325254721Semaste { 326254721Semaste // this value object represents an aggregate type whose 327254721Semaste // children have values, but this object does not. So we 328254721Semaste // say we are changed if our location has changed. 329254721Semaste SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 330254721Semaste } 331254721Semaste 332254721Semaste SetValueIsValid (true); 333254721Semaste return true; 334254721Semaste } 335254721Semaste } 336254721Semaste 337254721Semaste // We get here if we've failed above... 338254721Semaste SetValueIsValid (false); 339254721Semaste return false; 340254721Semaste} 341254721Semaste 342254721Semaste 343254721Semaste 344254721Semastebool 345254721SemasteValueObjectDynamicValue::IsInScope () 346254721Semaste{ 347254721Semaste return m_parent->IsInScope(); 348254721Semaste} 349254721Semaste 350254721Semastebool 351254721SemasteValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error) 352254721Semaste{ 353254721Semaste if (!UpdateValueIfNeeded(false)) 354254721Semaste { 355254721Semaste error.SetErrorString("unable to read value"); 356254721Semaste return false; 357254721Semaste } 358254721Semaste 359254721Semaste uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 360254721Semaste uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 361254721Semaste 362254721Semaste if (my_value == UINT64_MAX || parent_value == UINT64_MAX) 363254721Semaste { 364254721Semaste error.SetErrorString("unable to read value"); 365254721Semaste return false; 366254721Semaste } 367254721Semaste 368254721Semaste // if we are at an offset from our parent, in order to set ourselves correctly we would need 369254721Semaste // to change the new value so that it refers to the correct dynamic type. we choose not to deal 370254721Semaste // with that - if anything more than a value overwrite is required, you should be using the 371254721Semaste // expression parser instead of the value editing facility 372254721Semaste if (my_value != parent_value) 373254721Semaste { 374254721Semaste // but NULL'ing out a value should always be allowed 375254721Semaste if (strcmp(value_str,"0")) 376254721Semaste { 377254721Semaste error.SetErrorString("unable to modify dynamic value, use 'expression' command"); 378254721Semaste return false; 379254721Semaste } 380254721Semaste } 381254721Semaste 382254721Semaste bool ret_val = m_parent->SetValueFromCString(value_str,error); 383254721Semaste SetNeedsUpdate(); 384254721Semaste return ret_val; 385254721Semaste} 386254721Semaste 387254721Semastebool 388254721SemasteValueObjectDynamicValue::SetData (DataExtractor &data, Error &error) 389254721Semaste{ 390254721Semaste if (!UpdateValueIfNeeded(false)) 391254721Semaste { 392254721Semaste error.SetErrorString("unable to read value"); 393254721Semaste return false; 394254721Semaste } 395254721Semaste 396254721Semaste uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 397254721Semaste uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 398254721Semaste 399254721Semaste if (my_value == UINT64_MAX || parent_value == UINT64_MAX) 400254721Semaste { 401254721Semaste error.SetErrorString("unable to read value"); 402254721Semaste return false; 403254721Semaste } 404254721Semaste 405254721Semaste // if we are at an offset from our parent, in order to set ourselves correctly we would need 406254721Semaste // to change the new value so that it refers to the correct dynamic type. we choose not to deal 407254721Semaste // with that - if anything more than a value overwrite is required, you should be using the 408254721Semaste // expression parser instead of the value editing facility 409254721Semaste if (my_value != parent_value) 410254721Semaste { 411254721Semaste // but NULL'ing out a value should always be allowed 412254721Semaste lldb::offset_t offset = 0; 413254721Semaste 414254721Semaste if (data.GetPointer(&offset) != 0) 415254721Semaste { 416254721Semaste error.SetErrorString("unable to modify dynamic value, use 'expression' command"); 417254721Semaste return false; 418254721Semaste } 419254721Semaste } 420254721Semaste 421254721Semaste bool ret_val = m_parent->SetData(data, error); 422254721Semaste SetNeedsUpdate(); 423254721Semaste return ret_val; 424254721Semaste} 425