//===-- SBValue.cpp ---------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "lldb/API/SBValue.h" #include "lldb/API/SBStream.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBDebugger.h" using namespace lldb; using namespace lldb_private; SBValue::SBValue () : m_opaque_sp () { } SBValue::SBValue (const lldb::ValueObjectSP &value_sp) : m_opaque_sp (value_sp) { } SBValue::SBValue(const SBValue &rhs) : m_opaque_sp (rhs.m_opaque_sp) { } SBValue & SBValue::operator = (const SBValue &rhs) { if (this != &rhs) m_opaque_sp = rhs.m_opaque_sp; return *this; } SBValue::~SBValue() { } bool SBValue::IsValid () { // If this function ever changes to anything that does more than just // check if the opaque shared pointer is non NULL, then we need to update // all "if (m_opaque_sp)" code in this file. return m_opaque_sp.get() != NULL; } SBError SBValue::GetError() { SBError sb_error; if (m_opaque_sp.get()) sb_error.SetError(m_opaque_sp->GetError()); return sb_error; } user_id_t SBValue::GetID() { if (m_opaque_sp) return m_opaque_sp->GetID(); return LLDB_INVALID_UID; } const char * SBValue::GetName() { const char *name = NULL; if (m_opaque_sp) name = m_opaque_sp->GetName().GetCString(); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (name) log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name); else log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get()); } return name; } const char * SBValue::GetTypeName () { const char *name = NULL; if (m_opaque_sp) name = m_opaque_sp->GetTypeName().GetCString(); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (name) log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name); else log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get()); } return name; } size_t SBValue::GetByteSize () { size_t result = 0; if (m_opaque_sp) result = m_opaque_sp->GetByteSize(); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result); return result; } bool SBValue::IsInScope () { bool result = false; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); result = m_opaque_sp->IsInScope (); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result); return result; } const char * SBValue::GetValue () { const char *cstr = NULL; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); cstr = m_opaque_sp->GetValueAsCString (); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (cstr) log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr); else log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get()); } return cstr; } ValueType SBValue::GetValueType () { ValueType result = eValueTypeInvalid; if (m_opaque_sp) result = m_opaque_sp->GetValueType(); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { switch (result) { case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break; case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break; case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break; case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break; case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break; case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break; case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break; case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break; default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break; } } return result; } const char * SBValue::GetObjectDescription () { const char *cstr = NULL; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); cstr = m_opaque_sp->GetObjectDescription (); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (cstr) log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr); else log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get()); } return cstr; } SBType SBValue::GetType() { SBType result; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); result = SBType(ClangASTType (m_opaque_sp->GetClangAST(), m_opaque_sp->GetClangType())); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.IsValid()) log->Printf ("SBValue(%p)::GetType => %p", m_opaque_sp.get(), &result); else log->Printf ("SBValue(%p)::GetType => NULL", m_opaque_sp.get()); } return result; } bool SBValue::GetValueDidChange () { bool result = false; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); result = m_opaque_sp->GetValueDidChange (); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result); return result; } const char * SBValue::GetSummary () { const char *cstr = NULL; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); cstr = m_opaque_sp->GetSummaryAsCString(); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (cstr) log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); else log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); } return cstr; } const char * SBValue::GetLocation () { const char *cstr = NULL; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); cstr = m_opaque_sp->GetLocationAsCString(); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (cstr) log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); else log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); } return cstr; } bool SBValue::SetValueFromCString (const char *value_str) { bool success = false; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); success = m_opaque_sp->SetValueFromCString (value_str); } } return success; } lldb::SBValue SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) { lldb::SBValue result; if (m_opaque_sp) { if (type.IsValid()) { result = SBValue(m_opaque_sp->GetSyntheticChildAtOffset(offset, type.m_opaque_sp->GetClangASTType(), true)); result.m_opaque_sp->SetName(ConstString(name)); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.IsValid()) log->Printf ("SBValue(%p)::GetChildAtOffset => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); else log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", m_opaque_sp.get()); } return result; } lldb::SBValue SBValue::Cast (SBType type) { return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type); } lldb::SBValue SBValue::CreateValueFromExpression (const char *name, const char* expression) { lldb::SBValue result; if (m_opaque_sp) { ValueObjectSP result_valobj_sp; m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression, m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(), eExecutionPolicyOnlyWhenNeeded, true, // unwind on error true, // keep in memory eNoDynamicValues, result_valobj_sp); result_valobj_sp->SetName(ConstString(name)); result = SBValue(result_valobj_sp); } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.IsValid()) log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); else log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); } return result; } lldb::SBValue SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type) { lldb::SBValue result; if (m_opaque_sp) { SBType real_type(type.GetPointerType()); lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(), real_type.m_opaque_sp->GetASTContext(), real_type.m_opaque_sp->GetOpaqueQualType(), ConstString(name), buffer, lldb::endian::InlHostByteOrder(), GetTarget().GetProcess().GetAddressByteSize())); ValueObjectSP result_valobj_sp; ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); if (ptr_result_valobj_sp) { Error err; result_valobj_sp = ptr_result_valobj_sp->Dereference(err); if (result_valobj_sp) result_valobj_sp->SetName(ConstString(name)); } result = SBValue(result_valobj_sp); } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.IsValid()) log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); else log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get()); } return result; } lldb::SBValue SBValue::CreateValueFromData (const char* name, SBData data, SBType type) { SBValue result; AddressType addr_of_children_priv = eAddressTypeLoad; if (m_opaque_sp) { ValueObjectSP valobj_sp; valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(), type.m_opaque_sp->GetASTContext() , type.m_opaque_sp->GetOpaqueQualType(), ConstString(name), *data.m_opaque_sp, LLDB_INVALID_ADDRESS); valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv); result = SBValue(valobj_sp); } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.IsValid()) log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); else log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); } return result; } SBValue SBValue::GetChildAtIndex (uint32_t idx) { const bool can_create_synthetic = false; lldb::DynamicValueType use_dynamic = eNoDynamicValues; if (m_opaque_sp) use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue(); return GetChildAtIndex (idx, use_dynamic, can_create_synthetic); } SBValue SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic) { lldb::ValueObjectSP child_sp; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); const bool can_create = true; child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create); if (can_create_synthetic && !child_sp) { if (m_opaque_sp->IsPointerType()) { child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create); } else if (m_opaque_sp->IsArrayType()) { child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create); } } if (child_sp) { if (use_dynamic != lldb::eNoDynamicValues) { lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic)); if (dynamic_sp) child_sp = dynamic_sp; } } } } SBValue sb_value (child_sp); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); return sb_value; } uint32_t SBValue::GetIndexOfChildWithName (const char *name) { uint32_t idx = UINT32_MAX; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (idx == UINT32_MAX) log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name); else log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); } return idx; } SBValue SBValue::GetChildMemberWithName (const char *name) { if (m_opaque_sp) { lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue(); return GetChildMemberWithName (name, use_dynamic_value); } else return GetChildMemberWithName (name, eNoDynamicValues); } SBValue SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) { lldb::ValueObjectSP child_sp; const ConstString str_name (name); if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); if (use_dynamic_value != lldb::eNoDynamicValues) { if (child_sp) { lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); if (dynamic_sp) child_sp = dynamic_sp; } } } } SBValue sb_value (child_sp); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); return sb_value; } lldb::SBValue SBValue::GetValueForExpressionPath(const char* expr_path) { lldb::ValueObjectSP child_sp; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); // using default values for all the fancy options, just do it if you can child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path); } } SBValue sb_value (child_sp); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get()); return sb_value; } int64_t SBValue::GetValueAsSigned(SBError& error, int64_t fail_value) { error.Clear(); if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); Scalar scalar; if (m_opaque_sp->ResolveValue (scalar)) return scalar.GetRawBits64(fail_value); else error.SetErrorString("could not get value"); } else error.SetErrorString("could not get target"); } error.SetErrorString("invalid SBValue"); return fail_value; } uint64_t SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value) { error.Clear(); if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); Scalar scalar; if (m_opaque_sp->ResolveValue (scalar)) return scalar.GetRawBits64(fail_value); else error.SetErrorString("could not get value"); } else error.SetErrorString("could not get target"); } error.SetErrorString("invalid SBValue"); return fail_value; } int64_t SBValue::GetValueAsSigned(int64_t fail_value) { if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); Scalar scalar; if (m_opaque_sp->ResolveValue (scalar)) return scalar.GetRawBits64(fail_value); } } return fail_value; } uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) { if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); Scalar scalar; if (m_opaque_sp->ResolveValue (scalar)) return scalar.GetRawBits64(fail_value); } } return fail_value; } uint32_t SBValue::GetNumChildren () { uint32_t num_children = 0; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); num_children = m_opaque_sp->GetNumChildren(); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); return num_children; } SBValue SBValue::Dereference () { SBValue sb_value; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); Error error; sb_value = m_opaque_sp->Dereference (error); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); return sb_value; } bool SBValue::TypeIsPointerType () { bool is_ptr_type = false; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); is_ptr_type = m_opaque_sp->IsPointerType(); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); return is_ptr_type; } void * SBValue::GetOpaqueType() { if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); return m_opaque_sp->GetClangType(); } } return NULL; } lldb::SBTarget SBValue::GetTarget() { SBTarget result; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP())); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.get() == NULL) log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); else log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get()); } return result; } lldb::SBProcess SBValue::GetProcess() { SBProcess result; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { result = SBProcess(lldb::ProcessSP(target->GetProcessSP())); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.get() == NULL) log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get()); else log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get()); } return result; } lldb::SBThread SBValue::GetThread() { SBThread result; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()) { result = SBThread(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()->GetSP()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.get() == NULL) log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get()); else log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), result.get()); } return result; } lldb::SBFrame SBValue::GetFrame() { SBFrame result; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()) { result.SetFrame (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()->GetSP()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.get() == NULL) log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get()); else log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get()); } return result; } // Mimic shared pointer... lldb_private::ValueObject * SBValue::get() const { return m_opaque_sp.get(); } lldb_private::ValueObject * SBValue::operator->() const { return m_opaque_sp.get(); } lldb::ValueObjectSP & SBValue::operator*() { return m_opaque_sp; } const lldb::ValueObjectSP & SBValue::operator*() const { return m_opaque_sp; } bool SBValue::GetExpressionPath (SBStream &description) { if (m_opaque_sp) { m_opaque_sp->GetExpressionPath (description.ref(), false); return true; } return false; } bool SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) { if (m_opaque_sp) { m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); return true; } return false; } bool SBValue::GetDescription (SBStream &description) { Stream &strm = description.ref(); if (m_opaque_sp) { ValueObject::DumpValueObject (strm, m_opaque_sp.get()); } else strm.PutCString ("No value"); return true; } lldb::Format SBValue::GetFormat () { if (m_opaque_sp) return m_opaque_sp->GetFormat(); return eFormatDefault; } void SBValue::SetFormat (lldb::Format format) { if (m_opaque_sp) m_opaque_sp->SetFormat(format); } lldb::SBValue SBValue::AddressOf() { SBValue sb_value; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { Mutex::Locker api_locker (target->GetAPIMutex()); Error error; sb_value = m_opaque_sp->AddressOf (error); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); return sb_value; } lldb::addr_t SBValue::GetLoadAddress() { lldb::addr_t value = LLDB_INVALID_ADDRESS; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { Mutex::Locker api_locker (target->GetAPIMutex()); const bool scalar_is_load_address = true; AddressType addr_type; value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); if (addr_type == eAddressTypeFile) { Module* module = m_opaque_sp->GetModule(); if (!module) value = LLDB_INVALID_ADDRESS; else { Address addr; module->ResolveFileAddress(value, addr); value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get()); } } else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid) value = LLDB_INVALID_ADDRESS; } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value); return value; } lldb::SBAddress SBValue::GetAddress() { Address addr; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { lldb::addr_t value = LLDB_INVALID_ADDRESS; Mutex::Locker api_locker (target->GetAPIMutex()); const bool scalar_is_load_address = true; AddressType addr_type; value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); if (addr_type == eAddressTypeFile) { Module* module = m_opaque_sp->GetModule(); if (module) module->ResolveFileAddress(value, addr); } else if (addr_type == eAddressTypeLoad) { // no need to check the return value on this.. if it can actually do the resolve // addr will be in the form (section,offset), otherwise it will simply be returned // as (NULL, value) addr.SetLoadAddress(value, target); } } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset()); return SBAddress(new Address(addr)); } lldb::SBData SBValue::GetPointeeData (uint32_t item_idx, uint32_t item_count) { lldb::SBData sb_data; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { DataExtractorSP data_sp(new DataExtractor()); Mutex::Locker api_locker (target->GetAPIMutex()); m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count); if (data_sp->GetByteSize() > 0) *sb_data = data_sp; } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", m_opaque_sp.get(), item_idx, item_count, sb_data.get()); return sb_data; } lldb::SBData SBValue::GetData () { lldb::SBData sb_data; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { DataExtractorSP data_sp(new DataExtractor()); Mutex::Locker api_locker (target->GetAPIMutex()); m_opaque_sp->GetData(*data_sp); if (data_sp->GetByteSize() > 0) *sb_data = data_sp; } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetData () => SBData(%p)", m_opaque_sp.get(), sb_data.get()); return sb_data; } lldb::SBWatchpoint SBValue::Watch (bool resolve_location, bool read, bool write) { lldb::SBWatchpoint sb_watchpoint; if (!m_opaque_sp) return sb_watchpoint; Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { Mutex::Locker api_locker (target->GetAPIMutex()); sb_watchpoint = WatchValue(read, write, false); } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::Watch (resolve_location=%i, read=%i, write=%i) => wp(%p)", m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get()); return sb_watchpoint; } lldb::SBWatchpoint SBValue::WatchPointee (bool resolve_location, bool read, bool write) { lldb::SBWatchpoint sb_watchpoint; if (!m_opaque_sp) return sb_watchpoint; Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { Mutex::Locker api_locker (target->GetAPIMutex()); sb_watchpoint = WatchValue(read, write, true); } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::WatchPointee (resolve_location=%i, read=%i, write=%i) => wp(%p)", m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get()); return sb_watchpoint; } // Helper function for SBValue::Watch() and SBValue::WatchPointee(). SBWatchpoint SBValue::WatchValue(bool read, bool write, bool watch_pointee) { SBWatchpoint sb_wp_empty; // If the SBValue is not valid, there's no point in even trying to watch it. if (!IsValid() || !GetFrame().IsValid()) return sb_wp_empty; // Read and Write cannot both be false. if (!read && !write) return sb_wp_empty; // If we are watching the pointee, check that the SBValue is a pointer type. if (watch_pointee && !GetType().IsPointerType()) return sb_wp_empty; addr_t addr; size_t size; if (watch_pointee) { addr = GetValueAsUnsigned(LLDB_INVALID_ADDRESS); size = GetType().GetPointeeType().GetByteSize(); } else { addr = GetLoadAddress(); size = GetByteSize(); } // Sanity check the address and the size before calling Target::CreateWatchpoint(). if (addr == LLDB_INVALID_ADDRESS || size == 0) return sb_wp_empty; uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) | (write ? LLDB_WATCH_TYPE_WRITE : 0); WatchpointSP wp_sp = GetFrame().m_opaque_sp->GetThread().GetProcess().GetTarget(). CreateWatchpoint(addr, size, watch_type); if (wp_sp) { // StackFrame::GetInScopeVariableList(true) to get file globals as well. VariableListSP var_list_sp(GetFrame().m_opaque_sp->GetInScopeVariableList(true)); VariableSP var_sp = var_list_sp->FindVariable(ConstString(GetName())); if (var_sp && var_sp->GetDeclaration().GetFile()) { StreamString ss; // True to show fullpath for declaration file. var_sp->GetDeclaration().DumpStopContext(&ss, true); wp_sp->SetDeclInfo(ss.GetString()); } } return wp_sp; }