diff options
Diffstat (limited to 'source/Core/ValueObjectRegister.cpp')
-rw-r--r-- | source/Core/ValueObjectRegister.cpp | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp new file mode 100644 index 000000000000..4f21457519ec --- /dev/null +++ b/source/Core/ValueObjectRegister.cpp @@ -0,0 +1,431 @@ +//===-- ValueObjectRegister.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/Core/ValueObjectRegister.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Module.h" +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +#pragma mark ValueObjectRegisterContext + +ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP ®_ctx) : + ValueObject (parent), + m_reg_ctx_sp (reg_ctx) +{ + assert (reg_ctx); + m_name.SetCString("Registers"); + SetValueIsValid (true); +} + +ValueObjectRegisterContext::~ValueObjectRegisterContext() +{ +} + +ClangASTType +ValueObjectRegisterContext::GetClangTypeImpl () +{ + return ClangASTType(); +} + +ConstString +ValueObjectRegisterContext::GetTypeName() +{ + return ConstString(); +} + +ConstString +ValueObjectRegisterContext::GetQualifiedTypeName() +{ + return ConstString(); +} + +size_t +ValueObjectRegisterContext::CalculateNumChildren() +{ + return m_reg_ctx_sp->GetRegisterSetCount(); +} + +uint64_t +ValueObjectRegisterContext::GetByteSize() +{ + return 0; +} + +bool +ValueObjectRegisterContext::UpdateValue () +{ + m_error.Clear(); + ExecutionContext exe_ctx(GetExecutionContextRef()); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame) + m_reg_ctx_sp = frame->GetRegisterContext(); + else + m_reg_ctx_sp.reset(); + + if (m_reg_ctx_sp.get() == NULL) + { + SetValueIsValid (false); + m_error.SetErrorToGenericError(); + } + else + SetValueIsValid (true); + + return m_error.Success(); +} + +ValueObject * +ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index) +{ + ValueObject *new_valobj = NULL; + + const size_t num_children = GetNumChildren(); + if (idx < num_children) + { + ExecutionContext exe_ctx(GetExecutionContextRef()); + new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx); + } + + return new_valobj; +} + + +#pragma mark - +#pragma mark ValueObjectRegisterSet + +ValueObjectSP +ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx) +{ + return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP(); +} + + +ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_set_idx) : + ValueObject (exe_scope), + m_reg_ctx_sp (reg_ctx), + m_reg_set (NULL), + m_reg_set_idx (reg_set_idx) +{ + assert (reg_ctx); + m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx); + if (m_reg_set) + { + m_name.SetCString (m_reg_set->name); + } +} + +ValueObjectRegisterSet::~ValueObjectRegisterSet() +{ +} + +ClangASTType +ValueObjectRegisterSet::GetClangTypeImpl () +{ + return ClangASTType(); +} + +ConstString +ValueObjectRegisterSet::GetTypeName() +{ + return ConstString(); +} + +ConstString +ValueObjectRegisterSet::GetQualifiedTypeName() +{ + return ConstString(); +} + +size_t +ValueObjectRegisterSet::CalculateNumChildren() +{ + const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx); + if (reg_set) + return reg_set->num_registers; + return 0; +} + +uint64_t +ValueObjectRegisterSet::GetByteSize() +{ + return 0; +} + +bool +ValueObjectRegisterSet::UpdateValue () +{ + m_error.Clear(); + SetValueDidChange (false); + ExecutionContext exe_ctx(GetExecutionContextRef()); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame == NULL) + m_reg_ctx_sp.reset(); + else + { + m_reg_ctx_sp = frame->GetRegisterContext (); + if (m_reg_ctx_sp) + { + const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx); + if (reg_set == NULL) + m_reg_ctx_sp.reset(); + else if (m_reg_set != reg_set) + { + SetValueDidChange (true); + m_name.SetCString(reg_set->name); + } + } + } + if (m_reg_ctx_sp) + { + SetValueIsValid (true); + } + else + { + SetValueIsValid (false); + m_error.SetErrorToGenericError (); + m_children.Clear(); + } + return m_error.Success(); +} + + +ValueObject * +ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index) +{ + ValueObject *valobj = NULL; + if (m_reg_ctx_sp && m_reg_set) + { + const size_t num_children = GetNumChildren(); + if (idx < num_children) + valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]); + } + return valobj; +} + +lldb::ValueObjectSP +ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create) +{ + ValueObject *valobj = NULL; + if (m_reg_ctx_sp && m_reg_set) + { + const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString()); + if (reg_info != NULL) + valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]); + } + if (valobj) + return valobj->GetSP(); + else + return ValueObjectSP(); +} + +size_t +ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name) +{ + if (m_reg_ctx_sp && m_reg_set) + { + const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString()); + if (reg_info != NULL) + return reg_info->kinds[eRegisterKindLLDB]; + } + return UINT32_MAX; +} + +#pragma mark - +#pragma mark ValueObjectRegister + +void +ValueObjectRegister::ConstructObject (uint32_t reg_num) +{ + const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num); + if (reg_info) + { + m_reg_info = *reg_info; + if (reg_info->name) + m_name.SetCString(reg_info->name); + else if (reg_info->alt_name) + m_name.SetCString(reg_info->alt_name); + } +} + +ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) : + ValueObject (parent), + m_reg_ctx_sp (reg_ctx_sp), + m_reg_info (), + m_reg_value (), + m_type_name (), + m_clang_type () +{ + assert (reg_ctx_sp.get()); + ConstructObject(reg_num); +} + +ValueObjectSP +ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) +{ + return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP(); +} + +ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) : + ValueObject (exe_scope), + m_reg_ctx_sp (reg_ctx), + m_reg_info (), + m_reg_value (), + m_type_name (), + m_clang_type () +{ + assert (reg_ctx); + ConstructObject(reg_num); +} + +ValueObjectRegister::~ValueObjectRegister() +{ +} + +ClangASTType +ValueObjectRegister::GetClangTypeImpl () +{ + if (!m_clang_type.IsValid()) + { + ExecutionContext exe_ctx (GetExecutionContextRef()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) + { + Module *exe_module = target->GetExecutableModulePointer(); + if (exe_module) + { + m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding, + m_reg_info.byte_size * 8); + } + } + } + return m_clang_type; +} + +ConstString +ValueObjectRegister::GetTypeName() +{ + if (m_type_name.IsEmpty()) + m_type_name = GetClangType().GetConstTypeName (); + return m_type_name; +} + +size_t +ValueObjectRegister::CalculateNumChildren() +{ + return GetClangType().GetNumChildren(true); +} + +uint64_t +ValueObjectRegister::GetByteSize() +{ + return m_reg_info.byte_size; +} + +bool +ValueObjectRegister::UpdateValue () +{ + m_error.Clear(); + ExecutionContext exe_ctx(GetExecutionContextRef()); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame == NULL) + { + m_reg_ctx_sp.reset(); + m_reg_value.Clear(); + } + + + if (m_reg_ctx_sp) + { + if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value)) + { + if (m_reg_value.GetData (m_data)) + { + Process *process = exe_ctx.GetProcessPtr(); + if (process) + m_data.SetAddressByteSize(process->GetAddressByteSize()); + m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info); + m_value.SetValueType(Value::eValueTypeHostAddress); + m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); + SetValueIsValid (true); + return true; + } + } + } + + SetValueIsValid (false); + m_error.SetErrorToGenericError (); + return false; +} + +bool +ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error) +{ + // The new value will be in the m_data. Copy that into our register value. + error = m_reg_value.SetValueFromCString (&m_reg_info, value_str); + if (error.Success()) + { + if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value)) + { + SetNeedsUpdate(); + return true; + } + else + return false; + } + else + return false; +} + +bool +ValueObjectRegister::SetData (DataExtractor &data, Error &error) +{ + error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false); + if (error.Success()) + { + if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value)) + { + SetNeedsUpdate(); + return true; + } + else + return false; + } + else + return false; +} + +bool +ValueObjectRegister::ResolveValue (Scalar &scalar) +{ + if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything + return m_reg_value.GetScalarValue(scalar); + return false; +} + +void +ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) +{ + s.Printf("$%s", m_reg_info.name); +} + + |