1254721Semaste//===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Target/OperatingSystem.h" 10254721Semaste#include "lldb/Target/Process.h" 11254721Semaste#include "lldb/Target/Thread.h" 12321369Sdim#include "lldb/Utility/Status.h" 13314564Sdim#include "lldb/lldb-private.h" 14254721Semaste 15254721Semaste#include "RegisterContextThreadMemory.h" 16254721Semaste 17254721Semasteusing namespace lldb; 18254721Semasteusing namespace lldb_private; 19254721Semaste 20314564SdimRegisterContextThreadMemory::RegisterContextThreadMemory( 21314564Sdim Thread &thread, lldb::addr_t register_data_addr) 22314564Sdim : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()), 23314564Sdim m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {} 24254721Semaste 25314564SdimRegisterContextThreadMemory::~RegisterContextThreadMemory() {} 26254721Semaste 27314564Sdimvoid RegisterContextThreadMemory::UpdateRegisterContext() { 28314564Sdim ThreadSP thread_sp(m_thread_wp.lock()); 29314564Sdim if (thread_sp) { 30314564Sdim ProcessSP process_sp(thread_sp->GetProcess()); 31254721Semaste 32314564Sdim if (process_sp) { 33314564Sdim const uint32_t stop_id = process_sp->GetModID().GetStopID(); 34314564Sdim if (m_stop_id != stop_id) { 35314564Sdim m_stop_id = stop_id; 36314564Sdim m_reg_ctx_sp.reset(); 37314564Sdim } 38314564Sdim if (!m_reg_ctx_sp) { 39314564Sdim ThreadSP backing_thread_sp(thread_sp->GetBackingThread()); 40314564Sdim if (backing_thread_sp) { 41314564Sdim m_reg_ctx_sp = backing_thread_sp->GetRegisterContext(); 42314564Sdim } else { 43314564Sdim OperatingSystem *os = process_sp->GetOperatingSystem(); 44314564Sdim if (os->IsOperatingSystemPluginThread(thread_sp)) 45314564Sdim m_reg_ctx_sp = os->CreateRegisterContextForThread( 46314564Sdim thread_sp.get(), m_register_data_addr); 47254721Semaste } 48314564Sdim } 49314564Sdim } else { 50314564Sdim m_reg_ctx_sp.reset(); 51254721Semaste } 52314564Sdim } else { 53314564Sdim m_reg_ctx_sp.reset(); 54314564Sdim } 55254721Semaste} 56254721Semaste 57254721Semaste// Subclasses must override these functions 58314564Sdimvoid RegisterContextThreadMemory::InvalidateAllRegisters() { 59314564Sdim UpdateRegisterContext(); 60314564Sdim if (m_reg_ctx_sp) 61314564Sdim m_reg_ctx_sp->InvalidateAllRegisters(); 62254721Semaste} 63254721Semaste 64314564Sdimsize_t RegisterContextThreadMemory::GetRegisterCount() { 65314564Sdim UpdateRegisterContext(); 66314564Sdim if (m_reg_ctx_sp) 67314564Sdim return m_reg_ctx_sp->GetRegisterCount(); 68314564Sdim return 0; 69254721Semaste} 70254721Semaste 71254721Semasteconst RegisterInfo * 72314564SdimRegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) { 73314564Sdim UpdateRegisterContext(); 74314564Sdim if (m_reg_ctx_sp) 75314564Sdim return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg); 76353358Sdim return nullptr; 77254721Semaste} 78254721Semaste 79314564Sdimsize_t RegisterContextThreadMemory::GetRegisterSetCount() { 80314564Sdim UpdateRegisterContext(); 81314564Sdim if (m_reg_ctx_sp) 82314564Sdim return m_reg_ctx_sp->GetRegisterSetCount(); 83314564Sdim return 0; 84254721Semaste} 85254721Semaste 86314564Sdimconst RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) { 87314564Sdim UpdateRegisterContext(); 88314564Sdim if (m_reg_ctx_sp) 89314564Sdim return m_reg_ctx_sp->GetRegisterSet(reg_set); 90353358Sdim return nullptr; 91254721Semaste} 92254721Semaste 93314564Sdimbool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info, 94314564Sdim RegisterValue ®_value) { 95314564Sdim UpdateRegisterContext(); 96314564Sdim if (m_reg_ctx_sp) 97314564Sdim return m_reg_ctx_sp->ReadRegister(reg_info, reg_value); 98314564Sdim return false; 99254721Semaste} 100254721Semaste 101314564Sdimbool RegisterContextThreadMemory::WriteRegister( 102314564Sdim const RegisterInfo *reg_info, const RegisterValue ®_value) { 103314564Sdim UpdateRegisterContext(); 104314564Sdim if (m_reg_ctx_sp) 105314564Sdim return m_reg_ctx_sp->WriteRegister(reg_info, reg_value); 106314564Sdim return false; 107254721Semaste} 108254721Semaste 109314564Sdimbool RegisterContextThreadMemory::ReadAllRegisterValues( 110314564Sdim lldb::DataBufferSP &data_sp) { 111314564Sdim UpdateRegisterContext(); 112314564Sdim if (m_reg_ctx_sp) 113314564Sdim return m_reg_ctx_sp->ReadAllRegisterValues(data_sp); 114314564Sdim return false; 115254721Semaste} 116254721Semaste 117314564Sdimbool RegisterContextThreadMemory::WriteAllRegisterValues( 118314564Sdim const lldb::DataBufferSP &data_sp) { 119314564Sdim UpdateRegisterContext(); 120314564Sdim if (m_reg_ctx_sp) 121314564Sdim return m_reg_ctx_sp->WriteAllRegisterValues(data_sp); 122314564Sdim return false; 123254721Semaste} 124254721Semaste 125314564Sdimbool RegisterContextThreadMemory::CopyFromRegisterContext( 126314564Sdim lldb::RegisterContextSP reg_ctx_sp) { 127314564Sdim UpdateRegisterContext(); 128314564Sdim if (m_reg_ctx_sp) 129314564Sdim return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp); 130314564Sdim return false; 131254721Semaste} 132254721Semaste 133314564Sdimuint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber( 134314564Sdim lldb::RegisterKind kind, uint32_t num) { 135314564Sdim UpdateRegisterContext(); 136314564Sdim if (m_reg_ctx_sp) 137314564Sdim return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num); 138314564Sdim return false; 139254721Semaste} 140254721Semaste 141314564Sdimuint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() { 142314564Sdim UpdateRegisterContext(); 143314564Sdim if (m_reg_ctx_sp) 144314564Sdim return m_reg_ctx_sp->NumSupportedHardwareBreakpoints(); 145314564Sdim return false; 146254721Semaste} 147254721Semaste 148314564Sdimuint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr, 149314564Sdim size_t size) { 150314564Sdim UpdateRegisterContext(); 151314564Sdim if (m_reg_ctx_sp) 152314564Sdim return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size); 153314564Sdim return 0; 154254721Semaste} 155254721Semaste 156314564Sdimbool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) { 157314564Sdim UpdateRegisterContext(); 158314564Sdim if (m_reg_ctx_sp) 159314564Sdim return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx); 160314564Sdim return false; 161254721Semaste} 162254721Semaste 163314564Sdimuint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() { 164314564Sdim UpdateRegisterContext(); 165314564Sdim if (m_reg_ctx_sp) 166314564Sdim return m_reg_ctx_sp->NumSupportedHardwareWatchpoints(); 167314564Sdim return 0; 168254721Semaste} 169254721Semaste 170314564Sdimuint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr, 171314564Sdim size_t size, 172314564Sdim bool read, 173314564Sdim bool write) { 174314564Sdim UpdateRegisterContext(); 175314564Sdim if (m_reg_ctx_sp) 176314564Sdim return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write); 177314564Sdim return 0; 178254721Semaste} 179254721Semaste 180314564Sdimbool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) { 181314564Sdim UpdateRegisterContext(); 182314564Sdim if (m_reg_ctx_sp) 183314564Sdim return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index); 184314564Sdim return false; 185254721Semaste} 186254721Semaste 187314564Sdimbool RegisterContextThreadMemory::HardwareSingleStep(bool enable) { 188314564Sdim UpdateRegisterContext(); 189314564Sdim if (m_reg_ctx_sp) 190314564Sdim return m_reg_ctx_sp->HardwareSingleStep(enable); 191314564Sdim return false; 192254721Semaste} 193254721Semaste 194321369SdimStatus RegisterContextThreadMemory::ReadRegisterValueFromMemory( 195314564Sdim const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, 196314564Sdim uint32_t src_len, RegisterValue ®_value) { 197314564Sdim UpdateRegisterContext(); 198314564Sdim if (m_reg_ctx_sp) 199314564Sdim return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr, 200314564Sdim src_len, reg_value); 201321369Sdim Status error; 202314564Sdim error.SetErrorString("invalid register context"); 203314564Sdim return error; 204254721Semaste} 205254721Semaste 206321369SdimStatus RegisterContextThreadMemory::WriteRegisterValueToMemory( 207314564Sdim const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, 208314564Sdim uint32_t dst_len, const RegisterValue ®_value) { 209314564Sdim UpdateRegisterContext(); 210314564Sdim if (m_reg_ctx_sp) 211314564Sdim return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len, 212314564Sdim reg_value); 213321369Sdim Status error; 214314564Sdim error.SetErrorString("invalid register context"); 215314564Sdim return error; 216254721Semaste} 217