1 //===-- SBValue.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 #include "lldb/API/SBValue.h" 11 #include "lldb/API/SBStream.h" 12 13 #include "lldb/Breakpoint/Watchpoint.h" 14 #include "lldb/Core/DataExtractor.h" 15 #include "lldb/Core/Log.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/Scalar.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Core/StreamFile.h" 20 #include "lldb/Core/Value.h" 21 #include "lldb/Core/ValueObject.h" 22 #include "lldb/Core/ValueObjectConstResult.h" 23 #include "lldb/Symbol/Block.h" 24 #include "lldb/Symbol/ObjectFile.h" 25 #include "lldb/Symbol/Variable.h" 26 #include "lldb/Symbol/VariableList.h" 27 #include "lldb/Target/ExecutionContext.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/StackFrame.h" 30 #include "lldb/Target/Target.h" 31 #include "lldb/Target/Thread.h" 32 33 #include "lldb/API/SBProcess.h" 34 #include "lldb/API/SBTarget.h" 35 #include "lldb/API/SBThread.h" 36 #include "lldb/API/SBFrame.h" 37 #include "lldb/API/SBDebugger.h" 38 39 using namespace lldb; 40 using namespace lldb_private; 41 42 SBValue::SBValue () : 43 m_opaque_sp () 44 { 45 } 46 47 SBValue::SBValue (const lldb::ValueObjectSP &value_sp) : 48 m_opaque_sp (value_sp) 49 { 50 } 51 52 SBValue::SBValue(const SBValue &rhs) : 53 m_opaque_sp (rhs.m_opaque_sp) 54 { 55 } 56 57 SBValue & 58 SBValue::operator = (const SBValue &rhs) 59 { 60 if (this != &rhs) 61 m_opaque_sp = rhs.m_opaque_sp; 62 return *this; 63 } 64 65 SBValue::~SBValue() 66 { 67 } 68 69 bool 70 SBValue::IsValid () 71 { 72 // If this function ever changes to anything that does more than just 73 // check if the opaque shared pointer is non NULL, then we need to update 74 // all "if (m_opaque_sp)" code in this file. 75 return m_opaque_sp.get() != NULL; 76 } 77 78 void 79 SBValue::Clear() 80 { 81 m_opaque_sp.reset(); 82 } 83 84 SBError 85 SBValue::GetError() 86 { 87 SBError sb_error; 88 89 if (m_opaque_sp.get()) 90 sb_error.SetError(m_opaque_sp->GetError()); 91 else 92 sb_error.SetErrorString("error: invalid value"); 93 94 return sb_error; 95 } 96 97 user_id_t 98 SBValue::GetID() 99 { 100 if (m_opaque_sp) 101 return m_opaque_sp->GetID(); 102 return LLDB_INVALID_UID; 103 } 104 105 const char * 106 SBValue::GetName() 107 { 108 109 const char *name = NULL; 110 if (m_opaque_sp) 111 name = m_opaque_sp->GetName().GetCString(); 112 113 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 114 if (log) 115 { 116 if (name) 117 log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name); 118 else 119 log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get()); 120 } 121 122 return name; 123 } 124 125 const char * 126 SBValue::GetTypeName () 127 { 128 const char *name = NULL; 129 if (m_opaque_sp) 130 name = m_opaque_sp->GetTypeName().GetCString(); 131 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 132 if (log) 133 { 134 if (name) 135 log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name); 136 else 137 log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get()); 138 } 139 140 return name; 141 } 142 143 size_t 144 SBValue::GetByteSize () 145 { 146 size_t result = 0; 147 148 if (m_opaque_sp) 149 result = m_opaque_sp->GetByteSize(); 150 151 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 152 if (log) 153 log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result); 154 155 return result; 156 } 157 158 bool 159 SBValue::IsInScope () 160 { 161 bool result = false; 162 163 if (m_opaque_sp) 164 { 165 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 166 { 167 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 168 result = m_opaque_sp->IsInScope (); 169 } 170 } 171 172 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 173 if (log) 174 log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result); 175 176 return result; 177 } 178 179 const char * 180 SBValue::GetValue () 181 { 182 const char *cstr = NULL; 183 if (m_opaque_sp) 184 { 185 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 186 { 187 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 188 cstr = m_opaque_sp->GetValueAsCString (); 189 } 190 } 191 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 192 if (log) 193 { 194 if (cstr) 195 log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr); 196 else 197 log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get()); 198 } 199 200 return cstr; 201 } 202 203 ValueType 204 SBValue::GetValueType () 205 { 206 ValueType result = eValueTypeInvalid; 207 if (m_opaque_sp) 208 result = m_opaque_sp->GetValueType(); 209 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 210 if (log) 211 { 212 switch (result) 213 { 214 case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break; 215 case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break; 216 case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break; 217 case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break; 218 case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break; 219 case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break; 220 case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break; 221 case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break; 222 default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break; 223 } 224 } 225 return result; 226 } 227 228 const char * 229 SBValue::GetObjectDescription () 230 { 231 const char *cstr = NULL; 232 if (m_opaque_sp) 233 { 234 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 235 { 236 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 237 cstr = m_opaque_sp->GetObjectDescription (); 238 } 239 } 240 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 241 if (log) 242 { 243 if (cstr) 244 log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr); 245 else 246 log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get()); 247 } 248 return cstr; 249 } 250 251 SBType 252 SBValue::GetType() 253 { 254 SBType result; 255 if (m_opaque_sp) 256 { 257 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 258 { 259 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 260 result = SBType(ClangASTType (m_opaque_sp->GetClangAST(), m_opaque_sp->GetClangType())); 261 } 262 } 263 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 264 if (log) 265 { 266 if (result.IsValid()) 267 log->Printf ("SBValue(%p)::GetType => %p", m_opaque_sp.get(), &result); 268 else 269 log->Printf ("SBValue(%p)::GetType => NULL", m_opaque_sp.get()); 270 } 271 return result; 272 } 273 274 bool 275 SBValue::GetValueDidChange () 276 { 277 bool result = false; 278 if (m_opaque_sp) 279 { 280 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 281 { 282 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 283 result = m_opaque_sp->GetValueDidChange (); 284 } 285 } 286 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 287 if (log) 288 log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result); 289 290 return result; 291 } 292 293 const char * 294 SBValue::GetSummary () 295 { 296 const char *cstr = NULL; 297 if (m_opaque_sp) 298 { 299 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 300 { 301 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 302 cstr = m_opaque_sp->GetSummaryAsCString(); 303 } 304 } 305 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 306 if (log) 307 { 308 if (cstr) 309 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 310 else 311 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 312 } 313 return cstr; 314 } 315 316 const char * 317 SBValue::GetLocation () 318 { 319 const char *cstr = NULL; 320 if (m_opaque_sp) 321 { 322 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 323 { 324 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 325 cstr = m_opaque_sp->GetLocationAsCString(); 326 } 327 } 328 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 329 if (log) 330 { 331 if (cstr) 332 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 333 else 334 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 335 } 336 return cstr; 337 } 338 339 bool 340 SBValue::SetValueFromCString (const char *value_str) 341 { 342 bool success = false; 343 if (m_opaque_sp) 344 { 345 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 346 { 347 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 348 success = m_opaque_sp->SetValueFromCString (value_str); 349 } 350 } 351 return success; 352 } 353 354 lldb::SBValue 355 SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) 356 { 357 lldb::SBValue result; 358 if (m_opaque_sp) 359 { 360 if (type.IsValid()) 361 { 362 result = SBValue(m_opaque_sp->GetSyntheticChildAtOffset(offset, type.m_opaque_sp->GetClangASTType(), true)); 363 result.m_opaque_sp->SetName(ConstString(name)); 364 } 365 } 366 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 367 if (log) 368 { 369 if (result.IsValid()) 370 log->Printf ("SBValue(%p)::GetChildAtOffset => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 371 else 372 log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", m_opaque_sp.get()); 373 } 374 return result; 375 } 376 377 lldb::SBValue 378 SBValue::Cast (SBType type) 379 { 380 lldb::SBValue sb_value; 381 if (m_opaque_sp) 382 sb_value = CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type); 383 return sb_value; 384 } 385 386 lldb::SBValue 387 SBValue::CreateValueFromExpression (const char *name, const char* expression) 388 { 389 lldb::SBValue result; 390 if (m_opaque_sp) 391 { 392 ValueObjectSP result_valobj_sp; 393 m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression, 394 m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame(), 395 eExecutionPolicyOnlyWhenNeeded, 396 false, // coerce to id 397 true, // unwind on error 398 true, // keep in memory 399 eNoDynamicValues, 400 result_valobj_sp); 401 if (result_valobj_sp) 402 { 403 result_valobj_sp->SetName(ConstString(name)); 404 result = SBValue(result_valobj_sp); 405 } 406 } 407 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 408 if (log) 409 { 410 if (result.IsValid()) 411 log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 412 else 413 log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); 414 } 415 return result; 416 } 417 418 lldb::SBValue 419 SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type) 420 { 421 lldb::SBValue result; 422 if (m_opaque_sp && type.IsValid() && type.GetPointerType().IsValid()) 423 { 424 SBType real_type(type.GetPointerType()); 425 426 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); 427 428 ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(), 429 real_type.m_opaque_sp->GetASTContext(), 430 real_type.m_opaque_sp->GetOpaqueQualType(), 431 ConstString(name), 432 buffer, 433 lldb::endian::InlHostByteOrder(), 434 GetTarget().GetProcess().GetAddressByteSize())); 435 436 ValueObjectSP result_valobj_sp; 437 438 ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); 439 if (ptr_result_valobj_sp) 440 { 441 Error err; 442 result_valobj_sp = ptr_result_valobj_sp->Dereference(err); 443 if (result_valobj_sp) 444 result_valobj_sp->SetName(ConstString(name)); 445 } 446 result = SBValue(result_valobj_sp); 447 } 448 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 449 if (log) 450 { 451 if (result.IsValid()) 452 log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 453 else 454 log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get()); 455 } 456 return result; 457 } 458 459 lldb::SBValue 460 SBValue::CreateValueFromData (const char* name, SBData data, SBType type) 461 { 462 SBValue result; 463 464 AddressType addr_of_children_priv = eAddressTypeLoad; 465 466 if (m_opaque_sp) 467 { 468 ValueObjectSP valobj_sp; 469 valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(), 470 type.m_opaque_sp->GetASTContext() , 471 type.m_opaque_sp->GetOpaqueQualType(), 472 ConstString(name), 473 *data.m_opaque_sp, 474 LLDB_INVALID_ADDRESS); 475 valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv); 476 result = SBValue(valobj_sp); 477 } 478 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 479 if (log) 480 { 481 if (result.IsValid()) 482 log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 483 else 484 log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); 485 } 486 return result; 487 } 488 489 SBValue 490 SBValue::GetChildAtIndex (uint32_t idx) 491 { 492 const bool can_create_synthetic = false; 493 lldb::DynamicValueType use_dynamic = eNoDynamicValues; 494 if (m_opaque_sp) 495 use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue(); 496 return GetChildAtIndex (idx, use_dynamic, can_create_synthetic); 497 } 498 499 SBValue 500 SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic) 501 { 502 lldb::ValueObjectSP child_sp; 503 504 if (m_opaque_sp) 505 { 506 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 507 { 508 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 509 const bool can_create = true; 510 child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create); 511 if (can_create_synthetic && !child_sp) 512 { 513 if (m_opaque_sp->IsPointerType()) 514 { 515 child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create); 516 } 517 else if (m_opaque_sp->IsArrayType()) 518 { 519 child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create); 520 } 521 } 522 523 if (child_sp) 524 { 525 if (use_dynamic != lldb::eNoDynamicValues) 526 { 527 lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic)); 528 if (dynamic_sp) 529 child_sp = dynamic_sp; 530 } 531 } 532 } 533 } 534 535 SBValue sb_value (child_sp); 536 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 537 if (log) 538 log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); 539 540 return sb_value; 541 } 542 543 uint32_t 544 SBValue::GetIndexOfChildWithName (const char *name) 545 { 546 uint32_t idx = UINT32_MAX; 547 if (m_opaque_sp) 548 { 549 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 550 { 551 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 552 553 idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); 554 } 555 } 556 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 557 if (log) 558 { 559 if (idx == UINT32_MAX) 560 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name); 561 else 562 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); 563 } 564 return idx; 565 } 566 567 SBValue 568 SBValue::GetChildMemberWithName (const char *name) 569 { 570 if (m_opaque_sp) 571 { 572 lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue(); 573 return GetChildMemberWithName (name, use_dynamic_value); 574 } 575 else 576 return GetChildMemberWithName (name, eNoDynamicValues); 577 } 578 579 SBValue 580 SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) 581 { 582 lldb::ValueObjectSP child_sp; 583 const ConstString str_name (name); 584 585 586 if (m_opaque_sp) 587 { 588 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 589 { 590 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 591 child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); 592 if (use_dynamic_value != lldb::eNoDynamicValues) 593 { 594 if (child_sp) 595 { 596 lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); 597 if (dynamic_sp) 598 child_sp = dynamic_sp; 599 } 600 } 601 } 602 } 603 604 SBValue sb_value (child_sp); 605 606 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 607 if (log) 608 log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); 609 610 return sb_value; 611 } 612 613 lldb::SBValue 614 SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic) 615 { 616 if (m_opaque_sp) 617 { 618 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 619 { 620 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 621 return SBValue (m_opaque_sp->GetDynamicValue(use_dynamic)); 622 } 623 } 624 625 return SBValue(); 626 } 627 628 lldb::SBValue 629 SBValue::GetStaticValue () 630 { 631 if (m_opaque_sp) 632 { 633 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 634 { 635 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 636 return SBValue(m_opaque_sp->GetStaticValue()); 637 } 638 } 639 640 return SBValue(); 641 } 642 643 bool 644 SBValue::IsDynamic() 645 { 646 if (m_opaque_sp) 647 { 648 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 649 { 650 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 651 return m_opaque_sp->IsDynamic(); 652 } 653 } 654 return false; 655 } 656 657 lldb::SBValue 658 SBValue::GetValueForExpressionPath(const char* expr_path) 659 { 660 lldb::ValueObjectSP child_sp; 661 if (m_opaque_sp) 662 { 663 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 664 { 665 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 666 // using default values for all the fancy options, just do it if you can 667 child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path); 668 } 669 } 670 671 SBValue sb_value (child_sp); 672 673 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 674 if (log) 675 log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get()); 676 677 return sb_value; 678 } 679 680 int64_t 681 SBValue::GetValueAsSigned(SBError& error, int64_t fail_value) 682 { 683 error.Clear(); 684 if (m_opaque_sp) 685 { 686 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 687 { 688 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 689 Scalar scalar; 690 if (m_opaque_sp->ResolveValue (scalar)) 691 return scalar.GetRawBits64(fail_value); 692 else 693 error.SetErrorString("could not get value"); 694 } 695 else 696 error.SetErrorString("could not get target"); 697 } 698 error.SetErrorString("invalid SBValue"); 699 return fail_value; 700 } 701 702 uint64_t 703 SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value) 704 { 705 error.Clear(); 706 if (m_opaque_sp) 707 { 708 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 709 { 710 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 711 Scalar scalar; 712 if (m_opaque_sp->ResolveValue (scalar)) 713 return scalar.GetRawBits64(fail_value); 714 else 715 error.SetErrorString("could not get value"); 716 } 717 else 718 error.SetErrorString("could not get target"); 719 } 720 error.SetErrorString("invalid SBValue"); 721 return fail_value; 722 } 723 724 int64_t 725 SBValue::GetValueAsSigned(int64_t fail_value) 726 { 727 if (m_opaque_sp) 728 { 729 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 730 { 731 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 732 Scalar scalar; 733 if (m_opaque_sp->ResolveValue (scalar)) 734 return scalar.GetRawBits64(fail_value); 735 } 736 } 737 return fail_value; 738 } 739 740 uint64_t 741 SBValue::GetValueAsUnsigned(uint64_t fail_value) 742 { 743 if (m_opaque_sp) 744 { 745 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 746 { 747 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 748 Scalar scalar; 749 if (m_opaque_sp->ResolveValue (scalar)) 750 return scalar.GetRawBits64(fail_value); 751 } 752 } 753 return fail_value; 754 } 755 756 uint32_t 757 SBValue::GetNumChildren () 758 { 759 uint32_t num_children = 0; 760 761 if (m_opaque_sp) 762 { 763 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 764 { 765 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 766 767 num_children = m_opaque_sp->GetNumChildren(); 768 } 769 } 770 771 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 772 if (log) 773 log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); 774 775 return num_children; 776 } 777 778 779 SBValue 780 SBValue::Dereference () 781 { 782 SBValue sb_value; 783 if (m_opaque_sp) 784 { 785 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 786 { 787 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 788 789 Error error; 790 sb_value = m_opaque_sp->Dereference (error); 791 } 792 } 793 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 794 if (log) 795 log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 796 797 return sb_value; 798 } 799 800 bool 801 SBValue::TypeIsPointerType () 802 { 803 bool is_ptr_type = false; 804 805 if (m_opaque_sp) 806 { 807 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 808 { 809 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 810 811 is_ptr_type = m_opaque_sp->IsPointerType(); 812 } 813 } 814 815 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 816 if (log) 817 log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); 818 819 820 return is_ptr_type; 821 } 822 823 void * 824 SBValue::GetOpaqueType() 825 { 826 if (m_opaque_sp) 827 { 828 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 829 { 830 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 831 832 return m_opaque_sp->GetClangType(); 833 } 834 } 835 return NULL; 836 } 837 838 lldb::SBTarget 839 SBValue::GetTarget() 840 { 841 SBTarget sb_target; 842 TargetSP target_sp; 843 if (m_opaque_sp) 844 { 845 target_sp = m_opaque_sp->GetUpdatePoint().GetTargetSP(); 846 sb_target.SetSP (target_sp); 847 } 848 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 849 if (log) 850 { 851 if (target_sp.get() == NULL) 852 log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); 853 else 854 log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), target_sp.get()); 855 } 856 return sb_target; 857 } 858 859 lldb::SBProcess 860 SBValue::GetProcess() 861 { 862 SBProcess sb_process; 863 ProcessSP process_sp; 864 if (m_opaque_sp) 865 { 866 process_sp = m_opaque_sp->GetUpdatePoint().GetProcessSP(); 867 if (process_sp) 868 sb_process.SetSP (process_sp); 869 } 870 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 871 if (log) 872 { 873 if (process_sp.get() == NULL) 874 log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get()); 875 else 876 log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), process_sp.get()); 877 } 878 return sb_process; 879 } 880 881 lldb::SBThread 882 SBValue::GetThread() 883 { 884 SBThread sb_thread; 885 ThreadSP thread_sp; 886 if (m_opaque_sp) 887 { 888 if (m_opaque_sp->GetExecutionContextScope()) 889 { 890 thread_sp = m_opaque_sp->GetExecutionContextScope()->CalculateThread()->shared_from_this(); 891 sb_thread.SetThread(thread_sp); 892 } 893 } 894 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 895 if (log) 896 { 897 if (thread_sp.get() == NULL) 898 log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get()); 899 else 900 log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), thread_sp.get()); 901 } 902 return sb_thread; 903 } 904 905 lldb::SBFrame 906 SBValue::GetFrame() 907 { 908 SBFrame sb_frame; 909 StackFrameSP frame_sp; 910 if (m_opaque_sp) 911 { 912 if (m_opaque_sp->GetExecutionContextScope()) 913 { 914 frame_sp = m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame()->shared_from_this(); 915 sb_frame.SetFrameSP (frame_sp); 916 } 917 } 918 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 919 if (log) 920 { 921 if (frame_sp.get() == NULL) 922 log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get()); 923 else 924 log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), frame_sp.get()); 925 } 926 return sb_frame; 927 } 928 929 930 // Mimic shared pointer... 931 lldb_private::ValueObject * 932 SBValue::get() const 933 { 934 return m_opaque_sp.get(); 935 } 936 937 lldb_private::ValueObject * 938 SBValue::operator->() const 939 { 940 return m_opaque_sp.get(); 941 } 942 943 lldb::ValueObjectSP & 944 SBValue::operator*() 945 { 946 return m_opaque_sp; 947 } 948 949 const lldb::ValueObjectSP & 950 SBValue::operator*() const 951 { 952 return m_opaque_sp; 953 } 954 955 bool 956 SBValue::GetExpressionPath (SBStream &description) 957 { 958 if (m_opaque_sp) 959 { 960 m_opaque_sp->GetExpressionPath (description.ref(), false); 961 return true; 962 } 963 return false; 964 } 965 966 bool 967 SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) 968 { 969 if (m_opaque_sp) 970 { 971 m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); 972 return true; 973 } 974 return false; 975 } 976 977 bool 978 SBValue::GetDescription (SBStream &description) 979 { 980 Stream &strm = description.ref(); 981 982 if (m_opaque_sp) 983 { 984 ValueObject::DumpValueObject (strm, m_opaque_sp.get()); 985 } 986 else 987 strm.PutCString ("No value"); 988 989 return true; 990 } 991 992 lldb::Format 993 SBValue::GetFormat () 994 { 995 if (m_opaque_sp) 996 return m_opaque_sp->GetFormat(); 997 return eFormatDefault; 998 } 999 1000 void 1001 SBValue::SetFormat (lldb::Format format) 1002 { 1003 if (m_opaque_sp) 1004 m_opaque_sp->SetFormat(format); 1005 } 1006 1007 lldb::SBValue 1008 SBValue::AddressOf() 1009 { 1010 SBValue sb_value; 1011 if (m_opaque_sp) 1012 { 1013 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1014 if (target) 1015 { 1016 Mutex::Locker api_locker (target->GetAPIMutex()); 1017 Error error; 1018 sb_value = m_opaque_sp->AddressOf (error); 1019 } 1020 } 1021 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1022 if (log) 1023 log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 1024 1025 return sb_value; 1026 } 1027 1028 lldb::addr_t 1029 SBValue::GetLoadAddress() 1030 { 1031 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1032 if (m_opaque_sp) 1033 { 1034 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1035 if (target) 1036 { 1037 Mutex::Locker api_locker (target->GetAPIMutex()); 1038 const bool scalar_is_load_address = true; 1039 AddressType addr_type; 1040 value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1041 if (addr_type == eAddressTypeFile) 1042 { 1043 Module* module = m_opaque_sp->GetModule(); 1044 if (!module) 1045 value = LLDB_INVALID_ADDRESS; 1046 else 1047 { 1048 Address addr; 1049 module->ResolveFileAddress(value, addr); 1050 value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get()); 1051 } 1052 } 1053 else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid) 1054 value = LLDB_INVALID_ADDRESS; 1055 } 1056 } 1057 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1058 if (log) 1059 log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value); 1060 1061 return value; 1062 } 1063 1064 lldb::SBAddress 1065 SBValue::GetAddress() 1066 { 1067 Address addr; 1068 if (m_opaque_sp) 1069 { 1070 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1071 if (target) 1072 { 1073 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1074 Mutex::Locker api_locker (target->GetAPIMutex()); 1075 const bool scalar_is_load_address = true; 1076 AddressType addr_type; 1077 value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1078 if (addr_type == eAddressTypeFile) 1079 { 1080 Module* module = m_opaque_sp->GetModule(); 1081 if (module) 1082 module->ResolveFileAddress(value, addr); 1083 } 1084 else if (addr_type == eAddressTypeLoad) 1085 { 1086 // no need to check the return value on this.. if it can actually do the resolve 1087 // addr will be in the form (section,offset), otherwise it will simply be returned 1088 // as (NULL, value) 1089 addr.SetLoadAddress(value, target); 1090 } 1091 } 1092 } 1093 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1094 if (log) 1095 log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset()); 1096 return SBAddress(new Address(addr)); 1097 } 1098 1099 lldb::SBData 1100 SBValue::GetPointeeData (uint32_t item_idx, 1101 uint32_t item_count) 1102 { 1103 lldb::SBData sb_data; 1104 if (m_opaque_sp) 1105 { 1106 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1107 if (target) 1108 { 1109 DataExtractorSP data_sp(new DataExtractor()); 1110 Mutex::Locker api_locker (target->GetAPIMutex()); 1111 m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count); 1112 if (data_sp->GetByteSize() > 0) 1113 *sb_data = data_sp; 1114 } 1115 } 1116 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1117 if (log) 1118 log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", 1119 m_opaque_sp.get(), 1120 item_idx, 1121 item_count, 1122 sb_data.get()); 1123 1124 return sb_data; 1125 } 1126 1127 lldb::SBData 1128 SBValue::GetData () 1129 { 1130 lldb::SBData sb_data; 1131 if (m_opaque_sp) 1132 { 1133 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1134 if (target) 1135 { 1136 DataExtractorSP data_sp(new DataExtractor()); 1137 Mutex::Locker api_locker (target->GetAPIMutex()); 1138 m_opaque_sp->GetData(*data_sp); 1139 if (data_sp->GetByteSize() > 0) 1140 *sb_data = data_sp; 1141 } 1142 } 1143 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1144 if (log) 1145 log->Printf ("SBValue(%p)::GetData () => SBData(%p)", 1146 m_opaque_sp.get(), 1147 sb_data.get()); 1148 1149 return sb_data; 1150 } 1151 1152 lldb::SBWatchpoint 1153 SBValue::Watch (bool resolve_location, bool read, bool write) 1154 { 1155 lldb::SBWatchpoint sb_watchpoint; 1156 if (!m_opaque_sp) 1157 return sb_watchpoint; 1158 1159 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1160 if (target) 1161 { 1162 Mutex::Locker api_locker (target->GetAPIMutex()); 1163 sb_watchpoint = WatchValue(read, write, false); 1164 } 1165 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1166 if (log) 1167 log->Printf ("SBValue(%p)::Watch (resolve_location=%i, read=%i, write=%i) => wp(%p)", 1168 m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get()); 1169 return sb_watchpoint; 1170 } 1171 1172 lldb::SBWatchpoint 1173 SBValue::WatchPointee (bool resolve_location, bool read, bool write) 1174 { 1175 lldb::SBWatchpoint sb_watchpoint; 1176 if (!m_opaque_sp) 1177 return sb_watchpoint; 1178 1179 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1180 if (target) 1181 { 1182 Mutex::Locker api_locker (target->GetAPIMutex()); 1183 sb_watchpoint = WatchValue(read, write, true); 1184 } 1185 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1186 if (log) 1187 log->Printf ("SBValue(%p)::WatchPointee (resolve_location=%i, read=%i, write=%i) => wp(%p)", 1188 m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get()); 1189 return sb_watchpoint; 1190 } 1191 1192 // Helper function for SBValue::Watch() and SBValue::WatchPointee(). 1193 SBWatchpoint 1194 SBValue::WatchValue(bool read, bool write, bool watch_pointee) 1195 { 1196 SBWatchpoint sb_wp_empty; 1197 1198 // If the SBValue is not valid, there's no point in even trying to watch it. 1199 if (!IsValid()) 1200 return sb_wp_empty; 1201 1202 // Read and Write cannot both be false. 1203 if (!read && !write) 1204 return sb_wp_empty; 1205 1206 // If we are watching the pointee, check that the SBValue is a pointer type. 1207 if (watch_pointee && !GetType().IsPointerType()) 1208 return sb_wp_empty; 1209 1210 TargetSP target_sp (GetTarget().GetSP()); 1211 if (!target_sp) 1212 return sb_wp_empty; 1213 1214 StackFrameSP frame_sp (GetFrame().GetFrameSP()); 1215 if (!frame_sp) 1216 return sb_wp_empty; 1217 1218 addr_t addr; 1219 size_t size; 1220 if (watch_pointee) { 1221 addr = GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 1222 size = GetType().GetPointeeType().GetByteSize(); 1223 } else { 1224 addr = GetLoadAddress(); 1225 size = GetByteSize(); 1226 } 1227 1228 // Sanity check the address and the size before calling Target::CreateWatchpoint(). 1229 if (addr == LLDB_INVALID_ADDRESS || size == 0) 1230 return sb_wp_empty; 1231 1232 uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) | 1233 (write ? LLDB_WATCH_TYPE_WRITE : 0); 1234 WatchpointSP wp_sp = target_sp->CreateWatchpoint(addr, size, watch_type); 1235 1236 if (wp_sp) { 1237 // StackFrame::GetInScopeVariableList(true) to get file globals as well. 1238 VariableListSP var_list_sp(frame_sp->GetInScopeVariableList(true)); 1239 VariableSP var_sp = var_list_sp->FindVariable(ConstString(GetName())); 1240 if (var_sp && var_sp->GetDeclaration().GetFile()) { 1241 StreamString ss; 1242 // True to show fullpath for declaration file. 1243 var_sp->GetDeclaration().DumpStopContext(&ss, true); 1244 wp_sp->SetDeclInfo(ss.GetString()); 1245 } 1246 } 1247 return wp_sp; 1248 } 1249 1250