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 // Private namespace.
40 
41 namespace {
42 // x86 64-bit general purpose registers.
43 static const uint32_t g_gpr_regnums_x86_64[] = {
44     lldb_rax_x86_64,    lldb_rbx_x86_64,    lldb_rcx_x86_64, lldb_rdx_x86_64,
45     lldb_rdi_x86_64,    lldb_rsi_x86_64,    lldb_rbp_x86_64, lldb_rsp_x86_64,
46     lldb_r8_x86_64,     lldb_r9_x86_64,     lldb_r10_x86_64, lldb_r11_x86_64,
47     lldb_r12_x86_64,    lldb_r13_x86_64,    lldb_r14_x86_64, lldb_r15_x86_64,
48     lldb_rip_x86_64,    lldb_rflags_x86_64, lldb_cs_x86_64,  lldb_fs_x86_64,
49     lldb_gs_x86_64,     lldb_ss_x86_64,     lldb_ds_x86_64,  lldb_es_x86_64,
50     lldb_eax_x86_64,    lldb_ebx_x86_64,    lldb_ecx_x86_64, lldb_edx_x86_64,
51     lldb_edi_x86_64,    lldb_esi_x86_64,    lldb_ebp_x86_64, lldb_esp_x86_64,
52     lldb_r8d_x86_64,  // Low 32 bits or r8
53     lldb_r9d_x86_64,  // Low 32 bits or r9
54     lldb_r10d_x86_64, // Low 32 bits or r10
55     lldb_r11d_x86_64, // Low 32 bits or r11
56     lldb_r12d_x86_64, // Low 32 bits or r12
57     lldb_r13d_x86_64, // Low 32 bits or r13
58     lldb_r14d_x86_64, // Low 32 bits or r14
59     lldb_r15d_x86_64, // Low 32 bits or r15
60     lldb_ax_x86_64,     lldb_bx_x86_64,     lldb_cx_x86_64,  lldb_dx_x86_64,
61     lldb_di_x86_64,     lldb_si_x86_64,     lldb_bp_x86_64,  lldb_sp_x86_64,
62     lldb_r8w_x86_64,  // Low 16 bits or r8
63     lldb_r9w_x86_64,  // Low 16 bits or r9
64     lldb_r10w_x86_64, // Low 16 bits or r10
65     lldb_r11w_x86_64, // Low 16 bits or r11
66     lldb_r12w_x86_64, // Low 16 bits or r12
67     lldb_r13w_x86_64, // Low 16 bits or r13
68     lldb_r14w_x86_64, // Low 16 bits or r14
69     lldb_r15w_x86_64, // Low 16 bits or r15
70     lldb_ah_x86_64,     lldb_bh_x86_64,     lldb_ch_x86_64,  lldb_dh_x86_64,
71     lldb_al_x86_64,     lldb_bl_x86_64,     lldb_cl_x86_64,  lldb_dl_x86_64,
72     lldb_dil_x86_64,    lldb_sil_x86_64,    lldb_bpl_x86_64, lldb_spl_x86_64,
73     lldb_r8l_x86_64,    // Low 8 bits or r8
74     lldb_r9l_x86_64,    // Low 8 bits or r9
75     lldb_r10l_x86_64,   // Low 8 bits or r10
76     lldb_r11l_x86_64,   // Low 8 bits or r11
77     lldb_r12l_x86_64,   // Low 8 bits or r12
78     lldb_r13l_x86_64,   // Low 8 bits or r13
79     lldb_r14l_x86_64,   // Low 8 bits or r14
80     lldb_r15l_x86_64,   // Low 8 bits or r15
81     LLDB_INVALID_REGNUM // register sets need to end with this flag
82 };
83 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
84                       1 ==
85                   k_num_gpr_registers_x86_64,
86               "g_gpr_regnums_x86_64 has wrong number of register infos");
87 
88 // x86 64-bit floating point registers.
89 static const uint32_t g_fpu_regnums_x86_64[] = {
90     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
91     lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
92     lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
93     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
94     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
95     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
96     lldb_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
97     lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
98     lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
99     lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
100     lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
101     lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
102     lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
103     lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_x86_64,
104     LLDB_INVALID_REGNUM // register sets need to end with this flag
105 };
106 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
107                       1 ==
108                   k_num_fpr_registers_x86_64,
109               "g_fpu_regnums_x86_64 has wrong number of register infos");
110 
111 // x86 64-bit registers available via XState.
112 static const uint32_t g_xstate_regnums_x86_64[] = {
113     lldb_ymm0_x86_64,   lldb_ymm1_x86_64,  lldb_ymm2_x86_64,  lldb_ymm3_x86_64,
114     lldb_ymm4_x86_64,   lldb_ymm5_x86_64,  lldb_ymm6_x86_64,  lldb_ymm7_x86_64,
115     lldb_ymm8_x86_64,   lldb_ymm9_x86_64,  lldb_ymm10_x86_64, lldb_ymm11_x86_64,
116     lldb_ymm12_x86_64,  lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
117     // Note: we currently do not provide them but this is needed to avoid
118     // unnamed groups in SBFrame::GetRegisterContext().
119     lldb_bnd0_x86_64,    lldb_bnd1_x86_64,    lldb_bnd2_x86_64,
120     lldb_bnd3_x86_64,    lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
121     LLDB_INVALID_REGNUM // register sets need to end with this flag
122 };
123 static_assert((sizeof(g_xstate_regnums_x86_64) / sizeof(g_xstate_regnums_x86_64[0])) -
124                       1 ==
125                   k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64,
126               "g_xstate_regnums_x86_64 has wrong number of register infos");
127 
128 // x86 debug registers.
129 static const uint32_t g_dbr_regnums_x86_64[] = {
130     lldb_dr0_x86_64,   lldb_dr1_x86_64,  lldb_dr2_x86_64,  lldb_dr3_x86_64,
131     lldb_dr4_x86_64,   lldb_dr5_x86_64,  lldb_dr6_x86_64,  lldb_dr7_x86_64,
132     LLDB_INVALID_REGNUM // register sets need to end with this flag
133 };
134 static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
135                       1 ==
136                   k_num_dbr_registers_x86_64,
137               "g_dbr_regnums_x86_64 has wrong number of register infos");
138 
139 // x86 32-bit general purpose registers.
140 const uint32_t g_gpr_regnums_i386[] = {
141     lldb_eax_i386,      lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,
142     lldb_edi_i386,      lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,
143     lldb_eip_i386,      lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,
144     lldb_gs_i386,       lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,
145     lldb_ax_i386,       lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,
146     lldb_di_i386,       lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,
147     lldb_ah_i386,       lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,
148     lldb_al_i386,       lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,
149     LLDB_INVALID_REGNUM // register sets need to end with this flag
150 };
151 static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
152                       1 ==
153                   k_num_gpr_registers_i386,
154               "g_gpr_regnums_i386 has wrong number of register infos");
155 
156 // x86 32-bit floating point registers.
157 const uint32_t g_fpu_regnums_i386[] = {
158     lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,
159     lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,
160     lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,
161     lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,
162     lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,
163     lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,
164     lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,
165     lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,
166     lldb_xmm6_i386,     lldb_xmm7_i386,
167     LLDB_INVALID_REGNUM // register sets need to end with this flag
168 };
169 static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
170                       1 ==
171                   k_num_fpr_registers_i386,
172               "g_fpu_regnums_i386 has wrong number of register infos");
173 
174 // x86 64-bit registers available via XState.
175 static const uint32_t g_xstate_regnums_i386[] = {
176     lldb_ymm0_i386,     lldb_ymm1_i386,  lldb_ymm2_i386,  lldb_ymm3_i386,
177     lldb_ymm4_i386,     lldb_ymm5_i386,  lldb_ymm6_i386,  lldb_ymm7_i386,
178     // Note: we currently do not provide them but this is needed to avoid
179     // unnamed groups in SBFrame::GetRegisterContext().
180     lldb_bnd0_i386,      lldb_bnd1_i386,    lldb_bnd2_i386,
181     lldb_bnd3_i386,      lldb_bndcfgu_i386, lldb_bndstatus_i386,
182     LLDB_INVALID_REGNUM // register sets need to end with this flag
183 };
184 static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) -
185                       1 ==
186                   k_num_avx_registers_i386 + k_num_mpx_registers_i386,
187               "g_xstate_regnums_i386 has wrong number of register infos");
188 
189 // x86 debug registers.
190 static const uint32_t g_dbr_regnums_i386[] = {
191     lldb_dr0_i386,   lldb_dr1_i386,  lldb_dr2_i386,  lldb_dr3_i386,
192     lldb_dr4_i386,   lldb_dr5_i386,  lldb_dr6_i386,  lldb_dr7_i386,
193     LLDB_INVALID_REGNUM // register sets need to end with this flag
194 };
195 static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
196                       1 ==
197                   k_num_dbr_registers_i386,
198               "g_dbr_regnums_i386 has wrong number of register infos");
199 
200 
201 // Number of register sets provided by this context.
202 enum { k_num_register_sets = 4 };
203 
204 // Register sets for x86 32-bit.
205 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
206     {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
207      g_gpr_regnums_i386},
208     {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
209      g_fpu_regnums_i386},
210     {"Extended State Registers", "xstate",
211      k_num_avx_registers_i386 + k_num_mpx_registers_i386,
212      g_xstate_regnums_i386},
213     {"Debug Registers", "dbr", k_num_dbr_registers_i386,
214      g_dbr_regnums_i386},
215 };
216 
217 // Register sets for x86 64-bit.
218 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
219     {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
220      g_gpr_regnums_x86_64},
221     {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
222      g_fpu_regnums_x86_64},
223     {"Extended State Registers", "xstate",
224      k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64,
225      g_xstate_regnums_x86_64},
226     {"Debug Registers", "dbr", k_num_dbr_registers_x86_64,
227      g_dbr_regnums_x86_64},
228 };
229 
230 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
231 } // namespace
232 
233 NativeRegisterContextNetBSD *
234 NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
235     const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
236   return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread);
237 }
238 
239 // NativeRegisterContextNetBSD_x86_64 members.
240 
241 static RegisterInfoInterface *
242 CreateRegisterInfoInterface(const ArchSpec &target_arch) {
243   if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
244     // 32-bit hosts run with a RegisterContextNetBSD_i386 context.
245     return new RegisterContextNetBSD_i386(target_arch);
246   } else {
247     assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
248            "Register setting path assumes this is a 64-bit host");
249     // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
250     // register context.
251     return new RegisterContextNetBSD_x86_64(target_arch);
252   }
253 }
254 
255 NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
256     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
257     : NativeRegisterContextNetBSD(native_thread,
258                                   CreateRegisterInfoInterface(target_arch)),
259       m_gpr(), m_fpr(), m_dbr() {}
260 
261 // CONSIDER after local and llgs debugging are merged, register set support can
262 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
263 uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
264   uint32_t sets = 0;
265   for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
266     if (GetSetForNativeRegNum(set_index) != -1)
267       ++sets;
268   }
269 
270   return sets;
271 }
272 
273 const RegisterSet *
274 NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
275   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
276   case llvm::Triple::x86:
277     return &g_reg_sets_i386[set_index];
278   case llvm::Triple::x86_64:
279     return &g_reg_sets_x86_64[set_index];
280   default:
281     llvm_unreachable("Unhandled target architecture.");
282   }
283 }
284 
285 static constexpr int RegNumX86ToX86_64(int regnum) {
286   switch (regnum) {
287   case lldb_eax_i386:
288     return lldb_rax_x86_64;
289   case lldb_ebx_i386:
290     return lldb_rbx_x86_64;
291   case lldb_ecx_i386:
292     return lldb_rcx_x86_64;
293   case lldb_edx_i386:
294     return lldb_rdx_x86_64;
295   case lldb_edi_i386:
296     return lldb_rdi_x86_64;
297   case lldb_esi_i386:
298     return lldb_rsi_x86_64;
299   case lldb_ebp_i386:
300     return lldb_rbp_x86_64;
301   case lldb_esp_i386:
302     return lldb_rsp_x86_64;
303   case lldb_eip_i386:
304     return lldb_rip_x86_64;
305   case lldb_eflags_i386:
306     return lldb_rflags_x86_64;
307   case lldb_cs_i386:
308     return lldb_cs_x86_64;
309   case lldb_fs_i386:
310     return lldb_fs_x86_64;
311   case lldb_gs_i386:
312     return lldb_gs_x86_64;
313   case lldb_ss_i386:
314     return lldb_ss_x86_64;
315   case lldb_ds_i386:
316     return lldb_ds_x86_64;
317   case lldb_es_i386:
318     return lldb_es_x86_64;
319   case lldb_fctrl_i386:
320     return lldb_fctrl_x86_64;
321   case lldb_fstat_i386:
322     return lldb_fstat_x86_64;
323   case lldb_ftag_i386:
324     return lldb_ftag_x86_64;
325   case lldb_fop_i386:
326     return lldb_fop_x86_64;
327   case lldb_fiseg_i386:
328     return lldb_fiseg_x86_64;
329   case lldb_fioff_i386:
330     return lldb_fioff_x86_64;
331   case lldb_foseg_i386:
332     return lldb_foseg_x86_64;
333   case lldb_fooff_i386:
334     return lldb_fooff_x86_64;
335   case lldb_mxcsr_i386:
336     return lldb_mxcsr_x86_64;
337   case lldb_mxcsrmask_i386:
338     return lldb_mxcsrmask_x86_64;
339   case lldb_st0_i386:
340   case lldb_st1_i386:
341   case lldb_st2_i386:
342   case lldb_st3_i386:
343   case lldb_st4_i386:
344   case lldb_st5_i386:
345   case lldb_st6_i386:
346   case lldb_st7_i386:
347     return lldb_st0_x86_64 + regnum - lldb_st0_i386;
348   case lldb_mm0_i386:
349   case lldb_mm1_i386:
350   case lldb_mm2_i386:
351   case lldb_mm3_i386:
352   case lldb_mm4_i386:
353   case lldb_mm5_i386:
354   case lldb_mm6_i386:
355   case lldb_mm7_i386:
356     return lldb_mm0_x86_64 + regnum - lldb_mm0_i386;
357   case lldb_xmm0_i386:
358   case lldb_xmm1_i386:
359   case lldb_xmm2_i386:
360   case lldb_xmm3_i386:
361   case lldb_xmm4_i386:
362   case lldb_xmm5_i386:
363   case lldb_xmm6_i386:
364   case lldb_xmm7_i386:
365     return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386;
366   case lldb_ymm0_i386:
367   case lldb_ymm1_i386:
368   case lldb_ymm2_i386:
369   case lldb_ymm3_i386:
370   case lldb_ymm4_i386:
371   case lldb_ymm5_i386:
372   case lldb_ymm6_i386:
373   case lldb_ymm7_i386:
374     return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386;
375   case lldb_bnd0_i386:
376   case lldb_bnd1_i386:
377   case lldb_bnd2_i386:
378   case lldb_bnd3_i386:
379     return lldb_bnd0_x86_64 + regnum - lldb_bnd0_i386;
380   case lldb_bndcfgu_i386:
381     return lldb_bndcfgu_x86_64;
382   case lldb_bndstatus_i386:
383     return lldb_bndstatus_x86_64;
384   case lldb_dr0_i386:
385   case lldb_dr1_i386:
386   case lldb_dr2_i386:
387   case lldb_dr3_i386:
388   case lldb_dr4_i386:
389   case lldb_dr5_i386:
390   case lldb_dr6_i386:
391   case lldb_dr7_i386:
392     return lldb_dr0_x86_64 + regnum - lldb_dr0_i386;
393   default:
394     llvm_unreachable("Unhandled i386 register.");
395   }
396 }
397 
398 int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
399     int reg_num) const {
400   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
401   case llvm::Triple::x86:
402     if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386)
403       return GPRegSet;
404     if (reg_num >= k_first_fpr_i386 && reg_num <= k_last_fpr_i386)
405       return FPRegSet;
406     if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386)
407       return XStateRegSet; // AVX
408     if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386)
409       return -1; // MPXR
410     if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386)
411       return -1; // MPXC
412     if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386)
413       return DBRegSet; // DBR
414     break;
415   case llvm::Triple::x86_64:
416     if (reg_num >= k_first_gpr_x86_64 && reg_num <= k_last_gpr_x86_64)
417       return GPRegSet;
418     if (reg_num >= k_first_fpr_x86_64 && reg_num <= k_last_fpr_x86_64)
419       return FPRegSet;
420     if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64)
421       return XStateRegSet; // AVX
422     if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64)
423       return -1; // MPXR
424     if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64)
425       return -1; // MPXC
426     if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64)
427       return DBRegSet; // DBR
428     break;
429   default:
430     llvm_unreachable("Unhandled target architecture.");
431   }
432 
433   llvm_unreachable("Register does not belong to any register set");
434 }
435 
436 Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
437   switch (set) {
438   case GPRegSet:
439     return DoRegisterSet(PT_GETREGS, &m_gpr);
440   case FPRegSet:
441 #if defined(__x86_64__)
442     return DoRegisterSet(PT_GETFPREGS, &m_fpr);
443 #else
444     return DoRegisterSet(PT_GETXMMREGS, &m_fpr);
445 #endif
446   case DBRegSet:
447     return DoRegisterSet(PT_GETDBREGS, &m_dbr);
448   case XStateRegSet:
449 #ifdef HAVE_XSTATE
450     {
451       struct iovec iov = {&m_xstate, sizeof(m_xstate)};
452       return DoRegisterSet(PT_GETXSTATE, &iov);
453     }
454 #else
455     return Status("XState is not supported by the kernel");
456 #endif
457   }
458   llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet");
459 }
460 
461 Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) {
462   switch (set) {
463   case GPRegSet:
464     return DoRegisterSet(PT_SETREGS, &m_gpr);
465   case FPRegSet:
466 #if defined(__x86_64__)
467     return DoRegisterSet(PT_SETFPREGS, &m_fpr);
468 #else
469     return DoRegisterSet(PT_SETXMMREGS, &m_fpr);
470 #endif
471   case DBRegSet:
472     return DoRegisterSet(PT_SETDBREGS, &m_dbr);
473   case XStateRegSet:
474 #ifdef HAVE_XSTATE
475     {
476       struct iovec iov = {&m_xstate, sizeof(m_xstate)};
477       return DoRegisterSet(PT_SETXSTATE, &iov);
478     }
479 #else
480     return Status("XState is not supported by the kernel");
481 #endif
482   }
483   llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet");
484 }
485 
486 Status
487 NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
488                                                  RegisterValue &reg_value) {
489   Status error;
490 
491   if (!reg_info) {
492     error.SetErrorString("reg_info NULL");
493     return error;
494   }
495 
496   uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
497   if (reg == LLDB_INVALID_REGNUM) {
498     // This is likely an internal register for lldb use only and should not be
499     // directly queried.
500     error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
501                                    "register, cannot read directly",
502                                    reg_info->name);
503     return error;
504   }
505 
506   int set = GetSetForNativeRegNum(reg);
507   if (set == -1) {
508     // This is likely an internal register for lldb use only and should not be
509     // directly queried.
510     error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
511                                    reg_info->name);
512     return error;
513   }
514 
515   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
516   case llvm::Triple::x86_64:
517     break;
518   case llvm::Triple::x86:
519     reg = RegNumX86ToX86_64(reg);
520     break;
521   default:
522     llvm_unreachable("Unhandled target architecture.");
523   }
524 
525   error = ReadRegisterSet(set);
526   if (error.Fail())
527     return error;
528 
529   switch (reg) {
530 #if defined(__x86_64__)
531   case lldb_rax_x86_64:
532     reg_value = (uint64_t)m_gpr.regs[_REG_RAX];
533     break;
534   case lldb_rbx_x86_64:
535     reg_value = (uint64_t)m_gpr.regs[_REG_RBX];
536     break;
537   case lldb_rcx_x86_64:
538     reg_value = (uint64_t)m_gpr.regs[_REG_RCX];
539     break;
540   case lldb_rdx_x86_64:
541     reg_value = (uint64_t)m_gpr.regs[_REG_RDX];
542     break;
543   case lldb_rdi_x86_64:
544     reg_value = (uint64_t)m_gpr.regs[_REG_RDI];
545     break;
546   case lldb_rsi_x86_64:
547     reg_value = (uint64_t)m_gpr.regs[_REG_RSI];
548     break;
549   case lldb_rbp_x86_64:
550     reg_value = (uint64_t)m_gpr.regs[_REG_RBP];
551     break;
552   case lldb_rsp_x86_64:
553     reg_value = (uint64_t)m_gpr.regs[_REG_RSP];
554     break;
555   case lldb_r8_x86_64:
556     reg_value = (uint64_t)m_gpr.regs[_REG_R8];
557     break;
558   case lldb_r9_x86_64:
559     reg_value = (uint64_t)m_gpr.regs[_REG_R9];
560     break;
561   case lldb_r10_x86_64:
562     reg_value = (uint64_t)m_gpr.regs[_REG_R10];
563     break;
564   case lldb_r11_x86_64:
565     reg_value = (uint64_t)m_gpr.regs[_REG_R11];
566     break;
567   case lldb_r12_x86_64:
568     reg_value = (uint64_t)m_gpr.regs[_REG_R12];
569     break;
570   case lldb_r13_x86_64:
571     reg_value = (uint64_t)m_gpr.regs[_REG_R13];
572     break;
573   case lldb_r14_x86_64:
574     reg_value = (uint64_t)m_gpr.regs[_REG_R14];
575     break;
576   case lldb_r15_x86_64:
577     reg_value = (uint64_t)m_gpr.regs[_REG_R15];
578     break;
579   case lldb_rip_x86_64:
580     reg_value = (uint64_t)m_gpr.regs[_REG_RIP];
581     break;
582   case lldb_rflags_x86_64:
583     reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS];
584     break;
585   case lldb_cs_x86_64:
586     reg_value = (uint64_t)m_gpr.regs[_REG_CS];
587     break;
588   case lldb_fs_x86_64:
589     reg_value = (uint64_t)m_gpr.regs[_REG_FS];
590     break;
591   case lldb_gs_x86_64:
592     reg_value = (uint64_t)m_gpr.regs[_REG_GS];
593     break;
594   case lldb_ss_x86_64:
595     reg_value = (uint64_t)m_gpr.regs[_REG_SS];
596     break;
597   case lldb_ds_x86_64:
598     reg_value = (uint64_t)m_gpr.regs[_REG_DS];
599     break;
600   case lldb_es_x86_64:
601     reg_value = (uint64_t)m_gpr.regs[_REG_ES];
602     break;
603 #else
604   case lldb_rax_x86_64:
605     reg_value = (uint32_t)m_gpr.r_eax;
606     break;
607   case lldb_rbx_x86_64:
608     reg_value = (uint32_t)m_gpr.r_ebx;
609     break;
610   case lldb_rcx_x86_64:
611     reg_value = (uint32_t)m_gpr.r_ecx;
612     break;
613   case lldb_rdx_x86_64:
614     reg_value = (uint32_t)m_gpr.r_edx;
615     break;
616   case lldb_rdi_x86_64:
617     reg_value = (uint32_t)m_gpr.r_edi;
618     break;
619   case lldb_rsi_x86_64:
620     reg_value = (uint32_t)m_gpr.r_esi;
621     break;
622   case lldb_rsp_x86_64:
623     reg_value = (uint32_t)m_gpr.r_esp;
624     break;
625   case lldb_rbp_x86_64:
626     reg_value = (uint32_t)m_gpr.r_ebp;
627     break;
628   case lldb_rip_x86_64:
629     reg_value = (uint32_t)m_gpr.r_eip;
630     break;
631   case lldb_rflags_x86_64:
632     reg_value = (uint32_t)m_gpr.r_eflags;
633     break;
634   case lldb_cs_x86_64:
635     reg_value = (uint32_t)m_gpr.r_cs;
636     break;
637   case lldb_fs_x86_64:
638     reg_value = (uint32_t)m_gpr.r_fs;
639     break;
640   case lldb_gs_x86_64:
641     reg_value = (uint32_t)m_gpr.r_gs;
642     break;
643   case lldb_ss_x86_64:
644     reg_value = (uint32_t)m_gpr.r_ss;
645     break;
646   case lldb_ds_x86_64:
647     reg_value = (uint32_t)m_gpr.r_ds;
648     break;
649   case lldb_es_x86_64:
650     reg_value = (uint32_t)m_gpr.r_es;
651     break;
652 #endif
653   case lldb_fctrl_x86_64:
654     reg_value = (uint16_t)m_fpr.fxstate.fx_cw;
655     break;
656   case lldb_fstat_x86_64:
657     reg_value = (uint16_t)m_fpr.fxstate.fx_sw;
658     break;
659   case lldb_ftag_x86_64:
660     reg_value = (uint16_t)m_fpr.fxstate.fx_tw;
661     break;
662   case lldb_fop_x86_64:
663     reg_value = (uint64_t)m_fpr.fxstate.fx_opcode;
664     break;
665   case lldb_fiseg_x86_64:
666     reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_seg;
667     break;
668   case lldb_fioff_x86_64:
669     reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off;
670     break;
671   case lldb_foseg_x86_64:
672     reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_seg;
673     break;
674   case lldb_fooff_x86_64:
675     reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off;
676     break;
677   case lldb_mxcsr_x86_64:
678     reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr;
679     break;
680   case lldb_mxcsrmask_x86_64:
681     reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask;
682     break;
683   case lldb_st0_x86_64:
684   case lldb_st1_x86_64:
685   case lldb_st2_x86_64:
686   case lldb_st3_x86_64:
687   case lldb_st4_x86_64:
688   case lldb_st5_x86_64:
689   case lldb_st6_x86_64:
690   case lldb_st7_x86_64:
691     reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
692                        reg_info->byte_size, endian::InlHostByteOrder());
693     break;
694   case lldb_mm0_x86_64:
695   case lldb_mm1_x86_64:
696   case lldb_mm2_x86_64:
697   case lldb_mm3_x86_64:
698   case lldb_mm4_x86_64:
699   case lldb_mm5_x86_64:
700   case lldb_mm6_x86_64:
701   case lldb_mm7_x86_64:
702     reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
703                        reg_info->byte_size, endian::InlHostByteOrder());
704     break;
705   case lldb_xmm0_x86_64:
706   case lldb_xmm1_x86_64:
707   case lldb_xmm2_x86_64:
708   case lldb_xmm3_x86_64:
709   case lldb_xmm4_x86_64:
710   case lldb_xmm5_x86_64:
711   case lldb_xmm6_x86_64:
712   case lldb_xmm7_x86_64:
713   case lldb_xmm8_x86_64:
714   case lldb_xmm9_x86_64:
715   case lldb_xmm10_x86_64:
716   case lldb_xmm11_x86_64:
717   case lldb_xmm12_x86_64:
718   case lldb_xmm13_x86_64:
719   case lldb_xmm14_x86_64:
720   case lldb_xmm15_x86_64:
721     reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
722                        reg_info->byte_size, endian::InlHostByteOrder());
723     break;
724   case lldb_ymm0_x86_64:
725   case lldb_ymm1_x86_64:
726   case lldb_ymm2_x86_64:
727   case lldb_ymm3_x86_64:
728   case lldb_ymm4_x86_64:
729   case lldb_ymm5_x86_64:
730   case lldb_ymm6_x86_64:
731   case lldb_ymm7_x86_64:
732   case lldb_ymm8_x86_64:
733   case lldb_ymm9_x86_64:
734   case lldb_ymm10_x86_64:
735   case lldb_ymm11_x86_64:
736   case lldb_ymm12_x86_64:
737   case lldb_ymm13_x86_64:
738   case lldb_ymm14_x86_64:
739   case lldb_ymm15_x86_64:
740 #ifdef HAVE_XSTATE
741     if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
742         !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
743       error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel",
744                                      reg_info->name);
745     } else {
746       uint32_t reg_index = reg - lldb_ymm0_x86_64;
747       YMMReg ymm = XStateToYMM(
748           m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
749           m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
750       reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
751                          endian::InlHostByteOrder());
752     }
753 #else
754     error.SetErrorString("XState queries not supported by the kernel");
755 #endif
756     break;
757   case lldb_dr0_x86_64:
758   case lldb_dr1_x86_64:
759   case lldb_dr2_x86_64:
760   case lldb_dr3_x86_64:
761   case lldb_dr4_x86_64:
762   case lldb_dr5_x86_64:
763   case lldb_dr6_x86_64:
764   case lldb_dr7_x86_64:
765     reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
766     break;
767   default:
768     llvm_unreachable("Reading unknown/unsupported register");
769   }
770 
771   return error;
772 }
773 
774 Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
775     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
776 
777   Status error;
778 
779   if (!reg_info) {
780     error.SetErrorString("reg_info NULL");
781     return error;
782   }
783 
784   uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
785   if (reg == LLDB_INVALID_REGNUM) {
786     // This is likely an internal register for lldb use only and should not be
787     // directly queried.
788     error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
789                                    "register, cannot read directly",
790                                    reg_info->name);
791     return error;
792   }
793 
794   int set = GetSetForNativeRegNum(reg);
795   if (set == -1) {
796     // This is likely an internal register for lldb use only and should not be
797     // directly queried.
798     error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
799                                    reg_info->name);
800     return error;
801   }
802 
803   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
804   case llvm::Triple::x86_64:
805     break;
806   case llvm::Triple::x86:
807     reg = RegNumX86ToX86_64(reg);
808     break;
809   default:
810     llvm_unreachable("Unhandled target architecture.");
811   }
812 
813   error = ReadRegisterSet(set);
814   if (error.Fail())
815     return error;
816 
817   switch (reg) {
818 #if defined(__x86_64__)
819   case lldb_rax_x86_64:
820     m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
821     break;
822   case lldb_rbx_x86_64:
823     m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
824     break;
825   case lldb_rcx_x86_64:
826     m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
827     break;
828   case lldb_rdx_x86_64:
829     m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
830     break;
831   case lldb_rdi_x86_64:
832     m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
833     break;
834   case lldb_rsi_x86_64:
835     m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
836     break;
837   case lldb_rbp_x86_64:
838     m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
839     break;
840   case lldb_rsp_x86_64:
841     m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
842     break;
843   case lldb_r8_x86_64:
844     m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
845     break;
846   case lldb_r9_x86_64:
847     m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
848     break;
849   case lldb_r10_x86_64:
850     m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
851     break;
852   case lldb_r11_x86_64:
853     m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
854     break;
855   case lldb_r12_x86_64:
856     m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
857     break;
858   case lldb_r13_x86_64:
859     m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
860     break;
861   case lldb_r14_x86_64:
862     m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
863     break;
864   case lldb_r15_x86_64:
865     m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
866     break;
867   case lldb_rip_x86_64:
868     m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
869     break;
870   case lldb_rflags_x86_64:
871     m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
872     break;
873   case lldb_cs_x86_64:
874     m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
875     break;
876   case lldb_fs_x86_64:
877     m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64();
878     break;
879   case lldb_gs_x86_64:
880     m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64();
881     break;
882   case lldb_ss_x86_64:
883     m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
884     break;
885   case lldb_ds_x86_64:
886     m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64();
887     break;
888   case lldb_es_x86_64:
889     m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64();
890     break;
891 #else
892   case lldb_rax_x86_64:
893     m_gpr.r_eax = reg_value.GetAsUInt32();
894     break;
895   case lldb_rbx_x86_64:
896     m_gpr.r_ebx = reg_value.GetAsUInt32();
897     break;
898   case lldb_rcx_x86_64:
899     m_gpr.r_ecx = reg_value.GetAsUInt32();
900     break;
901   case lldb_rdx_x86_64:
902     m_gpr.r_edx = reg_value.GetAsUInt32();
903     break;
904   case lldb_rdi_x86_64:
905     m_gpr.r_edi = reg_value.GetAsUInt32();
906     break;
907   case lldb_rsi_x86_64:
908     m_gpr.r_esi = reg_value.GetAsUInt32();
909     break;
910   case lldb_rsp_x86_64:
911     m_gpr.r_esp = reg_value.GetAsUInt32();
912     break;
913   case lldb_rbp_x86_64:
914     m_gpr.r_ebp = reg_value.GetAsUInt32();
915     break;
916   case lldb_rip_x86_64:
917     m_gpr.r_eip = reg_value.GetAsUInt32();
918     break;
919   case lldb_rflags_x86_64:
920     m_gpr.r_eflags = reg_value.GetAsUInt32();
921     break;
922   case lldb_cs_x86_64:
923     m_gpr.r_cs = reg_value.GetAsUInt32();
924     break;
925   case lldb_fs_x86_64:
926     m_gpr.r_fs = reg_value.GetAsUInt32();
927     break;
928   case lldb_gs_x86_64:
929     m_gpr.r_gs = reg_value.GetAsUInt32();
930     break;
931   case lldb_ss_x86_64:
932     m_gpr.r_ss = reg_value.GetAsUInt32();
933     break;
934   case lldb_ds_x86_64:
935     m_gpr.r_ds = reg_value.GetAsUInt32();
936     break;
937   case lldb_es_x86_64:
938     m_gpr.r_es = reg_value.GetAsUInt32();
939     break;
940 #endif
941   case lldb_fctrl_x86_64:
942     m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16();
943     break;
944   case lldb_fstat_x86_64:
945     m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16();
946     break;
947   case lldb_ftag_x86_64:
948     m_fpr.fxstate.fx_tw = reg_value.GetAsUInt16();
949     break;
950   case lldb_fop_x86_64:
951     m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16();
952     break;
953   case lldb_fiseg_x86_64:
954     m_fpr.fxstate.fx_ip.fa_32.fa_seg = reg_value.GetAsUInt32();
955     break;
956   case lldb_fioff_x86_64:
957     m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
958     break;
959   case lldb_foseg_x86_64:
960     m_fpr.fxstate.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32();
961     break;
962   case lldb_fooff_x86_64:
963     m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
964     break;
965   case lldb_mxcsr_x86_64:
966     m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32();
967     break;
968   case lldb_mxcsrmask_x86_64:
969     m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32();
970     break;
971   case lldb_st0_x86_64:
972   case lldb_st1_x86_64:
973   case lldb_st2_x86_64:
974   case lldb_st3_x86_64:
975   case lldb_st4_x86_64:
976   case lldb_st5_x86_64:
977   case lldb_st6_x86_64:
978   case lldb_st7_x86_64:
979     ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
980              reg_value.GetBytes(), reg_value.GetByteSize());
981     break;
982   case lldb_mm0_x86_64:
983   case lldb_mm1_x86_64:
984   case lldb_mm2_x86_64:
985   case lldb_mm3_x86_64:
986   case lldb_mm4_x86_64:
987   case lldb_mm5_x86_64:
988   case lldb_mm6_x86_64:
989   case lldb_mm7_x86_64:
990     ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
991              reg_value.GetBytes(), reg_value.GetByteSize());
992     break;
993   case lldb_xmm0_x86_64:
994   case lldb_xmm1_x86_64:
995   case lldb_xmm2_x86_64:
996   case lldb_xmm3_x86_64:
997   case lldb_xmm4_x86_64:
998   case lldb_xmm5_x86_64:
999   case lldb_xmm6_x86_64:
1000   case lldb_xmm7_x86_64:
1001   case lldb_xmm8_x86_64:
1002   case lldb_xmm9_x86_64:
1003   case lldb_xmm10_x86_64:
1004   case lldb_xmm11_x86_64:
1005   case lldb_xmm12_x86_64:
1006   case lldb_xmm13_x86_64:
1007   case lldb_xmm14_x86_64:
1008   case lldb_xmm15_x86_64:
1009     ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
1010              reg_value.GetBytes(), reg_value.GetByteSize());
1011     break;
1012   case lldb_ymm0_x86_64:
1013   case lldb_ymm1_x86_64:
1014   case lldb_ymm2_x86_64:
1015   case lldb_ymm3_x86_64:
1016   case lldb_ymm4_x86_64:
1017   case lldb_ymm5_x86_64:
1018   case lldb_ymm6_x86_64:
1019   case lldb_ymm7_x86_64:
1020   case lldb_ymm8_x86_64:
1021   case lldb_ymm9_x86_64:
1022   case lldb_ymm10_x86_64:
1023   case lldb_ymm11_x86_64:
1024   case lldb_ymm12_x86_64:
1025   case lldb_ymm13_x86_64:
1026   case lldb_ymm14_x86_64:
1027   case lldb_ymm15_x86_64:
1028 #ifdef HAVE_XSTATE
1029     if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
1030         !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
1031       error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel",
1032                                      reg_info->name);
1033     } else {
1034       uint32_t reg_index = reg - lldb_ymm0_x86_64;
1035       YMMReg ymm;
1036       ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
1037       YMMToXState(ymm,
1038           m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
1039           m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
1040     }
1041 #else
1042     error.SetErrorString("XState not supported by the kernel");
1043     return error;
1044 #endif
1045     break;
1046   case lldb_dr0_x86_64:
1047   case lldb_dr1_x86_64:
1048   case lldb_dr2_x86_64:
1049   case lldb_dr3_x86_64:
1050   case lldb_dr4_x86_64:
1051   case lldb_dr5_x86_64:
1052   case lldb_dr6_x86_64:
1053   case lldb_dr7_x86_64:
1054     m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
1055     break;
1056   default:
1057     llvm_unreachable("Reading unknown/unsupported register");
1058   }
1059 
1060   return WriteRegisterSet(set);
1061 }
1062 
1063 Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
1064     lldb::DataBufferSP &data_sp) {
1065   Status error;
1066 
1067   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
1068   error = ReadRegisterSet(GPRegSet);
1069   if (error.Fail())
1070     return error;
1071 
1072   uint8_t *dst = data_sp->GetBytes();
1073   ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
1074   dst += GetRegisterInfoInterface().GetGPRSize();
1075 
1076   return error;
1077 }
1078 
1079 Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
1080     const lldb::DataBufferSP &data_sp) {
1081   Status error;
1082 
1083   if (!data_sp) {
1084     error.SetErrorStringWithFormat(
1085         "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided",
1086         __FUNCTION__);
1087     return error;
1088   }
1089 
1090   if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
1091     error.SetErrorStringWithFormat(
1092         "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched "
1093         "data size, expected %zu, actual %" PRIu64,
1094         __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
1095     return error;
1096   }
1097 
1098   uint8_t *src = data_sp->GetBytes();
1099   if (src == nullptr) {
1100     error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s "
1101                                    "DataBuffer::GetBytes() returned a null "
1102                                    "pointer",
1103                                    __FUNCTION__);
1104     return error;
1105   }
1106   ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
1107 
1108   error = WriteRegisterSet(GPRegSet);
1109   if (error.Fail())
1110     return error;
1111   src += GetRegisterInfoInterface().GetGPRSize();
1112 
1113   return error;
1114 }
1115 
1116 int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
1117   assert(num >= 0 && num <= 7);
1118   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1119   case llvm::Triple::x86:
1120     return lldb_dr0_i386 + num;
1121   case llvm::Triple::x86_64:
1122     return lldb_dr0_x86_64 + num;
1123   default:
1124     llvm_unreachable("Unhandled target architecture.");
1125   }
1126 }
1127 
1128 Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index,
1129                                                            bool &is_hit) {
1130   if (wp_index >= NumSupportedHardwareWatchpoints())
1131     return Status("Watchpoint index out of range");
1132 
1133   RegisterValue reg_value;
1134   const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6));
1135   Status error = ReadRegister(reg_info, reg_value);
1136   if (error.Fail()) {
1137     is_hit = false;
1138     return error;
1139   }
1140 
1141   uint64_t status_bits = reg_value.GetAsUInt64();
1142 
1143   is_hit = status_bits & (1 << wp_index);
1144 
1145   return error;
1146 }
1147 
1148 Status NativeRegisterContextNetBSD_x86_64::GetWatchpointHitIndex(
1149     uint32_t &wp_index, lldb::addr_t trap_addr) {
1150   uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
1151   for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
1152     bool is_hit;
1153     Status error = IsWatchpointHit(wp_index, is_hit);
1154     if (error.Fail()) {
1155       wp_index = LLDB_INVALID_INDEX32;
1156       return error;
1157     } else if (is_hit) {
1158       return error;
1159     }
1160   }
1161   wp_index = LLDB_INVALID_INDEX32;
1162   return Status();
1163 }
1164 
1165 Status NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index,
1166                                                               bool &is_vacant) {
1167   if (wp_index >= NumSupportedHardwareWatchpoints())
1168     return Status("Watchpoint index out of range");
1169 
1170   RegisterValue reg_value;
1171   const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7));
1172   Status error = ReadRegister(reg_info, reg_value);
1173   if (error.Fail()) {
1174     is_vacant = false;
1175     return error;
1176   }
1177 
1178   uint64_t control_bits = reg_value.GetAsUInt64();
1179 
1180   is_vacant = !(control_bits & (1 << (2 * wp_index + 1)));
1181 
1182   return error;
1183 }
1184 
1185 Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
1186     lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
1187 
1188   if (wp_index >= NumSupportedHardwareWatchpoints())
1189     return Status("Watchpoint index out of range");
1190 
1191   // Read only watchpoints aren't supported on x86_64. Fall back to read/write
1192   // waitchpoints instead.
1193   // TODO: Add logic to detect when a write happens and ignore that watchpoint
1194   // hit.
1195   if (watch_flags == 0x2)
1196     watch_flags = 0x3;
1197 
1198   if (watch_flags != 0x1 && watch_flags != 0x3)
1199     return Status("Invalid read/write bits for watchpoint");
1200 
1201   if (size != 1 && size != 2 && size != 4 && size != 8)
1202     return Status("Invalid size for watchpoint");
1203 
1204   bool is_vacant;
1205   Status error = IsWatchpointVacant(wp_index, is_vacant);
1206   if (error.Fail())
1207     return error;
1208   if (!is_vacant)
1209     return Status("Watchpoint index not vacant");
1210 
1211   const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
1212   RegisterValue dr7_value;
1213   error = ReadRegister(reg_info_dr7, dr7_value);
1214   if (error.Fail())
1215     return error;
1216 
1217   // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
1218   uint64_t enable_bit = 1 << (2 * wp_index + 1);
1219 
1220   // set bits 16-17, 20-21, 24-25, or 28-29
1221   // with 0b01 for write, and 0b11 for read/write
1222   uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
1223 
1224   // set bits 18-19, 22-23, 26-27, or 30-31
1225   // with 0b00, 0b01, 0b10, or 0b11
1226   // for 1, 2, 8 (if supported), or 4 bytes, respectively
1227   uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
1228 
1229   uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
1230 
1231   uint64_t control_bits = dr7_value.GetAsUInt64() & ~bit_mask;
1232 
1233   control_bits |= enable_bit | rw_bits | size_bits;
1234 
1235   const RegisterInfo *const reg_info_drN =
1236       GetRegisterInfoAtIndex(GetDR(wp_index));
1237   RegisterValue drN_value;
1238   error = ReadRegister(reg_info_drN, drN_value);
1239   if (error.Fail())
1240     return error;
1241 
1242   // clear dr6 if address or bits changed (i.e. we're not reenabling the same
1243   // watchpoint)
1244   if (drN_value.GetAsUInt64() != addr ||
1245       (dr7_value.GetAsUInt64() & bit_mask) != (rw_bits | size_bits)) {
1246     ClearWatchpointHit(wp_index);
1247 
1248     error = WriteRegister(reg_info_drN, RegisterValue(addr));
1249     if (error.Fail())
1250       return error;
1251   }
1252 
1253   error = WriteRegister(reg_info_dr7, RegisterValue(control_bits));
1254   if (error.Fail())
1255     return error;
1256 
1257   error.Clear();
1258   return error;
1259 }
1260 
1261 bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
1262     uint32_t wp_index) {
1263   if (wp_index >= NumSupportedHardwareWatchpoints())
1264     return false;
1265 
1266   // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5
1267   // or 6-7 of the debug control register (DR7)
1268   const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
1269   RegisterValue reg_value;
1270   Status error = ReadRegister(reg_info_dr7, reg_value);
1271   if (error.Fail())
1272     return false;
1273   uint64_t bit_mask = 0x3 << (2 * wp_index);
1274   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1275 
1276   return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success();
1277 }
1278 
1279 Status NativeRegisterContextNetBSD_x86_64::ClearWatchpointHit(uint32_t wp_index) {
1280   if (wp_index >= NumSupportedHardwareWatchpoints())
1281     return Status("Watchpoint index out of range");
1282 
1283   // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of
1284   // the debug status register (DR6)
1285   const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
1286   RegisterValue reg_value;
1287   Status error = ReadRegister(reg_info_dr6, reg_value);
1288   if (error.Fail())
1289     return error;
1290 
1291   uint64_t bit_mask = 1 << wp_index;
1292   uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
1293   return WriteRegister(reg_info_dr6, RegisterValue(status_bits));
1294 }
1295 
1296 Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
1297   RegisterValue reg_value;
1298 
1299   // clear bits {0-4} of the debug status register (DR6)
1300   const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
1301   Status error = ReadRegister(reg_info_dr6, reg_value);
1302   if (error.Fail())
1303     return error;
1304   uint64_t bit_mask = 0xF;
1305   uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
1306   error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
1307   if (error.Fail())
1308     return error;
1309 
1310   // clear bits {0-7,16-31} of the debug control register (DR7)
1311   const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
1312   error = ReadRegister(reg_info_dr7, reg_value);
1313   if (error.Fail())
1314     return error;
1315   bit_mask = 0xFF | (0xFFFF << 16);
1316   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1317   return WriteRegister(reg_info_dr7, RegisterValue(control_bits));
1318 }
1319 
1320 uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint(
1321     lldb::addr_t addr, size_t size, uint32_t watch_flags) {
1322   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1323   const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1324   for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
1325     bool is_vacant;
1326     Status error = IsWatchpointVacant(wp_index, is_vacant);
1327     if (is_vacant) {
1328       error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
1329       if (error.Success())
1330         return wp_index;
1331     }
1332     if (error.Fail() && log) {
1333       LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s",
1334                 __FUNCTION__, error.AsCString());
1335     }
1336   }
1337   return LLDB_INVALID_INDEX32;
1338 }
1339 
1340 lldb::addr_t
1341 NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) {
1342   if (wp_index >= NumSupportedHardwareWatchpoints())
1343     return LLDB_INVALID_ADDRESS;
1344   RegisterValue reg_value;
1345   const RegisterInfo *const reg_info_drN =
1346       GetRegisterInfoAtIndex(GetDR(wp_index));
1347   if (ReadRegister(reg_info_drN, reg_value).Fail())
1348     return LLDB_INVALID_ADDRESS;
1349   return reg_value.GetAsUInt64();
1350 }
1351 
1352 uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() {
1353   // Available debug address registers: dr0, dr1, dr2, dr3
1354   return 4;
1355 }
1356 
1357 Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
1358     NativeRegisterContextNetBSD &source) {
1359   auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
1360   Status res = r_source.ReadRegisterSet(DBRegSet);
1361   if (!res.Fail()) {
1362     // copy dbregs only if any watchpoints were set
1363     if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
1364       return res;
1365 
1366     m_dbr = r_source.m_dbr;
1367     res = WriteRegisterSet(DBRegSet);
1368   }
1369   return res;
1370 }
1371 
1372 #endif // defined(__x86_64__)
1373