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() 117 { 118 const bool success = UpdateValueIfNeeded(false); 119 if (success && m_dynamic_type_info.HasType()) 120 return GetCompilerType().GetNumChildren (true); 121 else 122 return m_parent->GetNumChildren(); 123 } 124 125 uint64_t 126 ValueObjectDynamicValue::GetByteSize() 127 { 128 const bool success = UpdateValueIfNeeded(false); 129 if (success && m_dynamic_type_info.HasType()) 130 { 131 ExecutionContext exe_ctx (GetExecutionContextRef()); 132 return m_value.GetValueByteSize(nullptr, &exe_ctx); 133 } 134 else 135 return m_parent->GetByteSize(); 136 } 137 138 lldb::ValueType 139 ValueObjectDynamicValue::GetValueType() const 140 { 141 return m_parent->GetValueType(); 142 } 143 144 bool 145 ValueObjectDynamicValue::UpdateValue () 146 { 147 SetValueIsValid (false); 148 m_error.Clear(); 149 150 if (!m_parent->UpdateValueIfNeeded(false)) 151 { 152 // 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(); 155 return false; 156 } 157 158 // 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 { 162 m_dynamic_type_info.Clear(); 163 return true; 164 } 165 166 ExecutionContext exe_ctx (GetExecutionContextRef()); 167 Target *target = exe_ctx.GetTargetPtr(); 168 if (target) 169 { 170 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 171 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 172 } 173 174 // First make sure our Type and/or Address haven't changed: 175 Process *process = exe_ctx.GetProcessPtr(); 176 if (!process) 177 return false; 178 179 TypeAndOrName class_type_or_name; 180 Address dynamic_address; 181 bool found_dynamic_type = false; 182 Value::ValueType value_type; 183 184 LanguageRuntime *runtime = nullptr; 185 186 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 187 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 188 { 189 runtime = process->GetLanguageRuntime (known_type); 190 if (runtime) 191 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); 192 } 193 else 194 { 195 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); 198 199 if (!found_dynamic_type) 200 { 201 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); 204 } 205 } 206 207 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really 208 // don't... 209 210 m_update_point.SetUpdated(); 211 212 if (runtime && found_dynamic_type) 213 { 214 if (class_type_or_name.HasType()) 215 { 216 m_type_impl = TypeImpl(m_parent->GetCompilerType(), 217 runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType()); 218 } 219 else 220 { 221 m_type_impl.Clear(); 222 } 223 } 224 else 225 { 226 m_type_impl.Clear(); 227 } 228 229 // 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 { 233 if (m_dynamic_type_info) 234 SetValueDidChange(true); 235 ClearDynamicTypeInformation(); 236 m_dynamic_type_info.Clear(); 237 m_value = m_parent->GetValue(); 238 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 239 return m_error.Success(); 240 } 241 242 Value old_value(m_value); 243 244 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 245 246 bool has_changed_type = false; 247 248 if (!m_dynamic_type_info) 249 { 250 m_dynamic_type_info = class_type_or_name; 251 has_changed_type = true; 252 } 253 else if (class_type_or_name != m_dynamic_type_info) 254 { 255 // We are another type, we need to tear down our children... 256 m_dynamic_type_info = class_type_or_name; 257 SetValueDidChange (true); 258 has_changed_type = true; 259 } 260 261 if (has_changed_type) 262 ClearDynamicTypeInformation (); 263 264 if (!m_address.IsValid() || m_address != dynamic_address) 265 { 266 if (m_address.IsValid()) 267 SetValueDidChange (true); 268 269 // We've moved, so we should be fine... 270 m_address = dynamic_address; 271 lldb::TargetSP target_sp (GetTargetSP()); 272 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 273 m_value.GetScalar() = load_address; 274 } 275 276 if (runtime) 277 m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); 278 279 //m_value.SetContext (Value::eContextTypeClangType, corrected_type); 280 m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType()); 281 282 m_value.SetValueType(value_type); 283 284 if (has_changed_type && log) 285 log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(), 286 static_cast<void*>(this), GetTypeName().GetCString()); 287 288 if (m_address.IsValid() && m_dynamic_type_info) 289 { 290 // The variable value is in the Scalar value inside the m_value. 291 // We can point our m_data right to it. 292 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 293 if (m_error.Success()) 294 { 295 if (!CanProvideValue()) 296 { 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 } 307 308 // We get here if we've failed above... 309 SetValueIsValid (false); 310 return false; 311 } 312 313 314 315 bool 316 ValueObjectDynamicValue::IsInScope () 317 { 318 return m_parent->IsInScope(); 319 } 320 321 bool 322 ValueObjectDynamicValue::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 } 357 358 bool 359 ValueObjectDynamicValue::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 } 396 397 void 398 ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang) 399 { 400 this->ValueObject::SetPreferredDisplayLanguage(lang); 401 if (m_parent) 402 m_parent->SetPreferredDisplayLanguage(lang); 403 } 404 405 lldb::LanguageType 406 ValueObjectDynamicValue::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 418 bool 419 ValueObjectDynamicValue::GetDeclaration (Declaration &decl) 420 { 421 if (m_parent) 422 return m_parent->GetDeclaration(decl); 423 424 return ValueObject::GetDeclaration(decl); 425 } 426