aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/Utility/RegisterContextMemory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/Utility/RegisterContextMemory.cpp')
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
new file mode 100644
index 000000000000..8c33a6814acc
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -0,0 +1,174 @@
+//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextMemory.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "DynamicRegisterInfo.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// RegisterContextMemory constructor
+//----------------------------------------------------------------------
+RegisterContextMemory::RegisterContextMemory
+(
+ Thread &thread,
+ uint32_t concrete_frame_idx,
+ DynamicRegisterInfo &reg_infos,
+ addr_t reg_data_addr
+) :
+ RegisterContext (thread, concrete_frame_idx),
+ m_reg_infos (reg_infos),
+ m_reg_valid (),
+ m_reg_data (),
+ m_reg_data_addr (reg_data_addr)
+{
+ // Resize our vector of bools to contain one bool for every register.
+ // We will use these boolean values to know when a register value
+ // is valid in m_reg_data.
+ const size_t num_regs = reg_infos.GetNumRegisters();
+ assert (num_regs > 0);
+ m_reg_valid.resize (num_regs);
+
+ // Make a heap based buffer that is big enough to store all registers
+ DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0));
+ m_reg_data.SetData (reg_data_sp);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+RegisterContextMemory::~RegisterContextMemory()
+{
+}
+
+void
+RegisterContextMemory::InvalidateAllRegisters ()
+{
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
+ SetAllRegisterValid (false);
+}
+
+void
+RegisterContextMemory::SetAllRegisterValid (bool b)
+{
+ std::vector<bool>::iterator pos, end = m_reg_valid.end();
+ for (pos = m_reg_valid.begin(); pos != end; ++pos)
+ *pos = b;
+}
+
+size_t
+RegisterContextMemory::GetRegisterCount ()
+{
+ return m_reg_infos.GetNumRegisters ();
+}
+
+const RegisterInfo *
+RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
+{
+ return m_reg_infos.GetRegisterInfoAtIndex (reg);
+}
+
+size_t
+RegisterContextMemory::GetRegisterSetCount ()
+{
+ return m_reg_infos.GetNumRegisterSets ();
+}
+
+const RegisterSet *
+RegisterContextMemory::GetRegisterSet (size_t reg_set)
+{
+ return m_reg_infos.GetRegisterSet (reg_set);
+}
+
+uint32_t
+RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
+{
+ return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
+}
+
+bool
+RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
+{
+ const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
+ if (!m_reg_valid[reg_num])
+ {
+ if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ()))
+ return false;
+ }
+ const bool partial_data_ok = false;
+ return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success();
+}
+
+bool
+RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
+{
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
+ {
+ const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
+ addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
+ Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value));
+ m_reg_valid[reg_num] = false;
+ return error.Success();
+ }
+ return false;
+}
+
+bool
+RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
+{
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
+ {
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
+ {
+ SetAllRegisterValid (true);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
+{
+ if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
+ {
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ SetAllRegisterValid (false);
+ if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+RegisterContextMemory::SetAllRegisterData (const lldb::DataBufferSP &data_sp)
+{
+ m_reg_data.SetData(data_sp);
+ SetAllRegisterValid (true);
+}