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(Thread &thread, 30 uint32_t concrete_frame_idx, 31 DynamicRegisterInfo ®_infos, 32 addr_t reg_data_addr) 33 : RegisterContext(thread, concrete_frame_idx), m_reg_infos(reg_infos), 34 m_reg_valid(), m_reg_data(), m_reg_data_addr(reg_data_addr) { 35 // Resize our vector of bools to contain one bool for every register. 36 // We will use these boolean values to know when a register value 37 // is valid in m_reg_data. 38 const size_t num_regs = reg_infos.GetNumRegisters(); 39 assert(num_regs > 0); 40 m_reg_valid.resize(num_regs); 41 42 // Make a heap based buffer that is big enough to store all registers 43 DataBufferSP reg_data_sp( 44 new DataBufferHeap(reg_infos.GetRegisterDataByteSize(), 0)); 45 m_reg_data.SetData(reg_data_sp); 46 } 47 48 //---------------------------------------------------------------------- 49 // Destructor 50 //---------------------------------------------------------------------- 51 RegisterContextMemory::~RegisterContextMemory() {} 52 53 void RegisterContextMemory::InvalidateAllRegisters() { 54 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) 55 SetAllRegisterValid(false); 56 } 57 58 void RegisterContextMemory::SetAllRegisterValid(bool b) { 59 std::vector<bool>::iterator pos, end = m_reg_valid.end(); 60 for (pos = m_reg_valid.begin(); pos != end; ++pos) 61 *pos = b; 62 } 63 64 size_t RegisterContextMemory::GetRegisterCount() { 65 return m_reg_infos.GetNumRegisters(); 66 } 67 68 const RegisterInfo *RegisterContextMemory::GetRegisterInfoAtIndex(size_t reg) { 69 return m_reg_infos.GetRegisterInfoAtIndex(reg); 70 } 71 72 size_t RegisterContextMemory::GetRegisterSetCount() { 73 return m_reg_infos.GetNumRegisterSets(); 74 } 75 76 const RegisterSet *RegisterContextMemory::GetRegisterSet(size_t reg_set) { 77 return m_reg_infos.GetRegisterSet(reg_set); 78 } 79 80 uint32_t RegisterContextMemory::ConvertRegisterKindToRegisterNumber( 81 lldb::RegisterKind kind, uint32_t num) { 82 return m_reg_infos.ConvertRegisterKindToRegisterNumber(kind, num); 83 } 84 85 bool RegisterContextMemory::ReadRegister(const RegisterInfo *reg_info, 86 RegisterValue ®_value) { 87 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; 88 if (!m_reg_valid[reg_num]) { 89 if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer())) 90 return false; 91 } 92 const bool partial_data_ok = false; 93 return reg_value 94 .SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, 95 partial_data_ok) 96 .Success(); 97 } 98 99 bool RegisterContextMemory::WriteRegister(const RegisterInfo *reg_info, 100 const RegisterValue ®_value) { 101 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { 102 const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; 103 addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset; 104 Error error(WriteRegisterValueToMemory(reg_info, reg_addr, 105 reg_info->byte_size, reg_value)); 106 m_reg_valid[reg_num] = false; 107 return error.Success(); 108 } 109 return false; 110 } 111 112 bool RegisterContextMemory::ReadAllRegisterValues(DataBufferSP &data_sp) { 113 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { 114 ProcessSP process_sp(CalculateProcess()); 115 if (process_sp) { 116 Error error; 117 if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), 118 data_sp->GetByteSize(), 119 error) == data_sp->GetByteSize()) { 120 SetAllRegisterValid(true); 121 return true; 122 } 123 } 124 } 125 return false; 126 } 127 128 bool RegisterContextMemory::WriteAllRegisterValues( 129 const DataBufferSP &data_sp) { 130 if (m_reg_data_addr != LLDB_INVALID_ADDRESS) { 131 ProcessSP process_sp(CalculateProcess()); 132 if (process_sp) { 133 Error error; 134 SetAllRegisterValid(false); 135 if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), 136 data_sp->GetByteSize(), 137 error) == data_sp->GetByteSize()) 138 return true; 139 } 140 } 141 return false; 142 } 143 144 void RegisterContextMemory::SetAllRegisterData( 145 const lldb::DataBufferSP &data_sp) { 146 m_reg_data.SetData(data_sp); 147 SetAllRegisterValid(true); 148 } 149