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 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 65 SetAllRegisterValid (false); 66 } 67 68 void 69 RegisterContextMemory::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 76 size_t 77 RegisterContextMemory::GetRegisterCount () 78 { 79 return m_reg_infos.GetNumRegisters (); 80 } 81 82 const RegisterInfo * 83 RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg) 84 { 85 return m_reg_infos.GetRegisterInfoAtIndex (reg); 86 } 87 88 size_t 89 RegisterContextMemory::GetRegisterSetCount () 90 { 91 return m_reg_infos.GetNumRegisterSets (); 92 } 93 94 const RegisterSet * 95 RegisterContextMemory::GetRegisterSet (size_t reg_set) 96 { 97 return m_reg_infos.GetRegisterSet (reg_set); 98 } 99 100 uint32_t 101 RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) 102 { 103 return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num); 104 } 105 106 bool 107 RegisterContextMemory::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 119 bool 120 RegisterContextMemory::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 133 bool 134 RegisterContextMemory::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 152 bool 153 RegisterContextMemory::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 169 void 170 RegisterContextMemory::SetAllRegisterData (const lldb::DataBufferSP &data_sp) 171 { 172 m_reg_data.SetData(data_sp); 173 SetAllRegisterValid (true); 174 } 175