1 //===-- RegisterContextThreadMemory.cpp -----------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
15 #include "RegisterContextThreadMemory.h"
18 using namespace lldb_private
;
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) {}
25 RegisterContextThreadMemory::~RegisterContextThreadMemory() = default;
27 void RegisterContextThreadMemory::UpdateRegisterContext() {
28 ThreadSP
thread_sp(m_thread_wp
.lock());
30 ProcessSP
process_sp(thread_sp
->GetProcess());
33 const uint32_t stop_id
= process_sp
->GetModID().GetStopID();
34 if (m_stop_id
!= stop_id
) {
39 ThreadSP
backing_thread_sp(thread_sp
->GetBackingThread());
40 if (backing_thread_sp
) {
41 m_reg_ctx_sp
= backing_thread_sp
->GetRegisterContext();
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
);
57 // Subclasses must override these functions
58 void RegisterContextThreadMemory::InvalidateAllRegisters() {
59 UpdateRegisterContext();
61 m_reg_ctx_sp
->InvalidateAllRegisters();
64 size_t RegisterContextThreadMemory::GetRegisterCount() {
65 UpdateRegisterContext();
67 return m_reg_ctx_sp
->GetRegisterCount();
72 RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg
) {
73 UpdateRegisterContext();
75 return m_reg_ctx_sp
->GetRegisterInfoAtIndex(reg
);
79 size_t RegisterContextThreadMemory::GetRegisterSetCount() {
80 UpdateRegisterContext();
82 return m_reg_ctx_sp
->GetRegisterSetCount();
86 const RegisterSet
*RegisterContextThreadMemory::GetRegisterSet(size_t reg_set
) {
87 UpdateRegisterContext();
89 return m_reg_ctx_sp
->GetRegisterSet(reg_set
);
93 bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo
*reg_info
,
94 RegisterValue
®_value
) {
95 UpdateRegisterContext();
97 return m_reg_ctx_sp
->ReadRegister(reg_info
, reg_value
);
101 bool RegisterContextThreadMemory::WriteRegister(
102 const RegisterInfo
*reg_info
, const RegisterValue
®_value
) {
103 UpdateRegisterContext();
105 return m_reg_ctx_sp
->WriteRegister(reg_info
, reg_value
);
109 bool RegisterContextThreadMemory::ReadAllRegisterValues(
110 lldb::WritableDataBufferSP
&data_sp
) {
111 UpdateRegisterContext();
113 return m_reg_ctx_sp
->ReadAllRegisterValues(data_sp
);
117 bool RegisterContextThreadMemory::WriteAllRegisterValues(
118 const lldb::DataBufferSP
&data_sp
) {
119 UpdateRegisterContext();
121 return m_reg_ctx_sp
->WriteAllRegisterValues(data_sp
);
125 bool RegisterContextThreadMemory::CopyFromRegisterContext(
126 lldb::RegisterContextSP reg_ctx_sp
) {
127 UpdateRegisterContext();
129 return m_reg_ctx_sp
->CopyFromRegisterContext(reg_ctx_sp
);
133 uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber(
134 lldb::RegisterKind kind
, uint32_t num
) {
135 UpdateRegisterContext();
137 return m_reg_ctx_sp
->ConvertRegisterKindToRegisterNumber(kind
, num
);
141 uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() {
142 UpdateRegisterContext();
144 return m_reg_ctx_sp
->NumSupportedHardwareBreakpoints();
148 uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr
,
150 UpdateRegisterContext();
152 return m_reg_ctx_sp
->SetHardwareBreakpoint(addr
, size
);
156 bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx
) {
157 UpdateRegisterContext();
159 return m_reg_ctx_sp
->ClearHardwareBreakpoint(hw_idx
);
163 uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() {
164 UpdateRegisterContext();
166 return m_reg_ctx_sp
->NumSupportedHardwareWatchpoints();
170 uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr
,
174 UpdateRegisterContext();
176 return m_reg_ctx_sp
->SetHardwareWatchpoint(addr
, size
, read
, write
);
180 bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index
) {
181 UpdateRegisterContext();
183 return m_reg_ctx_sp
->ClearHardwareWatchpoint(hw_index
);
187 bool RegisterContextThreadMemory::HardwareSingleStep(bool enable
) {
188 UpdateRegisterContext();
190 return m_reg_ctx_sp
->HardwareSingleStep(enable
);
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();
199 return m_reg_ctx_sp
->ReadRegisterValueFromMemory(reg_info
, src_addr
,
202 error
.SetErrorString("invalid register context");
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();
211 return m_reg_ctx_sp
->WriteRegisterValueToMemory(reg_info
, dst_addr
, dst_len
,
214 error
.SetErrorString("invalid register context");