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 23 using namespace lldb; 24 using namespace lldb_private; 25 26 //---------------------------------------------------------------------- 27 // RegisterContextMemory constructor 28 //---------------------------------------------------------------------- 29 RegisterContextMemory::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 //---------------------------------------------------------------------- 57 RegisterContextMemory::~RegisterContextMemory() 58 { 59 } 60 61 void 62 RegisterContextMemory::InvalidateAllRegisters () 63 { 64 SetAllRegisterValid (false); 65 } 66 67 void 68 RegisterContextMemory::SetAllRegisterValid (bool b) 69 { 70 std::vector<bool>::iterator pos, end = m_reg_valid.end(); 71 for (pos = m_reg_valid.begin(); pos != end; ++pos) 72 *pos = b; 73 } 74 75 size_t 76 RegisterContextMemory::GetRegisterCount () 77 { 78 return m_reg_infos.GetNumRegisters (); 79 } 80 81 const RegisterInfo * 82 RegisterContextMemory::GetRegisterInfoAtIndex (uint32_t reg) 83 { 84 return m_reg_infos.GetRegisterInfoAtIndex (reg); 85 } 86 87 size_t 88 RegisterContextMemory::GetRegisterSetCount () 89 { 90 return m_reg_infos.GetNumRegisterSets (); 91 } 92 93 const RegisterSet * 94 RegisterContextMemory::GetRegisterSet (uint32_t reg_set) 95 { 96 return m_reg_infos.GetRegisterSet (reg_set); 97 } 98 99 uint32_t 100 RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) 101 { 102 return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num); 103 } 104 105 bool 106 RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) 107 { 108 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; 109 if (!m_reg_valid[reg_num]) 110 { 111 if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ())) 112 return false; 113 } 114 const bool partial_data_ok = false; 115 return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success(); 116 } 117 118 bool 119 RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) 120 { 121 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 122 { 123 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; 124 addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset; 125 Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value)); 126 m_reg_valid[reg_num] = false; 127 return error.Success(); 128 } 129 return false; 130 } 131 132 bool 133 RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp) 134 { 135 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 136 { 137 Error error; 138 if (m_thread.GetProcess().ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize()) 139 { 140 SetAllRegisterValid (true); 141 return true; 142 } 143 } 144 return false; 145 } 146 147 bool 148 RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp) 149 { 150 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 151 { 152 Error error; 153 SetAllRegisterValid (false); 154 if (m_thread.GetProcess().WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize()) 155 return true; 156 } 157 return false; 158 } 159