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 return m_value.GetValueByteSize(nullptr); 131 else 132 return m_parent->GetByteSize(); 133 } 134 135 lldb::ValueType 136 ValueObjectDynamicValue::GetValueType() const 137 { 138 return m_parent->GetValueType(); 139 } 140 141 bool 142 ValueObjectDynamicValue::UpdateValue () 143 { 144 SetValueIsValid (false); 145 m_error.Clear(); 146 147 if (!m_parent->UpdateValueIfNeeded(false)) 148 { 149 // The dynamic value failed to get an error, pass the error along 150 if (m_error.Success() && m_parent->GetError().Fail()) 151 m_error = m_parent->GetError(); 152 return false; 153 } 154 155 // Setting our type_sp to NULL will route everything back through our 156 // parent which is equivalent to not using dynamic values. 157 if (m_use_dynamic == lldb::eNoDynamicValues) 158 { 159 m_dynamic_type_info.Clear(); 160 return true; 161 } 162 163 ExecutionContext exe_ctx (GetExecutionContextRef()); 164 Target *target = exe_ctx.GetTargetPtr(); 165 if (target) 166 { 167 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 168 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 169 } 170 171 // First make sure our Type and/or Address haven't changed: 172 Process *process = exe_ctx.GetProcessPtr(); 173 if (!process) 174 return false; 175 176 TypeAndOrName class_type_or_name; 177 Address dynamic_address; 178 bool found_dynamic_type = false; 179 Value::ValueType value_type; 180 181 LanguageRuntime *runtime = nullptr; 182 183 lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 184 if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 185 { 186 runtime = process->GetLanguageRuntime (known_type); 187 if (runtime) 188 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); 189 } 190 else 191 { 192 runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); 193 if (runtime) 194 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); 195 196 if (!found_dynamic_type) 197 { 198 runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); 199 if (runtime) 200 found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); 201 } 202 } 203 204 // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really 205 // don't... 206 207 m_update_point.SetUpdated(); 208 209 if (runtime && found_dynamic_type) 210 { 211 if (class_type_or_name.HasType()) 212 { 213 m_type_impl = TypeImpl(m_parent->GetCompilerType(), 214 runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType()); 215 } 216 else 217 { 218 m_type_impl.Clear(); 219 } 220 } 221 else 222 { 223 m_type_impl.Clear(); 224 } 225 226 // If we don't have a dynamic type, then make ourselves just a echo of our parent. 227 // Or we could return false, and make ourselves an echo of our parent? 228 if (!found_dynamic_type) 229 { 230 if (m_dynamic_type_info) 231 SetValueDidChange(true); 232 ClearDynamicTypeInformation(); 233 m_dynamic_type_info.Clear(); 234 m_value = m_parent->GetValue(); 235 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 236 return m_error.Success(); 237 } 238 239 Value old_value(m_value); 240 241 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 242 243 bool has_changed_type = false; 244 245 if (!m_dynamic_type_info) 246 { 247 m_dynamic_type_info = class_type_or_name; 248 has_changed_type = true; 249 } 250 else if (class_type_or_name != m_dynamic_type_info) 251 { 252 // We are another type, we need to tear down our children... 253 m_dynamic_type_info = class_type_or_name; 254 SetValueDidChange (true); 255 has_changed_type = true; 256 } 257 258 if (has_changed_type) 259 ClearDynamicTypeInformation (); 260 261 if (!m_address.IsValid() || m_address != dynamic_address) 262 { 263 if (m_address.IsValid()) 264 SetValueDidChange (true); 265 266 // We've moved, so we should be fine... 267 m_address = dynamic_address; 268 lldb::TargetSP target_sp (GetTargetSP()); 269 lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 270 m_value.GetScalar() = load_address; 271 } 272 273 if (runtime) 274 m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); 275 276 //m_value.SetContext (Value::eContextTypeClangType, corrected_type); 277 m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType()); 278 279 m_value.SetValueType(value_type); 280 281 if (has_changed_type && log) 282 log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(), 283 static_cast<void*>(this), GetTypeName().GetCString()); 284 285 if (m_address.IsValid() && m_dynamic_type_info) 286 { 287 // The variable value is in the Scalar value inside the m_value. 288 // We can point our m_data right to it. 289 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 290 if (m_error.Success()) 291 { 292 if (!CanProvideValue()) 293 { 294 // this value object represents an aggregate type whose 295 // children have values, but this object does not. So we 296 // say we are changed if our location has changed. 297 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 298 } 299 300 SetValueIsValid (true); 301 return true; 302 } 303 } 304 305 // We get here if we've failed above... 306 SetValueIsValid (false); 307 return false; 308 } 309 310 311 312 bool 313 ValueObjectDynamicValue::IsInScope () 314 { 315 return m_parent->IsInScope(); 316 } 317 318 bool 319 ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error) 320 { 321 if (!UpdateValueIfNeeded(false)) 322 { 323 error.SetErrorString("unable to read value"); 324 return false; 325 } 326 327 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 328 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 329 330 if (my_value == UINT64_MAX || parent_value == UINT64_MAX) 331 { 332 error.SetErrorString("unable to read value"); 333 return false; 334 } 335 336 // if we are at an offset from our parent, in order to set ourselves correctly we would need 337 // to change the new value so that it refers to the correct dynamic type. we choose not to deal 338 // with that - if anything more than a value overwrite is required, you should be using the 339 // expression parser instead of the value editing facility 340 if (my_value != parent_value) 341 { 342 // but NULL'ing out a value should always be allowed 343 if (strcmp(value_str,"0")) 344 { 345 error.SetErrorString("unable to modify dynamic value, use 'expression' command"); 346 return false; 347 } 348 } 349 350 bool ret_val = m_parent->SetValueFromCString(value_str,error); 351 SetNeedsUpdate(); 352 return ret_val; 353 } 354 355 bool 356 ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error) 357 { 358 if (!UpdateValueIfNeeded(false)) 359 { 360 error.SetErrorString("unable to read value"); 361 return false; 362 } 363 364 uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 365 uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 366 367 if (my_value == UINT64_MAX || parent_value == UINT64_MAX) 368 { 369 error.SetErrorString("unable to read value"); 370 return false; 371 } 372 373 // if we are at an offset from our parent, in order to set ourselves correctly we would need 374 // to change the new value so that it refers to the correct dynamic type. we choose not to deal 375 // with that - if anything more than a value overwrite is required, you should be using the 376 // expression parser instead of the value editing facility 377 if (my_value != parent_value) 378 { 379 // but NULL'ing out a value should always be allowed 380 lldb::offset_t offset = 0; 381 382 if (data.GetPointer(&offset) != 0) 383 { 384 error.SetErrorString("unable to modify dynamic value, use 'expression' command"); 385 return false; 386 } 387 } 388 389 bool ret_val = m_parent->SetData(data, error); 390 SetNeedsUpdate(); 391 return ret_val; 392 } 393 394 bool 395 ValueObjectDynamicValue::GetDeclaration (Declaration &decl) 396 { 397 if (m_parent) 398 return m_parent->GetDeclaration(decl); 399 400 return ValueObject::GetDeclaration(decl); 401 } 402