]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
MFV r341618:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextThreadMemory.cpp
1 //===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Target/OperatingSystem.h"
11 #include "lldb/Target/Process.h"
12 #include "lldb/Target/Thread.h"
13 #include "lldb/Utility/Status.h"
14 #include "lldb/lldb-private.h"
15
16 #include "RegisterContextThreadMemory.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 RegisterContextThreadMemory::RegisterContextThreadMemory(
22     Thread &thread, lldb::addr_t register_data_addr)
23     : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),
24       m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}
25
26 RegisterContextThreadMemory::~RegisterContextThreadMemory() {}
27
28 void RegisterContextThreadMemory::UpdateRegisterContext() {
29   ThreadSP thread_sp(m_thread_wp.lock());
30   if (thread_sp) {
31     ProcessSP process_sp(thread_sp->GetProcess());
32
33     if (process_sp) {
34       const uint32_t stop_id = process_sp->GetModID().GetStopID();
35       if (m_stop_id != stop_id) {
36         m_stop_id = stop_id;
37         m_reg_ctx_sp.reset();
38       }
39       if (!m_reg_ctx_sp) {
40         ThreadSP backing_thread_sp(thread_sp->GetBackingThread());
41         if (backing_thread_sp) {
42           m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
43         } else {
44           OperatingSystem *os = process_sp->GetOperatingSystem();
45           if (os->IsOperatingSystemPluginThread(thread_sp))
46             m_reg_ctx_sp = os->CreateRegisterContextForThread(
47                 thread_sp.get(), m_register_data_addr);
48         }
49       }
50     } else {
51       m_reg_ctx_sp.reset();
52     }
53   } else {
54     m_reg_ctx_sp.reset();
55   }
56 }
57
58 //------------------------------------------------------------------
59 // Subclasses must override these functions
60 //------------------------------------------------------------------
61 void RegisterContextThreadMemory::InvalidateAllRegisters() {
62   UpdateRegisterContext();
63   if (m_reg_ctx_sp)
64     m_reg_ctx_sp->InvalidateAllRegisters();
65 }
66
67 size_t RegisterContextThreadMemory::GetRegisterCount() {
68   UpdateRegisterContext();
69   if (m_reg_ctx_sp)
70     return m_reg_ctx_sp->GetRegisterCount();
71   return 0;
72 }
73
74 const RegisterInfo *
75 RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) {
76   UpdateRegisterContext();
77   if (m_reg_ctx_sp)
78     return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
79   return NULL;
80 }
81
82 size_t RegisterContextThreadMemory::GetRegisterSetCount() {
83   UpdateRegisterContext();
84   if (m_reg_ctx_sp)
85     return m_reg_ctx_sp->GetRegisterSetCount();
86   return 0;
87 }
88
89 const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) {
90   UpdateRegisterContext();
91   if (m_reg_ctx_sp)
92     return m_reg_ctx_sp->GetRegisterSet(reg_set);
93   return NULL;
94 }
95
96 bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info,
97                                                RegisterValue &reg_value) {
98   UpdateRegisterContext();
99   if (m_reg_ctx_sp)
100     return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
101   return false;
102 }
103
104 bool RegisterContextThreadMemory::WriteRegister(
105     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
106   UpdateRegisterContext();
107   if (m_reg_ctx_sp)
108     return m_reg_ctx_sp->WriteRegister(reg_info, reg_value);
109   return false;
110 }
111
112 bool RegisterContextThreadMemory::ReadAllRegisterValues(
113     lldb::DataBufferSP &data_sp) {
114   UpdateRegisterContext();
115   if (m_reg_ctx_sp)
116     return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
117   return false;
118 }
119
120 bool RegisterContextThreadMemory::WriteAllRegisterValues(
121     const lldb::DataBufferSP &data_sp) {
122   UpdateRegisterContext();
123   if (m_reg_ctx_sp)
124     return m_reg_ctx_sp->WriteAllRegisterValues(data_sp);
125   return false;
126 }
127
128 bool RegisterContextThreadMemory::CopyFromRegisterContext(
129     lldb::RegisterContextSP reg_ctx_sp) {
130   UpdateRegisterContext();
131   if (m_reg_ctx_sp)
132     return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
133   return false;
134 }
135
136 uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber(
137     lldb::RegisterKind kind, uint32_t num) {
138   UpdateRegisterContext();
139   if (m_reg_ctx_sp)
140     return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
141   return false;
142 }
143
144 uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() {
145   UpdateRegisterContext();
146   if (m_reg_ctx_sp)
147     return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
148   return false;
149 }
150
151 uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr,
152                                                             size_t size) {
153   UpdateRegisterContext();
154   if (m_reg_ctx_sp)
155     return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
156   return 0;
157 }
158
159 bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) {
160   UpdateRegisterContext();
161   if (m_reg_ctx_sp)
162     return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx);
163   return false;
164 }
165
166 uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() {
167   UpdateRegisterContext();
168   if (m_reg_ctx_sp)
169     return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
170   return 0;
171 }
172
173 uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr,
174                                                             size_t size,
175                                                             bool read,
176                                                             bool write) {
177   UpdateRegisterContext();
178   if (m_reg_ctx_sp)
179     return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
180   return 0;
181 }
182
183 bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) {
184   UpdateRegisterContext();
185   if (m_reg_ctx_sp)
186     return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
187   return false;
188 }
189
190 bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) {
191   UpdateRegisterContext();
192   if (m_reg_ctx_sp)
193     return m_reg_ctx_sp->HardwareSingleStep(enable);
194   return false;
195 }
196
197 Status RegisterContextThreadMemory::ReadRegisterValueFromMemory(
198     const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr,
199     uint32_t src_len, RegisterValue &reg_value) {
200   UpdateRegisterContext();
201   if (m_reg_ctx_sp)
202     return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr,
203                                                      src_len, reg_value);
204   Status error;
205   error.SetErrorString("invalid register context");
206   return error;
207 }
208
209 Status RegisterContextThreadMemory::WriteRegisterValueToMemory(
210     const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr,
211     uint32_t dst_len, const RegisterValue &reg_value) {
212   UpdateRegisterContext();
213   if (m_reg_ctx_sp)
214     return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len,
215                                                     reg_value);
216   Status error;
217   error.SetErrorString("invalid register context");
218   return error;
219 }