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