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 18 using namespace lldb; 19 using namespace lldb_private; 20 21 RegisterContextThreadMemory::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 26 RegisterContextThreadMemory::~RegisterContextThreadMemory() {} 27 28 void 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 //------------------------------------------------------------------ 61 void RegisterContextThreadMemory::InvalidateAllRegisters() { 62 UpdateRegisterContext(); 63 if (m_reg_ctx_sp) 64 m_reg_ctx_sp->InvalidateAllRegisters(); 65 } 66 67 size_t RegisterContextThreadMemory::GetRegisterCount() { 68 UpdateRegisterContext(); 69 if (m_reg_ctx_sp) 70 return m_reg_ctx_sp->GetRegisterCount(); 71 return 0; 72 } 73 74 const RegisterInfo * 75 RegisterContextThreadMemory::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 82 size_t RegisterContextThreadMemory::GetRegisterSetCount() { 83 UpdateRegisterContext(); 84 if (m_reg_ctx_sp) 85 return m_reg_ctx_sp->GetRegisterSetCount(); 86 return 0; 87 } 88 89 const 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 96 bool 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 104 bool 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 112 bool 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 120 bool 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 128 bool 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 136 uint32_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 144 uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() { 145 UpdateRegisterContext(); 146 if (m_reg_ctx_sp) 147 return m_reg_ctx_sp->NumSupportedHardwareBreakpoints(); 148 return false; 149 } 150 151 uint32_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 159 bool 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 166 uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() { 167 UpdateRegisterContext(); 168 if (m_reg_ctx_sp) 169 return m_reg_ctx_sp->NumSupportedHardwareWatchpoints(); 170 return 0; 171 } 172 173 uint32_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 183 bool 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 190 bool 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 197 Error 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 209 Error 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