RegisterContextThreadMemory.cpp revision 314564
1//===-- RegisterContextThreadMemory.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 "lldb/Core/Error.h" 11#include "lldb/Target/OperatingSystem.h" 12#include "lldb/Target/Process.h" 13#include "lldb/Target/Thread.h" 14#include "lldb/lldb-private.h" 15 16#include "RegisterContextThreadMemory.h" 17 18using namespace lldb; 19using namespace lldb_private; 20 21RegisterContextThreadMemory::RegisterContextThreadMemory( 22 Thread &thread, lldb::addr_t register_data_addr) 23 : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()), 24 m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {} 25 26RegisterContextThreadMemory::~RegisterContextThreadMemory() {} 27 28void RegisterContextThreadMemory::UpdateRegisterContext() { 29 ThreadSP thread_sp(m_thread_wp.lock()); 30 if (thread_sp) { 31 ProcessSP process_sp(thread_sp->GetProcess()); 32 33 if (process_sp) { 34 const uint32_t stop_id = process_sp->GetModID().GetStopID(); 35 if (m_stop_id != stop_id) { 36 m_stop_id = stop_id; 37 m_reg_ctx_sp.reset(); 38 } 39 if (!m_reg_ctx_sp) { 40 ThreadSP backing_thread_sp(thread_sp->GetBackingThread()); 41 if (backing_thread_sp) { 42 m_reg_ctx_sp = backing_thread_sp->GetRegisterContext(); 43 } else { 44 OperatingSystem *os = process_sp->GetOperatingSystem(); 45 if (os->IsOperatingSystemPluginThread(thread_sp)) 46 m_reg_ctx_sp = os->CreateRegisterContextForThread( 47 thread_sp.get(), m_register_data_addr); 48 } 49 } 50 } else { 51 m_reg_ctx_sp.reset(); 52 } 53 } else { 54 m_reg_ctx_sp.reset(); 55 } 56} 57 58//------------------------------------------------------------------ 59// Subclasses must override these functions 60//------------------------------------------------------------------ 61void RegisterContextThreadMemory::InvalidateAllRegisters() { 62 UpdateRegisterContext(); 63 if (m_reg_ctx_sp) 64 m_reg_ctx_sp->InvalidateAllRegisters(); 65} 66 67size_t RegisterContextThreadMemory::GetRegisterCount() { 68 UpdateRegisterContext(); 69 if (m_reg_ctx_sp) 70 return m_reg_ctx_sp->GetRegisterCount(); 71 return 0; 72} 73 74const RegisterInfo * 75RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) { 76 UpdateRegisterContext(); 77 if (m_reg_ctx_sp) 78 return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg); 79 return NULL; 80} 81 82size_t RegisterContextThreadMemory::GetRegisterSetCount() { 83 UpdateRegisterContext(); 84 if (m_reg_ctx_sp) 85 return m_reg_ctx_sp->GetRegisterSetCount(); 86 return 0; 87} 88 89const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) { 90 UpdateRegisterContext(); 91 if (m_reg_ctx_sp) 92 return m_reg_ctx_sp->GetRegisterSet(reg_set); 93 return NULL; 94} 95 96bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info, 97 RegisterValue ®_value) { 98 UpdateRegisterContext(); 99 if (m_reg_ctx_sp) 100 return m_reg_ctx_sp->ReadRegister(reg_info, reg_value); 101 return false; 102} 103 104bool RegisterContextThreadMemory::WriteRegister( 105 const RegisterInfo *reg_info, const RegisterValue ®_value) { 106 UpdateRegisterContext(); 107 if (m_reg_ctx_sp) 108 return m_reg_ctx_sp->WriteRegister(reg_info, reg_value); 109 return false; 110} 111 112bool RegisterContextThreadMemory::ReadAllRegisterValues( 113 lldb::DataBufferSP &data_sp) { 114 UpdateRegisterContext(); 115 if (m_reg_ctx_sp) 116 return m_reg_ctx_sp->ReadAllRegisterValues(data_sp); 117 return false; 118} 119 120bool RegisterContextThreadMemory::WriteAllRegisterValues( 121 const lldb::DataBufferSP &data_sp) { 122 UpdateRegisterContext(); 123 if (m_reg_ctx_sp) 124 return m_reg_ctx_sp->WriteAllRegisterValues(data_sp); 125 return false; 126} 127 128bool RegisterContextThreadMemory::CopyFromRegisterContext( 129 lldb::RegisterContextSP reg_ctx_sp) { 130 UpdateRegisterContext(); 131 if (m_reg_ctx_sp) 132 return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp); 133 return false; 134} 135 136uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber( 137 lldb::RegisterKind kind, uint32_t num) { 138 UpdateRegisterContext(); 139 if (m_reg_ctx_sp) 140 return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num); 141 return false; 142} 143 144uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() { 145 UpdateRegisterContext(); 146 if (m_reg_ctx_sp) 147 return m_reg_ctx_sp->NumSupportedHardwareBreakpoints(); 148 return false; 149} 150 151uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr, 152 size_t size) { 153 UpdateRegisterContext(); 154 if (m_reg_ctx_sp) 155 return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size); 156 return 0; 157} 158 159bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) { 160 UpdateRegisterContext(); 161 if (m_reg_ctx_sp) 162 return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx); 163 return false; 164} 165 166uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() { 167 UpdateRegisterContext(); 168 if (m_reg_ctx_sp) 169 return m_reg_ctx_sp->NumSupportedHardwareWatchpoints(); 170 return 0; 171} 172 173uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr, 174 size_t size, 175 bool read, 176 bool write) { 177 UpdateRegisterContext(); 178 if (m_reg_ctx_sp) 179 return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write); 180 return 0; 181} 182 183bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) { 184 UpdateRegisterContext(); 185 if (m_reg_ctx_sp) 186 return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index); 187 return false; 188} 189 190bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) { 191 UpdateRegisterContext(); 192 if (m_reg_ctx_sp) 193 return m_reg_ctx_sp->HardwareSingleStep(enable); 194 return false; 195} 196 197Error RegisterContextThreadMemory::ReadRegisterValueFromMemory( 198 const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, 199 uint32_t src_len, RegisterValue ®_value) { 200 UpdateRegisterContext(); 201 if (m_reg_ctx_sp) 202 return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr, 203 src_len, reg_value); 204 Error error; 205 error.SetErrorString("invalid register context"); 206 return error; 207} 208 209Error RegisterContextThreadMemory::WriteRegisterValueToMemory( 210 const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, 211 uint32_t dst_len, const RegisterValue ®_value) { 212 UpdateRegisterContext(); 213 if (m_reg_ctx_sp) 214 return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len, 215 reg_value); 216 Error error; 217 error.SetErrorString("invalid register context"); 218 return error; 219} 220