//===-- 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::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 (lldb::RegisterKind 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); }