1 //===-- NativeRegisterContextNetBSD_x86_64.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
9 #if defined(__i386__) || defined(__x86_64__)
10
11 #include "NativeRegisterContextNetBSD_x86_64.h"
12
13 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Utility/DataBufferHeap.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/RegisterValue.h"
17 #include "lldb/Utility/Status.h"
18
19 #include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h"
20 #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
21
22 // clang-format off
23 #include <sys/types.h>
24 #include <sys/ptrace.h>
25 #include <sys/sysctl.h>
26 #include <sys/uio.h>
27 #include <x86/cpu.h>
28 #include <x86/cpu_extended_state.h>
29 #include <x86/specialreg.h>
30 #include <elf.h>
31 #include <err.h>
32 #include <stdint.h>
33 #include <stdlib.h>
34 // clang-format on
35
36 using namespace lldb_private;
37 using namespace lldb_private::process_netbsd;
38
39 static const uint32_t g_gpr_regnums_x86_64[] = {
40 lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
41 lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
42 lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
43 lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
44 lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
45 lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
46 lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
47 lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
48 lldb_r8d_x86_64, // Low 32 bits or r8
49 lldb_r9d_x86_64, // Low 32 bits or r9
50 lldb_r10d_x86_64, // Low 32 bits or r10
51 lldb_r11d_x86_64, // Low 32 bits or r11
52 lldb_r12d_x86_64, // Low 32 bits or r12
53 lldb_r13d_x86_64, // Low 32 bits or r13
54 lldb_r14d_x86_64, // Low 32 bits or r14
55 lldb_r15d_x86_64, // Low 32 bits or r15
56 lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
57 lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
58 lldb_r8w_x86_64, // Low 16 bits or r8
59 lldb_r9w_x86_64, // Low 16 bits or r9
60 lldb_r10w_x86_64, // Low 16 bits or r10
61 lldb_r11w_x86_64, // Low 16 bits or r11
62 lldb_r12w_x86_64, // Low 16 bits or r12
63 lldb_r13w_x86_64, // Low 16 bits or r13
64 lldb_r14w_x86_64, // Low 16 bits or r14
65 lldb_r15w_x86_64, // Low 16 bits or r15
66 lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
67 lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
68 lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
69 lldb_r8l_x86_64, // Low 8 bits or r8
70 lldb_r9l_x86_64, // Low 8 bits or r9
71 lldb_r10l_x86_64, // Low 8 bits or r10
72 lldb_r11l_x86_64, // Low 8 bits or r11
73 lldb_r12l_x86_64, // Low 8 bits or r12
74 lldb_r13l_x86_64, // Low 8 bits or r13
75 lldb_r14l_x86_64, // Low 8 bits or r14
76 lldb_r15l_x86_64, // Low 8 bits or r15
77 LLDB_INVALID_REGNUM // register sets need to end with this flag
78 };
79 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
80 1 ==
81 k_num_gpr_registers_x86_64,
82 "g_gpr_regnums_x86_64 has wrong number of register infos");
83
84 // x86 64-bit registers available via XState.
85 static const uint32_t g_xstate_regnums_x86_64[] = {
86 lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, lldb_fop_x86_64,
87 lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64, lldb_foseg_x86_64,
88 lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64,
89 lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64,
90 lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64, lldb_st6_x86_64,
91 lldb_st7_x86_64, lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
92 lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,
93 lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64, lldb_xmm2_x86_64,
94 lldb_xmm3_x86_64, lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
95 lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,
96 lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64, lldb_xmm14_x86_64,
97 lldb_xmm15_x86_64, lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64,
98 lldb_ymm3_x86_64, lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64,
99 lldb_ymm7_x86_64, lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64,
100 lldb_ymm11_x86_64, lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64,
101 lldb_ymm15_x86_64,
102 // Note: we currently do not provide them but this is needed to avoid
103 // unnamed groups in SBFrame::GetRegisterContext().
104 lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64, lldb_bnd3_x86_64,
105 lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
106 LLDB_INVALID_REGNUM // register sets need to end with this flag
107 };
108 static_assert((sizeof(g_xstate_regnums_x86_64) /
109 sizeof(g_xstate_regnums_x86_64[0])) -
110 1 ==
111 k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64 +
112 k_num_mpx_registers_x86_64,
113 "g_xstate_regnums_x86_64 has wrong number of register infos");
114
115 // x86 debug registers.
116 static const uint32_t g_dbr_regnums_x86_64[] = {
117 lldb_dr0_x86_64, lldb_dr1_x86_64, lldb_dr2_x86_64, lldb_dr3_x86_64,
118 lldb_dr4_x86_64, lldb_dr5_x86_64, lldb_dr6_x86_64, lldb_dr7_x86_64,
119 LLDB_INVALID_REGNUM // register sets need to end with this flag
120 };
121 static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
122 1 ==
123 k_num_dbr_registers_x86_64,
124 "g_dbr_regnums_x86_64 has wrong number of register infos");
125
126 // x86 32-bit general purpose registers.
127 static const uint32_t g_gpr_regnums_i386[] = {
128 lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
129 lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
130 lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
131 lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
132 lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
133 lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
134 lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
135 lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
136 LLDB_INVALID_REGNUM // register sets need to end with this flag
137 };
138 static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
139 1 ==
140 k_num_gpr_registers_i386,
141 "g_gpr_regnums_i386 has wrong number of register infos");
142
143 // x86 32-bit registers available via XState.
144 static const uint32_t g_xstate_regnums_i386[] = {
145 lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
146 lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
147 lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
148 lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
149 lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
150 lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
151 lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
152 lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
153 lldb_xmm6_i386, lldb_xmm7_i386,
154 lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
155 lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
156 // Note: we currently do not provide them but this is needed to avoid
157 // unnamed groups in SBFrame::GetRegisterContext().
158 lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386,
159 lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386,
160 LLDB_INVALID_REGNUM // register sets need to end with this flag
161 };
162 static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) -
163 1 ==
164 k_num_fpr_registers_i386 + k_num_avx_registers_i386 + k_num_mpx_registers_i386,
165 "g_xstate_regnums_i386 has wrong number of register infos");
166
167 // x86 debug registers.
168 static const uint32_t g_dbr_regnums_i386[] = {
169 lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386,
170 lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386,
171 LLDB_INVALID_REGNUM // register sets need to end with this flag
172 };
173 static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
174 1 ==
175 k_num_dbr_registers_i386,
176 "g_dbr_regnums_i386 has wrong number of register infos");
177
178
179 // Number of register sets provided by this context.
180 enum { k_num_register_sets = 4 };
181
182 // Register sets for x86 32-bit.
183 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
184 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
185 g_gpr_regnums_i386},
186 {"Extended State Registers", "xstate",
187 k_num_avx_registers_i386 + k_num_mpx_registers_i386,
188 g_xstate_regnums_i386},
189 {"Debug Registers", "dbr", k_num_dbr_registers_i386,
190 g_dbr_regnums_i386},
191 };
192
193 // Register sets for x86 64-bit.
194 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
195 {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
196 g_gpr_regnums_x86_64},
197 {"Extended State Registers", "xstate",
198 k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64,
199 g_xstate_regnums_x86_64},
200 {"Debug Registers", "dbr", k_num_dbr_registers_x86_64,
201 g_dbr_regnums_x86_64},
202 };
203
204 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
205
206 NativeRegisterContextNetBSD *
CreateHostNativeRegisterContextNetBSD(const ArchSpec & target_arch,NativeThreadProtocol & native_thread)207 NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
208 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
209 return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread);
210 }
211
212 // NativeRegisterContextNetBSD_x86_64 members.
213
214 static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec & target_arch)215 CreateRegisterInfoInterface(const ArchSpec &target_arch) {
216 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
217 // 32-bit hosts run with a RegisterContextNetBSD_i386 context.
218 return new RegisterContextNetBSD_i386(target_arch);
219 } else {
220 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
221 "Register setting path assumes this is a 64-bit host");
222 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
223 // register context.
224 return new RegisterContextNetBSD_x86_64(target_arch);
225 }
226 }
227
NativeRegisterContextNetBSD_x86_64(const ArchSpec & target_arch,NativeThreadProtocol & native_thread)228 NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
229 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
230 : NativeRegisterContextRegisterInfo(
231 native_thread, CreateRegisterInfoInterface(target_arch)),
232 m_gpr(), m_xstate(), m_dbr() {}
233
234 // CONSIDER after local and llgs debugging are merged, register set support can
235 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
GetRegisterSetCount() const236 uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
237 uint32_t sets = 0;
238 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
239 if (GetSetForNativeRegNum(set_index) != -1)
240 ++sets;
241 }
242
243 return sets;
244 }
245
246 const RegisterSet *
GetRegisterSet(uint32_t set_index) const247 NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
248 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
249 case llvm::Triple::x86:
250 return &g_reg_sets_i386[set_index];
251 case llvm::Triple::x86_64:
252 return &g_reg_sets_x86_64[set_index];
253 default:
254 llvm_unreachable("Unhandled target architecture.");
255 }
256 }
257
RegNumX86ToX86_64(int regnum)258 static constexpr int RegNumX86ToX86_64(int regnum) {
259 switch (regnum) {
260 case lldb_eax_i386:
261 return lldb_rax_x86_64;
262 case lldb_ebx_i386:
263 return lldb_rbx_x86_64;
264 case lldb_ecx_i386:
265 return lldb_rcx_x86_64;
266 case lldb_edx_i386:
267 return lldb_rdx_x86_64;
268 case lldb_edi_i386:
269 return lldb_rdi_x86_64;
270 case lldb_esi_i386:
271 return lldb_rsi_x86_64;
272 case lldb_ebp_i386:
273 return lldb_rbp_x86_64;
274 case lldb_esp_i386:
275 return lldb_rsp_x86_64;
276 case lldb_eip_i386:
277 return lldb_rip_x86_64;
278 case lldb_eflags_i386:
279 return lldb_rflags_x86_64;
280 case lldb_cs_i386:
281 return lldb_cs_x86_64;
282 case lldb_fs_i386:
283 return lldb_fs_x86_64;
284 case lldb_gs_i386:
285 return lldb_gs_x86_64;
286 case lldb_ss_i386:
287 return lldb_ss_x86_64;
288 case lldb_ds_i386:
289 return lldb_ds_x86_64;
290 case lldb_es_i386:
291 return lldb_es_x86_64;
292 case lldb_fctrl_i386:
293 return lldb_fctrl_x86_64;
294 case lldb_fstat_i386:
295 return lldb_fstat_x86_64;
296 case lldb_ftag_i386:
297 return lldb_ftag_x86_64;
298 case lldb_fop_i386:
299 return lldb_fop_x86_64;
300 case lldb_fiseg_i386:
301 return lldb_fiseg_x86_64;
302 case lldb_fioff_i386:
303 return lldb_fioff_x86_64;
304 case lldb_foseg_i386:
305 return lldb_foseg_x86_64;
306 case lldb_fooff_i386:
307 return lldb_fooff_x86_64;
308 case lldb_mxcsr_i386:
309 return lldb_mxcsr_x86_64;
310 case lldb_mxcsrmask_i386:
311 return lldb_mxcsrmask_x86_64;
312 case lldb_st0_i386:
313 case lldb_st1_i386:
314 case lldb_st2_i386:
315 case lldb_st3_i386:
316 case lldb_st4_i386:
317 case lldb_st5_i386:
318 case lldb_st6_i386:
319 case lldb_st7_i386:
320 return lldb_st0_x86_64 + regnum - lldb_st0_i386;
321 case lldb_mm0_i386:
322 case lldb_mm1_i386:
323 case lldb_mm2_i386:
324 case lldb_mm3_i386:
325 case lldb_mm4_i386:
326 case lldb_mm5_i386:
327 case lldb_mm6_i386:
328 case lldb_mm7_i386:
329 return lldb_mm0_x86_64 + regnum - lldb_mm0_i386;
330 case lldb_xmm0_i386:
331 case lldb_xmm1_i386:
332 case lldb_xmm2_i386:
333 case lldb_xmm3_i386:
334 case lldb_xmm4_i386:
335 case lldb_xmm5_i386:
336 case lldb_xmm6_i386:
337 case lldb_xmm7_i386:
338 return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386;
339 case lldb_ymm0_i386:
340 case lldb_ymm1_i386:
341 case lldb_ymm2_i386:
342 case lldb_ymm3_i386:
343 case lldb_ymm4_i386:
344 case lldb_ymm5_i386:
345 case lldb_ymm6_i386:
346 case lldb_ymm7_i386:
347 return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386;
348 case lldb_bnd0_i386:
349 case lldb_bnd1_i386:
350 case lldb_bnd2_i386:
351 case lldb_bnd3_i386:
352 return lldb_bnd0_x86_64 + regnum - lldb_bnd0_i386;
353 case lldb_bndcfgu_i386:
354 return lldb_bndcfgu_x86_64;
355 case lldb_bndstatus_i386:
356 return lldb_bndstatus_x86_64;
357 case lldb_dr0_i386:
358 case lldb_dr1_i386:
359 case lldb_dr2_i386:
360 case lldb_dr3_i386:
361 case lldb_dr4_i386:
362 case lldb_dr5_i386:
363 case lldb_dr6_i386:
364 case lldb_dr7_i386:
365 return lldb_dr0_x86_64 + regnum - lldb_dr0_i386;
366 default:
367 llvm_unreachable("Unhandled i386 register.");
368 }
369 }
370
GetSetForNativeRegNum(int reg_num) const371 int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
372 int reg_num) const {
373 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
374 case llvm::Triple::x86:
375 if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386)
376 return GPRegSet;
377 if (reg_num >= k_first_fpr_i386 && reg_num <= k_last_fpr_i386)
378 return XStateRegSet;
379 if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386)
380 return XStateRegSet; // AVX
381 if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386)
382 return -1; // MPXR
383 if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386)
384 return -1; // MPXC
385 if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386)
386 return DBRegSet; // DBR
387 break;
388 case llvm::Triple::x86_64:
389 if (reg_num >= k_first_gpr_x86_64 && reg_num <= k_last_gpr_x86_64)
390 return GPRegSet;
391 if (reg_num >= k_first_fpr_x86_64 && reg_num <= k_last_fpr_x86_64)
392 return XStateRegSet;
393 if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64)
394 return XStateRegSet; // AVX
395 if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64)
396 return -1; // MPXR
397 if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64)
398 return -1; // MPXC
399 if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64)
400 return DBRegSet; // DBR
401 break;
402 default:
403 llvm_unreachable("Unhandled target architecture.");
404 }
405
406 llvm_unreachable("Register does not belong to any register set");
407 }
408
ReadRegisterSet(uint32_t set)409 Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
410 switch (set) {
411 case GPRegSet:
412 return DoRegisterSet(PT_GETREGS, &m_gpr);
413 case DBRegSet:
414 return DoRegisterSet(PT_GETDBREGS, &m_dbr);
415 case XStateRegSet: {
416 struct iovec iov = {&m_xstate, sizeof(m_xstate)};
417 return DoRegisterSet(PT_GETXSTATE, &iov);
418 }
419 }
420 llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet");
421 }
422
WriteRegisterSet(uint32_t set)423 Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) {
424 switch (set) {
425 case GPRegSet:
426 return DoRegisterSet(PT_SETREGS, &m_gpr);
427 case DBRegSet:
428 return DoRegisterSet(PT_SETDBREGS, &m_dbr);
429 case XStateRegSet: {
430 struct iovec iov = {&m_xstate, sizeof(m_xstate)};
431 return DoRegisterSet(PT_SETXSTATE, &iov);
432 }
433 }
434 llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet");
435 }
436
437 Status
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)438 NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
439 RegisterValue ®_value) {
440 Status error;
441
442 if (!reg_info) {
443 error.SetErrorString("reg_info NULL");
444 return error;
445 }
446
447 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
448 if (reg == LLDB_INVALID_REGNUM) {
449 // This is likely an internal register for lldb use only and should not be
450 // directly queried.
451 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
452 "register, cannot read directly",
453 reg_info->name);
454 return error;
455 }
456
457 int set = GetSetForNativeRegNum(reg);
458 if (set == -1) {
459 // This is likely an internal register for lldb use only and should not be
460 // directly queried.
461 error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
462 reg_info->name);
463 return error;
464 }
465
466 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
467 case llvm::Triple::x86_64:
468 break;
469 case llvm::Triple::x86:
470 reg = RegNumX86ToX86_64(reg);
471 break;
472 default:
473 llvm_unreachable("Unhandled target architecture.");
474 }
475
476 error = ReadRegisterSet(set);
477 if (error.Fail())
478 return error;
479
480 switch (reg) {
481 #if defined(__x86_64__)
482 case lldb_rax_x86_64:
483 reg_value = (uint64_t)m_gpr.regs[_REG_RAX];
484 break;
485 case lldb_rbx_x86_64:
486 reg_value = (uint64_t)m_gpr.regs[_REG_RBX];
487 break;
488 case lldb_rcx_x86_64:
489 reg_value = (uint64_t)m_gpr.regs[_REG_RCX];
490 break;
491 case lldb_rdx_x86_64:
492 reg_value = (uint64_t)m_gpr.regs[_REG_RDX];
493 break;
494 case lldb_rdi_x86_64:
495 reg_value = (uint64_t)m_gpr.regs[_REG_RDI];
496 break;
497 case lldb_rsi_x86_64:
498 reg_value = (uint64_t)m_gpr.regs[_REG_RSI];
499 break;
500 case lldb_rbp_x86_64:
501 reg_value = (uint64_t)m_gpr.regs[_REG_RBP];
502 break;
503 case lldb_rsp_x86_64:
504 reg_value = (uint64_t)m_gpr.regs[_REG_RSP];
505 break;
506 case lldb_r8_x86_64:
507 reg_value = (uint64_t)m_gpr.regs[_REG_R8];
508 break;
509 case lldb_r9_x86_64:
510 reg_value = (uint64_t)m_gpr.regs[_REG_R9];
511 break;
512 case lldb_r10_x86_64:
513 reg_value = (uint64_t)m_gpr.regs[_REG_R10];
514 break;
515 case lldb_r11_x86_64:
516 reg_value = (uint64_t)m_gpr.regs[_REG_R11];
517 break;
518 case lldb_r12_x86_64:
519 reg_value = (uint64_t)m_gpr.regs[_REG_R12];
520 break;
521 case lldb_r13_x86_64:
522 reg_value = (uint64_t)m_gpr.regs[_REG_R13];
523 break;
524 case lldb_r14_x86_64:
525 reg_value = (uint64_t)m_gpr.regs[_REG_R14];
526 break;
527 case lldb_r15_x86_64:
528 reg_value = (uint64_t)m_gpr.regs[_REG_R15];
529 break;
530 case lldb_rip_x86_64:
531 reg_value = (uint64_t)m_gpr.regs[_REG_RIP];
532 break;
533 case lldb_rflags_x86_64:
534 reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS];
535 break;
536 case lldb_cs_x86_64:
537 reg_value = (uint64_t)m_gpr.regs[_REG_CS];
538 break;
539 case lldb_fs_x86_64:
540 reg_value = (uint16_t)m_gpr.regs[_REG_FS];
541 break;
542 case lldb_gs_x86_64:
543 reg_value = (uint16_t)m_gpr.regs[_REG_GS];
544 break;
545 case lldb_ss_x86_64:
546 reg_value = (uint64_t)m_gpr.regs[_REG_SS];
547 break;
548 case lldb_ds_x86_64:
549 reg_value = (uint16_t)m_gpr.regs[_REG_DS];
550 break;
551 case lldb_es_x86_64:
552 reg_value = (uint16_t)m_gpr.regs[_REG_ES];
553 break;
554 #else
555 case lldb_rax_x86_64:
556 reg_value = (uint32_t)m_gpr.r_eax;
557 break;
558 case lldb_rbx_x86_64:
559 reg_value = (uint32_t)m_gpr.r_ebx;
560 break;
561 case lldb_rcx_x86_64:
562 reg_value = (uint32_t)m_gpr.r_ecx;
563 break;
564 case lldb_rdx_x86_64:
565 reg_value = (uint32_t)m_gpr.r_edx;
566 break;
567 case lldb_rdi_x86_64:
568 reg_value = (uint32_t)m_gpr.r_edi;
569 break;
570 case lldb_rsi_x86_64:
571 reg_value = (uint32_t)m_gpr.r_esi;
572 break;
573 case lldb_rsp_x86_64:
574 reg_value = (uint32_t)m_gpr.r_esp;
575 break;
576 case lldb_rbp_x86_64:
577 reg_value = (uint32_t)m_gpr.r_ebp;
578 break;
579 case lldb_rip_x86_64:
580 reg_value = (uint32_t)m_gpr.r_eip;
581 break;
582 case lldb_rflags_x86_64:
583 reg_value = (uint32_t)m_gpr.r_eflags;
584 break;
585 case lldb_cs_x86_64:
586 reg_value = (uint32_t)m_gpr.r_cs;
587 break;
588 case lldb_fs_x86_64:
589 reg_value = (uint16_t)m_gpr.r_fs;
590 break;
591 case lldb_gs_x86_64:
592 reg_value = (uint16_t)m_gpr.r_gs;
593 break;
594 case lldb_ss_x86_64:
595 reg_value = (uint32_t)m_gpr.r_ss;
596 break;
597 case lldb_ds_x86_64:
598 reg_value = (uint16_t)m_gpr.r_ds;
599 break;
600 case lldb_es_x86_64:
601 reg_value = (uint16_t)m_gpr.r_es;
602 break;
603 #endif
604 case lldb_fctrl_x86_64:
605 reg_value = (uint16_t)m_xstate.xs_fxsave.fx_cw;
606 break;
607 case lldb_fstat_x86_64:
608 reg_value = (uint16_t)m_xstate.xs_fxsave.fx_sw;
609 break;
610 case lldb_ftag_x86_64: {
611 llvm::ArrayRef<MMSReg> st_regs{
612 reinterpret_cast<MMSReg *>(m_xstate.xs_fxsave.fx_87_ac), 8};
613 reg_value = (uint16_t)AbridgedToFullTagWord(
614 m_xstate.xs_fxsave.fx_tw, m_xstate.xs_fxsave.fx_sw, st_regs);
615 break;
616 }
617 case lldb_fop_x86_64:
618 reg_value = (uint64_t)m_xstate.xs_fxsave.fx_opcode;
619 break;
620 case lldb_fiseg_x86_64:
621 reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg;
622 break;
623 case lldb_fioff_x86_64:
624 reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_off;
625 break;
626 case lldb_fip_x86_64:
627 reg_value = (uint64_t)m_xstate.xs_fxsave.fx_ip.fa_64;
628 break;
629 case lldb_foseg_x86_64:
630 reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg;
631 break;
632 case lldb_fooff_x86_64:
633 reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_off;
634 break;
635 case lldb_fdp_x86_64:
636 reg_value = (uint64_t)m_xstate.xs_fxsave.fx_dp.fa_64;
637 break;
638 case lldb_mxcsr_x86_64:
639 reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr;
640 break;
641 case lldb_mxcsrmask_x86_64:
642 reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr_mask;
643 break;
644 case lldb_st0_x86_64:
645 case lldb_st1_x86_64:
646 case lldb_st2_x86_64:
647 case lldb_st3_x86_64:
648 case lldb_st4_x86_64:
649 case lldb_st5_x86_64:
650 case lldb_st6_x86_64:
651 case lldb_st7_x86_64:
652 reg_value.SetBytes(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
653 reg_info->byte_size, endian::InlHostByteOrder());
654 break;
655 case lldb_mm0_x86_64:
656 case lldb_mm1_x86_64:
657 case lldb_mm2_x86_64:
658 case lldb_mm3_x86_64:
659 case lldb_mm4_x86_64:
660 case lldb_mm5_x86_64:
661 case lldb_mm6_x86_64:
662 case lldb_mm7_x86_64:
663 reg_value.SetBytes(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
664 reg_info->byte_size, endian::InlHostByteOrder());
665 break;
666 case lldb_xmm0_x86_64:
667 case lldb_xmm1_x86_64:
668 case lldb_xmm2_x86_64:
669 case lldb_xmm3_x86_64:
670 case lldb_xmm4_x86_64:
671 case lldb_xmm5_x86_64:
672 case lldb_xmm6_x86_64:
673 case lldb_xmm7_x86_64:
674 case lldb_xmm8_x86_64:
675 case lldb_xmm9_x86_64:
676 case lldb_xmm10_x86_64:
677 case lldb_xmm11_x86_64:
678 case lldb_xmm12_x86_64:
679 case lldb_xmm13_x86_64:
680 case lldb_xmm14_x86_64:
681 case lldb_xmm15_x86_64:
682 if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
683 error.SetErrorStringWithFormat(
684 "register \"%s\" not supported by CPU/kernel", reg_info->name);
685 } else {
686 reg_value.SetBytes(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
687 reg_info->byte_size, endian::InlHostByteOrder());
688 }
689 break;
690 case lldb_ymm0_x86_64:
691 case lldb_ymm1_x86_64:
692 case lldb_ymm2_x86_64:
693 case lldb_ymm3_x86_64:
694 case lldb_ymm4_x86_64:
695 case lldb_ymm5_x86_64:
696 case lldb_ymm6_x86_64:
697 case lldb_ymm7_x86_64:
698 case lldb_ymm8_x86_64:
699 case lldb_ymm9_x86_64:
700 case lldb_ymm10_x86_64:
701 case lldb_ymm11_x86_64:
702 case lldb_ymm12_x86_64:
703 case lldb_ymm13_x86_64:
704 case lldb_ymm14_x86_64:
705 case lldb_ymm15_x86_64:
706 if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
707 !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
708 error.SetErrorStringWithFormat(
709 "register \"%s\" not supported by CPU/kernel", reg_info->name);
710 } else {
711 uint32_t reg_index = reg - lldb_ymm0_x86_64;
712 YMMReg ymm =
713 XStateToYMM(m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
714 m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
715 reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
716 endian::InlHostByteOrder());
717 }
718 break;
719 case lldb_dr0_x86_64:
720 case lldb_dr1_x86_64:
721 case lldb_dr2_x86_64:
722 case lldb_dr3_x86_64:
723 case lldb_dr4_x86_64:
724 case lldb_dr5_x86_64:
725 case lldb_dr6_x86_64:
726 case lldb_dr7_x86_64:
727 reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
728 break;
729 default:
730 llvm_unreachable("Reading unknown/unsupported register");
731 }
732
733 return error;
734 }
735
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)736 Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
737 const RegisterInfo *reg_info, const RegisterValue ®_value) {
738
739 Status error;
740
741 if (!reg_info) {
742 error.SetErrorString("reg_info NULL");
743 return error;
744 }
745
746 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
747 if (reg == LLDB_INVALID_REGNUM) {
748 // This is likely an internal register for lldb use only and should not be
749 // directly queried.
750 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
751 "register, cannot read directly",
752 reg_info->name);
753 return error;
754 }
755
756 int set = GetSetForNativeRegNum(reg);
757 if (set == -1) {
758 // This is likely an internal register for lldb use only and should not be
759 // directly queried.
760 error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
761 reg_info->name);
762 return error;
763 }
764
765 uint64_t new_xstate_bv = XCR0_X87; // the most common case
766
767 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
768 case llvm::Triple::x86_64:
769 break;
770 case llvm::Triple::x86:
771 reg = RegNumX86ToX86_64(reg);
772 break;
773 default:
774 llvm_unreachable("Unhandled target architecture.");
775 }
776
777 error = ReadRegisterSet(set);
778 if (error.Fail())
779 return error;
780
781 switch (reg) {
782 #if defined(__x86_64__)
783 case lldb_rax_x86_64:
784 m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
785 break;
786 case lldb_rbx_x86_64:
787 m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
788 break;
789 case lldb_rcx_x86_64:
790 m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
791 break;
792 case lldb_rdx_x86_64:
793 m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
794 break;
795 case lldb_rdi_x86_64:
796 m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
797 break;
798 case lldb_rsi_x86_64:
799 m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
800 break;
801 case lldb_rbp_x86_64:
802 m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
803 break;
804 case lldb_rsp_x86_64:
805 m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
806 break;
807 case lldb_r8_x86_64:
808 m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
809 break;
810 case lldb_r9_x86_64:
811 m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
812 break;
813 case lldb_r10_x86_64:
814 m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
815 break;
816 case lldb_r11_x86_64:
817 m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
818 break;
819 case lldb_r12_x86_64:
820 m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
821 break;
822 case lldb_r13_x86_64:
823 m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
824 break;
825 case lldb_r14_x86_64:
826 m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
827 break;
828 case lldb_r15_x86_64:
829 m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
830 break;
831 case lldb_rip_x86_64:
832 m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
833 break;
834 case lldb_rflags_x86_64:
835 m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
836 break;
837 case lldb_cs_x86_64:
838 m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
839 break;
840 case lldb_fs_x86_64:
841 m_gpr.regs[_REG_FS] = reg_value.GetAsUInt16();
842 break;
843 case lldb_gs_x86_64:
844 m_gpr.regs[_REG_GS] = reg_value.GetAsUInt16();
845 break;
846 case lldb_ss_x86_64:
847 m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
848 break;
849 case lldb_ds_x86_64:
850 m_gpr.regs[_REG_DS] = reg_value.GetAsUInt16();
851 break;
852 case lldb_es_x86_64:
853 m_gpr.regs[_REG_ES] = reg_value.GetAsUInt16();
854 break;
855 #else
856 case lldb_rax_x86_64:
857 m_gpr.r_eax = reg_value.GetAsUInt32();
858 break;
859 case lldb_rbx_x86_64:
860 m_gpr.r_ebx = reg_value.GetAsUInt32();
861 break;
862 case lldb_rcx_x86_64:
863 m_gpr.r_ecx = reg_value.GetAsUInt32();
864 break;
865 case lldb_rdx_x86_64:
866 m_gpr.r_edx = reg_value.GetAsUInt32();
867 break;
868 case lldb_rdi_x86_64:
869 m_gpr.r_edi = reg_value.GetAsUInt32();
870 break;
871 case lldb_rsi_x86_64:
872 m_gpr.r_esi = reg_value.GetAsUInt32();
873 break;
874 case lldb_rsp_x86_64:
875 m_gpr.r_esp = reg_value.GetAsUInt32();
876 break;
877 case lldb_rbp_x86_64:
878 m_gpr.r_ebp = reg_value.GetAsUInt32();
879 break;
880 case lldb_rip_x86_64:
881 m_gpr.r_eip = reg_value.GetAsUInt32();
882 break;
883 case lldb_rflags_x86_64:
884 m_gpr.r_eflags = reg_value.GetAsUInt32();
885 break;
886 case lldb_cs_x86_64:
887 m_gpr.r_cs = reg_value.GetAsUInt32();
888 break;
889 case lldb_fs_x86_64:
890 m_gpr.r_fs = reg_value.GetAsUInt16();
891 break;
892 case lldb_gs_x86_64:
893 m_gpr.r_gs = reg_value.GetAsUInt16();
894 break;
895 case lldb_ss_x86_64:
896 m_gpr.r_ss = reg_value.GetAsUInt32();
897 break;
898 case lldb_ds_x86_64:
899 m_gpr.r_ds = reg_value.GetAsUInt16();
900 break;
901 case lldb_es_x86_64:
902 m_gpr.r_es = reg_value.GetAsUInt16();
903 break;
904 #endif
905 case lldb_fctrl_x86_64:
906 m_xstate.xs_fxsave.fx_cw = reg_value.GetAsUInt16();
907 break;
908 case lldb_fstat_x86_64:
909 m_xstate.xs_fxsave.fx_sw = reg_value.GetAsUInt16();
910 break;
911 case lldb_ftag_x86_64:
912 m_xstate.xs_fxsave.fx_tw = FullToAbridgedTagWord(reg_value.GetAsUInt16());
913 break;
914 case lldb_fop_x86_64:
915 m_xstate.xs_fxsave.fx_opcode = reg_value.GetAsUInt16();
916 break;
917 case lldb_fiseg_x86_64:
918 m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg = reg_value.GetAsUInt32();
919 break;
920 case lldb_fioff_x86_64:
921 m_xstate.xs_fxsave.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
922 break;
923 case lldb_fip_x86_64:
924 m_xstate.xs_fxsave.fx_ip.fa_64 = reg_value.GetAsUInt64();
925 break;
926 case lldb_foseg_x86_64:
927 m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32();
928 break;
929 case lldb_fooff_x86_64:
930 m_xstate.xs_fxsave.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
931 break;
932 case lldb_fdp_x86_64:
933 m_xstate.xs_fxsave.fx_dp.fa_64 = reg_value.GetAsUInt64();
934 break;
935 case lldb_mxcsr_x86_64:
936 m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32();
937 new_xstate_bv = XCR0_SSE;
938 break;
939 case lldb_mxcsrmask_x86_64:
940 m_xstate.xs_fxsave.fx_mxcsr_mask = reg_value.GetAsUInt32();
941 new_xstate_bv = XCR0_SSE;
942 break;
943 case lldb_st0_x86_64:
944 case lldb_st1_x86_64:
945 case lldb_st2_x86_64:
946 case lldb_st3_x86_64:
947 case lldb_st4_x86_64:
948 case lldb_st5_x86_64:
949 case lldb_st6_x86_64:
950 case lldb_st7_x86_64:
951 ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
952 reg_value.GetBytes(), reg_value.GetByteSize());
953 break;
954 case lldb_mm0_x86_64:
955 case lldb_mm1_x86_64:
956 case lldb_mm2_x86_64:
957 case lldb_mm3_x86_64:
958 case lldb_mm4_x86_64:
959 case lldb_mm5_x86_64:
960 case lldb_mm6_x86_64:
961 case lldb_mm7_x86_64:
962 ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
963 reg_value.GetBytes(), reg_value.GetByteSize());
964 break;
965 case lldb_xmm0_x86_64:
966 case lldb_xmm1_x86_64:
967 case lldb_xmm2_x86_64:
968 case lldb_xmm3_x86_64:
969 case lldb_xmm4_x86_64:
970 case lldb_xmm5_x86_64:
971 case lldb_xmm6_x86_64:
972 case lldb_xmm7_x86_64:
973 case lldb_xmm8_x86_64:
974 case lldb_xmm9_x86_64:
975 case lldb_xmm10_x86_64:
976 case lldb_xmm11_x86_64:
977 case lldb_xmm12_x86_64:
978 case lldb_xmm13_x86_64:
979 case lldb_xmm14_x86_64:
980 case lldb_xmm15_x86_64:
981 if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
982 error.SetErrorStringWithFormat(
983 "register \"%s\" not supported by CPU/kernel", reg_info->name);
984 } else {
985 ::memcpy(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
986 reg_value.GetBytes(), reg_value.GetByteSize());
987 new_xstate_bv = XCR0_SSE;
988 }
989 break;
990 case lldb_ymm0_x86_64:
991 case lldb_ymm1_x86_64:
992 case lldb_ymm2_x86_64:
993 case lldb_ymm3_x86_64:
994 case lldb_ymm4_x86_64:
995 case lldb_ymm5_x86_64:
996 case lldb_ymm6_x86_64:
997 case lldb_ymm7_x86_64:
998 case lldb_ymm8_x86_64:
999 case lldb_ymm9_x86_64:
1000 case lldb_ymm10_x86_64:
1001 case lldb_ymm11_x86_64:
1002 case lldb_ymm12_x86_64:
1003 case lldb_ymm13_x86_64:
1004 case lldb_ymm14_x86_64:
1005 case lldb_ymm15_x86_64:
1006 if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
1007 !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
1008 error.SetErrorStringWithFormat(
1009 "register \"%s\" not supported by CPU/kernel", reg_info->name);
1010 } else {
1011 uint32_t reg_index = reg - lldb_ymm0_x86_64;
1012 YMMReg ymm;
1013 ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
1014 YMMToXState(ymm, m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
1015 m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
1016 new_xstate_bv = XCR0_SSE | XCR0_YMM_Hi128;
1017 }
1018 break;
1019 case lldb_dr0_x86_64:
1020 case lldb_dr1_x86_64:
1021 case lldb_dr2_x86_64:
1022 case lldb_dr3_x86_64:
1023 case lldb_dr4_x86_64:
1024 case lldb_dr5_x86_64:
1025 case lldb_dr6_x86_64:
1026 case lldb_dr7_x86_64:
1027 m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
1028 break;
1029 default:
1030 llvm_unreachable("Reading unknown/unsupported register");
1031 }
1032
1033 if (set == XStateRegSet)
1034 m_xstate.xs_xstate_bv |= new_xstate_bv;
1035
1036 return WriteRegisterSet(set);
1037 }
1038
ReadAllRegisterValues(lldb::DataBufferSP & data_sp)1039 Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
1040 lldb::DataBufferSP &data_sp) {
1041 Status error;
1042
1043 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
1044 error = ReadRegisterSet(GPRegSet);
1045 if (error.Fail())
1046 return error;
1047
1048 uint8_t *dst = data_sp->GetBytes();
1049 ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
1050 dst += GetRegisterInfoInterface().GetGPRSize();
1051
1052 return error;
1053 }
1054
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)1055 Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
1056 const lldb::DataBufferSP &data_sp) {
1057 Status error;
1058
1059 if (!data_sp) {
1060 error.SetErrorStringWithFormat(
1061 "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided",
1062 __FUNCTION__);
1063 return error;
1064 }
1065
1066 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
1067 error.SetErrorStringWithFormat(
1068 "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched "
1069 "data size, expected %zu, actual %" PRIu64,
1070 __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
1071 return error;
1072 }
1073
1074 uint8_t *src = data_sp->GetBytes();
1075 if (src == nullptr) {
1076 error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s "
1077 "DataBuffer::GetBytes() returned a null "
1078 "pointer",
1079 __FUNCTION__);
1080 return error;
1081 }
1082 ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
1083
1084 error = WriteRegisterSet(GPRegSet);
1085 if (error.Fail())
1086 return error;
1087 src += GetRegisterInfoInterface().GetGPRSize();
1088
1089 return error;
1090 }
1091
GetDR(int num) const1092 int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
1093 assert(num >= 0 && num <= 7);
1094 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1095 case llvm::Triple::x86:
1096 return lldb_dr0_i386 + num;
1097 case llvm::Triple::x86_64:
1098 return lldb_dr0_x86_64 + num;
1099 default:
1100 llvm_unreachable("Unhandled target architecture.");
1101 }
1102 }
1103
CopyHardwareWatchpointsFrom(NativeRegisterContextNetBSD & source)1104 llvm::Error NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
1105 NativeRegisterContextNetBSD &source) {
1106 auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
1107 Status res = r_source.ReadRegisterSet(DBRegSet);
1108 if (!res.Fail()) {
1109 // copy dbregs only if any watchpoints were set
1110 if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
1111 return llvm::Error::success();
1112
1113 m_dbr = r_source.m_dbr;
1114 res = WriteRegisterSet(DBRegSet);
1115 }
1116 return res.ToError();
1117 }
1118
1119 #endif // defined(__x86_64__)
1120