aboutsummaryrefslogtreecommitdiff
path: root/source/Core/ValueObjectRegister.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Core/ValueObjectRegister.cpp')
-rw-r--r--source/Core/ValueObjectRegister.cpp431
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 &reg_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 &reg_ctx_sp, uint32_t set_idx)
+{
+ return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
+}
+
+
+ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_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 &reg_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 &reg_ctx_sp, uint32_t reg_num)
+{
+ return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
+}
+
+ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_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);
+}
+
+