]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / Process / Utility / RegisterContextThreadMemory.cpp
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 // 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 &reg_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 &reg_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::DataBufferSP &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 &reg_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 &reg_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 }