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