diff options
Diffstat (limited to 'source/Plugins/Process/Utility/RegisterContextMemory.cpp')
-rw-r--r-- | source/Plugins/Process/Utility/RegisterContextMemory.cpp | 174 |
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 ®_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 ®_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 ®_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); +} |