| //===-- 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 () |
| { |
| 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 (uint32_t reg) |
| { |
| return m_reg_infos.GetRegisterInfoAtIndex (reg); |
| } |
| |
| size_t |
| RegisterContextMemory::GetRegisterSetCount () |
| { |
| return m_reg_infos.GetNumRegisterSets (); |
| } |
| |
| const RegisterSet * |
| RegisterContextMemory::GetRegisterSet (uint32_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; |
| } |