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