1//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "RegisterContextMemory.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "DynamicRegisterInfo.h" 17#include "lldb/Core/DataBufferHeap.h" 18#include "lldb/Core/Error.h" 19#include "lldb/Core/RegisterValue.h" 20#include "lldb/Target/Process.h" 21#include "lldb/Target/Thread.h" 22 23using namespace lldb; 24using namespace lldb_private; 25 26//---------------------------------------------------------------------- 27// RegisterContextMemory constructor 28//---------------------------------------------------------------------- 29RegisterContextMemory::RegisterContextMemory 30( 31 Thread &thread, 32 uint32_t concrete_frame_idx, 33 DynamicRegisterInfo ®_infos, 34 addr_t reg_data_addr 35) : 36 RegisterContext (thread, concrete_frame_idx), 37 m_reg_infos (reg_infos), 38 m_reg_valid (), 39 m_reg_data (), 40 m_reg_data_addr (reg_data_addr) 41{ 42 // Resize our vector of bools to contain one bool for every register. 43 // We will use these boolean values to know when a register value 44 // is valid in m_reg_data. 45 const size_t num_regs = reg_infos.GetNumRegisters(); 46 assert (num_regs > 0); 47 m_reg_valid.resize (num_regs); 48 49 // Make a heap based buffer that is big enough to store all registers 50 DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0)); 51 m_reg_data.SetData (reg_data_sp); 52} 53 54//---------------------------------------------------------------------- 55// Destructor 56//---------------------------------------------------------------------- 57RegisterContextMemory::~RegisterContextMemory() 58{ 59} 60 61void 62RegisterContextMemory::InvalidateAllRegisters () 63{ 64 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 65 SetAllRegisterValid (false); 66} 67 68void 69RegisterContextMemory::SetAllRegisterValid (bool b) 70{ 71 std::vector<bool>::iterator pos, end = m_reg_valid.end(); 72 for (pos = m_reg_valid.begin(); pos != end; ++pos) 73 *pos = b; 74} 75 76size_t 77RegisterContextMemory::GetRegisterCount () 78{ 79 return m_reg_infos.GetNumRegisters (); 80} 81 82const RegisterInfo * 83RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg) 84{ 85 return m_reg_infos.GetRegisterInfoAtIndex (reg); 86} 87 88size_t 89RegisterContextMemory::GetRegisterSetCount () 90{ 91 return m_reg_infos.GetNumRegisterSets (); 92} 93 94const RegisterSet * 95RegisterContextMemory::GetRegisterSet (size_t reg_set) 96{ 97 return m_reg_infos.GetRegisterSet (reg_set); 98} 99 100uint32_t 101RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) 102{ 103 return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num); 104} 105 106bool 107RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) 108{ 109 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; 110 if (!m_reg_valid[reg_num]) 111 { 112 if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ())) 113 return false; 114 } 115 const bool partial_data_ok = false; 116 return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success(); 117} 118 119bool 120RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) 121{ 122 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 123 { 124 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; 125 addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset; 126 Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value)); 127 m_reg_valid[reg_num] = false; 128 return error.Success(); 129 } 130 return false; 131} 132 133bool 134RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp) 135{ 136 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 137 { 138 ProcessSP process_sp (CalculateProcess()); 139 if (process_sp) 140 { 141 Error error; 142 if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize()) 143 { 144 SetAllRegisterValid (true); 145 return true; 146 } 147 } 148 } 149 return false; 150} 151 152bool 153RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp) 154{ 155 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 156 { 157 ProcessSP process_sp (CalculateProcess()); 158 if (process_sp) 159 { 160 Error error; 161 SetAllRegisterValid (false); 162 if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize()) 163 return true; 164 } 165 } 166 return false; 167} 168 169void 170RegisterContextMemory::SetAllRegisterData (const lldb::DataBufferSP &data_sp) 171{ 172 m_reg_data.SetData(data_sp); 173 SetAllRegisterValid (true); 174} 175