LLDB mainline
RegisterContextThreadMemory.cpp
Go to the documentation of this file.
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
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
16
17using namespace lldb;
18using namespace lldb_private;
19
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
26
28 std::lock_guard<std::mutex> lock(m_update_register_ctx_lock);
29
30 ThreadSP thread_sp(m_thread_wp.lock());
31 if (thread_sp) {
32 ProcessSP process_sp(thread_sp->GetProcess());
33
34 if (process_sp) {
35 const uint32_t stop_id = process_sp->GetModID().GetStopID();
36 if (m_stop_id != stop_id) {
37 m_stop_id = stop_id;
38 m_reg_ctx_sp.reset();
39 }
40 if (!m_reg_ctx_sp) {
41 ThreadSP backing_thread_sp(thread_sp->GetBackingThread());
42 if (backing_thread_sp) {
43 m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
44 } else {
45 OperatingSystem *os = process_sp->GetOperatingSystem();
46 if (os->IsOperatingSystemPluginThread(thread_sp))
48 thread_sp.get(), m_register_data_addr);
49 }
50 }
51 } else {
52 m_reg_ctx_sp.reset();
53 }
54 } else {
55 m_reg_ctx_sp.reset();
56 }
57}
58
59// Subclasses must override these functions
65
68 if (m_reg_ctx_sp)
69 return m_reg_ctx_sp->GetRegisterCount();
70 return 0;
71}
72
73const RegisterInfo *
76 if (m_reg_ctx_sp)
77 return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
78 return nullptr;
79}
80
83 if (m_reg_ctx_sp)
84 return m_reg_ctx_sp->GetRegisterSetCount();
85 return 0;
86}
87
90 if (m_reg_ctx_sp)
91 return m_reg_ctx_sp->GetRegisterSet(reg_set);
92 return nullptr;
93}
94
96 RegisterValue &reg_value) {
98 if (m_reg_ctx_sp)
99 return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
100 return false;
101}
102
104 const RegisterInfo *reg_info, const RegisterValue &reg_value) {
106 if (m_reg_ctx_sp)
107 return m_reg_ctx_sp->WriteRegister(reg_info, reg_value);
108 return false;
109}
110
114 if (m_reg_ctx_sp)
115 return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
116 return false;
117}
118
120 lldb_private::RegisterCheckpoint &reg_checkpoint) {
122 if (m_reg_ctx_sp)
123 return m_reg_ctx_sp->ReadAllRegisterValues(reg_checkpoint);
124 return false;
125}
126
128 const lldb::DataBufferSP &data_sp) {
130 if (m_reg_ctx_sp)
131 return m_reg_ctx_sp->WriteAllRegisterValues(data_sp);
132 return false;
133}
134
136 const lldb_private::RegisterCheckpoint &reg_checkpoint) {
138 if (m_reg_ctx_sp)
139 return m_reg_ctx_sp->WriteAllRegisterValues(reg_checkpoint);
140 return false;
141}
142
144 lldb::RegisterContextSP reg_ctx_sp) {
146 if (m_reg_ctx_sp)
147 return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
148 return false;
149}
150
152 lldb::RegisterKind kind, uint32_t num) {
154 if (m_reg_ctx_sp)
155 return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
156 return LLDB_INVALID_REGNUM;
157}
158
161 if (m_reg_ctx_sp)
162 return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
163 return 0;
164}
165
167 size_t size) {
169 if (m_reg_ctx_sp)
170 return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
171 return 0;
172}
173
176 if (m_reg_ctx_sp)
177 return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx);
178 return false;
179}
180
183 if (m_reg_ctx_sp)
184 return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
185 return 0;
186}
187
189 size_t size,
190 bool read,
191 bool write) {
193 if (m_reg_ctx_sp)
194 return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
195 return 0;
196}
197
200 if (m_reg_ctx_sp)
201 return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
202 return false;
203}
204
207 if (m_reg_ctx_sp)
208 return m_reg_ctx_sp->HardwareSingleStep(enable);
209 return false;
210}
211
213 const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr,
214 uint32_t src_len, RegisterValue &reg_value) {
216 if (m_reg_ctx_sp)
217 return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr,
218 src_len, reg_value);
219 return Status::FromErrorString("invalid register context");
220}
221
223 const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr,
224 uint32_t dst_len, const RegisterValue &reg_value) {
226 if (m_reg_ctx_sp)
227 return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len,
228 reg_value);
229 return Status::FromErrorString("invalid register context");
230}
A plug-in interface definition class for halted OS helpers.
virtual lldb::RegisterContextSP CreateRegisterContextForThread(Thread *thread, lldb::addr_t reg_data_addr)=0
virtual bool IsOperatingSystemPluginThread(const lldb::ThreadSP &thread_sp)
bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override
const RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override
Status ReadRegisterValueFromMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, RegisterValue &reg_value) override
bool CopyFromRegisterContext(lldb::RegisterContextSP context)
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override
RegisterContextThreadMemory(Thread &thread, lldb::addr_t register_data_addr)
uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override
Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value) override
const RegisterSet * GetRegisterSet(size_t reg_set) override
bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
RegisterKind
Register numbering types.
Every register is described in detail including its name, alternate name (optional),...
Registers are grouped into register sets.