1 //===-- RegisterContextThreadMemory.cpp -----------------------------------===// 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() = default; 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 // Subclasses must override these functions 58 void RegisterContextThreadMemory::InvalidateAllRegisters() { 59 UpdateRegisterContext(); 60 if (m_reg_ctx_sp) 61 m_reg_ctx_sp->InvalidateAllRegisters(); 62 } 63 64 size_t RegisterContextThreadMemory::GetRegisterCount() { 65 UpdateRegisterContext(); 66 if (m_reg_ctx_sp) 67 return m_reg_ctx_sp->GetRegisterCount(); 68 return 0; 69 } 70 71 const RegisterInfo * 72 RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) { 73 UpdateRegisterContext(); 74 if (m_reg_ctx_sp) 75 return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg); 76 return nullptr; 77 } 78 79 size_t RegisterContextThreadMemory::GetRegisterSetCount() { 80 UpdateRegisterContext(); 81 if (m_reg_ctx_sp) 82 return m_reg_ctx_sp->GetRegisterSetCount(); 83 return 0; 84 } 85 86 const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) { 87 UpdateRegisterContext(); 88 if (m_reg_ctx_sp) 89 return m_reg_ctx_sp->GetRegisterSet(reg_set); 90 return nullptr; 91 } 92 93 bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info, 94 RegisterValue ®_value) { 95 UpdateRegisterContext(); 96 if (m_reg_ctx_sp) 97 return m_reg_ctx_sp->ReadRegister(reg_info, reg_value); 98 return false; 99 } 100 101 bool RegisterContextThreadMemory::WriteRegister( 102 const RegisterInfo *reg_info, const RegisterValue ®_value) { 103 UpdateRegisterContext(); 104 if (m_reg_ctx_sp) 105 return m_reg_ctx_sp->WriteRegister(reg_info, reg_value); 106 return false; 107 } 108 109 bool RegisterContextThreadMemory::ReadAllRegisterValues( 110 lldb::WritableDataBufferSP &data_sp) { 111 UpdateRegisterContext(); 112 if (m_reg_ctx_sp) 113 return m_reg_ctx_sp->ReadAllRegisterValues(data_sp); 114 return false; 115 } 116 117 bool RegisterContextThreadMemory::WriteAllRegisterValues( 118 const lldb::DataBufferSP &data_sp) { 119 UpdateRegisterContext(); 120 if (m_reg_ctx_sp) 121 return m_reg_ctx_sp->WriteAllRegisterValues(data_sp); 122 return false; 123 } 124 125 bool RegisterContextThreadMemory::CopyFromRegisterContext( 126 lldb::RegisterContextSP reg_ctx_sp) { 127 UpdateRegisterContext(); 128 if (m_reg_ctx_sp) 129 return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp); 130 return false; 131 } 132 133 uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber( 134 lldb::RegisterKind kind, uint32_t num) { 135 UpdateRegisterContext(); 136 if (m_reg_ctx_sp) 137 return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num); 138 return false; 139 } 140 141 uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() { 142 UpdateRegisterContext(); 143 if (m_reg_ctx_sp) 144 return m_reg_ctx_sp->NumSupportedHardwareBreakpoints(); 145 return false; 146 } 147 148 uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr, 149 size_t size) { 150 UpdateRegisterContext(); 151 if (m_reg_ctx_sp) 152 return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size); 153 return 0; 154 } 155 156 bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) { 157 UpdateRegisterContext(); 158 if (m_reg_ctx_sp) 159 return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx); 160 return false; 161 } 162 163 uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() { 164 UpdateRegisterContext(); 165 if (m_reg_ctx_sp) 166 return m_reg_ctx_sp->NumSupportedHardwareWatchpoints(); 167 return 0; 168 } 169 170 uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr, 171 size_t size, 172 bool read, 173 bool write) { 174 UpdateRegisterContext(); 175 if (m_reg_ctx_sp) 176 return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write); 177 return 0; 178 } 179 180 bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) { 181 UpdateRegisterContext(); 182 if (m_reg_ctx_sp) 183 return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index); 184 return false; 185 } 186 187 bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) { 188 UpdateRegisterContext(); 189 if (m_reg_ctx_sp) 190 return m_reg_ctx_sp->HardwareSingleStep(enable); 191 return false; 192 } 193 194 Status RegisterContextThreadMemory::ReadRegisterValueFromMemory( 195 const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, 196 uint32_t src_len, RegisterValue ®_value) { 197 UpdateRegisterContext(); 198 if (m_reg_ctx_sp) 199 return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr, 200 src_len, reg_value); 201 Status error; 202 error.SetErrorString("invalid register context"); 203 return error; 204 } 205 206 Status RegisterContextThreadMemory::WriteRegisterValueToMemory( 207 const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, 208 uint32_t dst_len, const RegisterValue ®_value) { 209 UpdateRegisterContext(); 210 if (m_reg_ctx_sp) 211 return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len, 212 reg_value); 213 Status error; 214 error.SetErrorString("invalid register context"); 215 return error; 216 } 217