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