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 *
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 *
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 
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.
236 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 *
247 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 
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 
371 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 
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 
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
438 NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
439                                                  RegisterValue &reg_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     reg_value = (uint16_t)m_xstate.xs_fxsave.fx_tw;
612     break;
613   case lldb_fop_x86_64:
614     reg_value = (uint64_t)m_xstate.xs_fxsave.fx_opcode;
615     break;
616   case lldb_fiseg_x86_64:
617     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg;
618     break;
619   case lldb_fioff_x86_64:
620     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_off;
621     break;
622   case lldb_fip_x86_64:
623     reg_value = (uint64_t)m_xstate.xs_fxsave.fx_ip.fa_64;
624     break;
625   case lldb_foseg_x86_64:
626     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg;
627     break;
628   case lldb_fooff_x86_64:
629     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_off;
630     break;
631   case lldb_fdp_x86_64:
632     reg_value = (uint64_t)m_xstate.xs_fxsave.fx_dp.fa_64;
633     break;
634   case lldb_mxcsr_x86_64:
635     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr;
636     break;
637   case lldb_mxcsrmask_x86_64:
638     reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr_mask;
639     break;
640   case lldb_st0_x86_64:
641   case lldb_st1_x86_64:
642   case lldb_st2_x86_64:
643   case lldb_st3_x86_64:
644   case lldb_st4_x86_64:
645   case lldb_st5_x86_64:
646   case lldb_st6_x86_64:
647   case lldb_st7_x86_64:
648     reg_value.SetBytes(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
649                        reg_info->byte_size, endian::InlHostByteOrder());
650     break;
651   case lldb_mm0_x86_64:
652   case lldb_mm1_x86_64:
653   case lldb_mm2_x86_64:
654   case lldb_mm3_x86_64:
655   case lldb_mm4_x86_64:
656   case lldb_mm5_x86_64:
657   case lldb_mm6_x86_64:
658   case lldb_mm7_x86_64:
659     reg_value.SetBytes(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
660                        reg_info->byte_size, endian::InlHostByteOrder());
661     break;
662   case lldb_xmm0_x86_64:
663   case lldb_xmm1_x86_64:
664   case lldb_xmm2_x86_64:
665   case lldb_xmm3_x86_64:
666   case lldb_xmm4_x86_64:
667   case lldb_xmm5_x86_64:
668   case lldb_xmm6_x86_64:
669   case lldb_xmm7_x86_64:
670   case lldb_xmm8_x86_64:
671   case lldb_xmm9_x86_64:
672   case lldb_xmm10_x86_64:
673   case lldb_xmm11_x86_64:
674   case lldb_xmm12_x86_64:
675   case lldb_xmm13_x86_64:
676   case lldb_xmm14_x86_64:
677   case lldb_xmm15_x86_64:
678     if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
679       error.SetErrorStringWithFormat(
680           "register \"%s\" not supported by CPU/kernel", reg_info->name);
681     } else {
682       reg_value.SetBytes(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
683                          reg_info->byte_size, endian::InlHostByteOrder());
684     }
685     break;
686   case lldb_ymm0_x86_64:
687   case lldb_ymm1_x86_64:
688   case lldb_ymm2_x86_64:
689   case lldb_ymm3_x86_64:
690   case lldb_ymm4_x86_64:
691   case lldb_ymm5_x86_64:
692   case lldb_ymm6_x86_64:
693   case lldb_ymm7_x86_64:
694   case lldb_ymm8_x86_64:
695   case lldb_ymm9_x86_64:
696   case lldb_ymm10_x86_64:
697   case lldb_ymm11_x86_64:
698   case lldb_ymm12_x86_64:
699   case lldb_ymm13_x86_64:
700   case lldb_ymm14_x86_64:
701   case lldb_ymm15_x86_64:
702     if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
703         !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
704       error.SetErrorStringWithFormat(
705           "register \"%s\" not supported by CPU/kernel", reg_info->name);
706     } else {
707       uint32_t reg_index = reg - lldb_ymm0_x86_64;
708       YMMReg ymm =
709           XStateToYMM(m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
710                       m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
711       reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
712                          endian::InlHostByteOrder());
713     }
714     break;
715   case lldb_dr0_x86_64:
716   case lldb_dr1_x86_64:
717   case lldb_dr2_x86_64:
718   case lldb_dr3_x86_64:
719   case lldb_dr4_x86_64:
720   case lldb_dr5_x86_64:
721   case lldb_dr6_x86_64:
722   case lldb_dr7_x86_64:
723     reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
724     break;
725   default:
726     llvm_unreachable("Reading unknown/unsupported register");
727   }
728 
729   return error;
730 }
731 
732 Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
733     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
734 
735   Status error;
736 
737   if (!reg_info) {
738     error.SetErrorString("reg_info NULL");
739     return error;
740   }
741 
742   uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
743   if (reg == LLDB_INVALID_REGNUM) {
744     // This is likely an internal register for lldb use only and should not be
745     // directly queried.
746     error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
747                                    "register, cannot read directly",
748                                    reg_info->name);
749     return error;
750   }
751 
752   int set = GetSetForNativeRegNum(reg);
753   if (set == -1) {
754     // This is likely an internal register for lldb use only and should not be
755     // directly queried.
756     error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
757                                    reg_info->name);
758     return error;
759   }
760 
761   uint64_t new_xstate_bv = XCR0_X87;  // the most common case
762 
763   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
764   case llvm::Triple::x86_64:
765     break;
766   case llvm::Triple::x86:
767     reg = RegNumX86ToX86_64(reg);
768     break;
769   default:
770     llvm_unreachable("Unhandled target architecture.");
771   }
772 
773   error = ReadRegisterSet(set);
774   if (error.Fail())
775     return error;
776 
777   switch (reg) {
778 #if defined(__x86_64__)
779   case lldb_rax_x86_64:
780     m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
781     break;
782   case lldb_rbx_x86_64:
783     m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
784     break;
785   case lldb_rcx_x86_64:
786     m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
787     break;
788   case lldb_rdx_x86_64:
789     m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
790     break;
791   case lldb_rdi_x86_64:
792     m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
793     break;
794   case lldb_rsi_x86_64:
795     m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
796     break;
797   case lldb_rbp_x86_64:
798     m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
799     break;
800   case lldb_rsp_x86_64:
801     m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
802     break;
803   case lldb_r8_x86_64:
804     m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
805     break;
806   case lldb_r9_x86_64:
807     m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
808     break;
809   case lldb_r10_x86_64:
810     m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
811     break;
812   case lldb_r11_x86_64:
813     m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
814     break;
815   case lldb_r12_x86_64:
816     m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
817     break;
818   case lldb_r13_x86_64:
819     m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
820     break;
821   case lldb_r14_x86_64:
822     m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
823     break;
824   case lldb_r15_x86_64:
825     m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
826     break;
827   case lldb_rip_x86_64:
828     m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
829     break;
830   case lldb_rflags_x86_64:
831     m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
832     break;
833   case lldb_cs_x86_64:
834     m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
835     break;
836   case lldb_fs_x86_64:
837     m_gpr.regs[_REG_FS] = reg_value.GetAsUInt16();
838     break;
839   case lldb_gs_x86_64:
840     m_gpr.regs[_REG_GS] = reg_value.GetAsUInt16();
841     break;
842   case lldb_ss_x86_64:
843     m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
844     break;
845   case lldb_ds_x86_64:
846     m_gpr.regs[_REG_DS] = reg_value.GetAsUInt16();
847     break;
848   case lldb_es_x86_64:
849     m_gpr.regs[_REG_ES] = reg_value.GetAsUInt16();
850     break;
851 #else
852   case lldb_rax_x86_64:
853     m_gpr.r_eax = reg_value.GetAsUInt32();
854     break;
855   case lldb_rbx_x86_64:
856     m_gpr.r_ebx = reg_value.GetAsUInt32();
857     break;
858   case lldb_rcx_x86_64:
859     m_gpr.r_ecx = reg_value.GetAsUInt32();
860     break;
861   case lldb_rdx_x86_64:
862     m_gpr.r_edx = reg_value.GetAsUInt32();
863     break;
864   case lldb_rdi_x86_64:
865     m_gpr.r_edi = reg_value.GetAsUInt32();
866     break;
867   case lldb_rsi_x86_64:
868     m_gpr.r_esi = reg_value.GetAsUInt32();
869     break;
870   case lldb_rsp_x86_64:
871     m_gpr.r_esp = reg_value.GetAsUInt32();
872     break;
873   case lldb_rbp_x86_64:
874     m_gpr.r_ebp = reg_value.GetAsUInt32();
875     break;
876   case lldb_rip_x86_64:
877     m_gpr.r_eip = reg_value.GetAsUInt32();
878     break;
879   case lldb_rflags_x86_64:
880     m_gpr.r_eflags = reg_value.GetAsUInt32();
881     break;
882   case lldb_cs_x86_64:
883     m_gpr.r_cs = reg_value.GetAsUInt32();
884     break;
885   case lldb_fs_x86_64:
886     m_gpr.r_fs = reg_value.GetAsUInt16();
887     break;
888   case lldb_gs_x86_64:
889     m_gpr.r_gs = reg_value.GetAsUInt16();
890     break;
891   case lldb_ss_x86_64:
892     m_gpr.r_ss = reg_value.GetAsUInt32();
893     break;
894   case lldb_ds_x86_64:
895     m_gpr.r_ds = reg_value.GetAsUInt16();
896     break;
897   case lldb_es_x86_64:
898     m_gpr.r_es = reg_value.GetAsUInt16();
899     break;
900 #endif
901   case lldb_fctrl_x86_64:
902     m_xstate.xs_fxsave.fx_cw = reg_value.GetAsUInt16();
903     break;
904   case lldb_fstat_x86_64:
905     m_xstate.xs_fxsave.fx_sw = reg_value.GetAsUInt16();
906     break;
907   case lldb_ftag_x86_64:
908     m_xstate.xs_fxsave.fx_tw = reg_value.GetAsUInt16();
909     break;
910   case lldb_fop_x86_64:
911     m_xstate.xs_fxsave.fx_opcode = reg_value.GetAsUInt16();
912     break;
913   case lldb_fiseg_x86_64:
914     m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg = reg_value.GetAsUInt32();
915     break;
916   case lldb_fioff_x86_64:
917     m_xstate.xs_fxsave.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
918     break;
919   case lldb_fip_x86_64:
920     m_xstate.xs_fxsave.fx_ip.fa_64 = reg_value.GetAsUInt64();
921     break;
922   case lldb_foseg_x86_64:
923     m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32();
924     break;
925   case lldb_fooff_x86_64:
926     m_xstate.xs_fxsave.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
927     break;
928   case lldb_fdp_x86_64:
929     m_xstate.xs_fxsave.fx_dp.fa_64 = reg_value.GetAsUInt64();
930     break;
931   case lldb_mxcsr_x86_64:
932     m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32();
933     new_xstate_bv = XCR0_SSE;
934     break;
935   case lldb_mxcsrmask_x86_64:
936     m_xstate.xs_fxsave.fx_mxcsr_mask = reg_value.GetAsUInt32();
937     new_xstate_bv = XCR0_SSE;
938     break;
939   case lldb_st0_x86_64:
940   case lldb_st1_x86_64:
941   case lldb_st2_x86_64:
942   case lldb_st3_x86_64:
943   case lldb_st4_x86_64:
944   case lldb_st5_x86_64:
945   case lldb_st6_x86_64:
946   case lldb_st7_x86_64:
947     ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
948              reg_value.GetBytes(), reg_value.GetByteSize());
949     break;
950   case lldb_mm0_x86_64:
951   case lldb_mm1_x86_64:
952   case lldb_mm2_x86_64:
953   case lldb_mm3_x86_64:
954   case lldb_mm4_x86_64:
955   case lldb_mm5_x86_64:
956   case lldb_mm6_x86_64:
957   case lldb_mm7_x86_64:
958     ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
959              reg_value.GetBytes(), reg_value.GetByteSize());
960     break;
961   case lldb_xmm0_x86_64:
962   case lldb_xmm1_x86_64:
963   case lldb_xmm2_x86_64:
964   case lldb_xmm3_x86_64:
965   case lldb_xmm4_x86_64:
966   case lldb_xmm5_x86_64:
967   case lldb_xmm6_x86_64:
968   case lldb_xmm7_x86_64:
969   case lldb_xmm8_x86_64:
970   case lldb_xmm9_x86_64:
971   case lldb_xmm10_x86_64:
972   case lldb_xmm11_x86_64:
973   case lldb_xmm12_x86_64:
974   case lldb_xmm13_x86_64:
975   case lldb_xmm14_x86_64:
976   case lldb_xmm15_x86_64:
977     if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
978       error.SetErrorStringWithFormat(
979           "register \"%s\" not supported by CPU/kernel", reg_info->name);
980     } else {
981       ::memcpy(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
982                reg_value.GetBytes(), reg_value.GetByteSize());
983       new_xstate_bv = XCR0_SSE;
984     }
985     break;
986   case lldb_ymm0_x86_64:
987   case lldb_ymm1_x86_64:
988   case lldb_ymm2_x86_64:
989   case lldb_ymm3_x86_64:
990   case lldb_ymm4_x86_64:
991   case lldb_ymm5_x86_64:
992   case lldb_ymm6_x86_64:
993   case lldb_ymm7_x86_64:
994   case lldb_ymm8_x86_64:
995   case lldb_ymm9_x86_64:
996   case lldb_ymm10_x86_64:
997   case lldb_ymm11_x86_64:
998   case lldb_ymm12_x86_64:
999   case lldb_ymm13_x86_64:
1000   case lldb_ymm14_x86_64:
1001   case lldb_ymm15_x86_64:
1002     if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
1003         !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
1004       error.SetErrorStringWithFormat(
1005           "register \"%s\" not supported by CPU/kernel", reg_info->name);
1006     } else {
1007       uint32_t reg_index = reg - lldb_ymm0_x86_64;
1008       YMMReg ymm;
1009       ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
1010       YMMToXState(ymm, m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
1011                   m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
1012       new_xstate_bv = XCR0_SSE | XCR0_YMM_Hi128;
1013     }
1014     break;
1015   case lldb_dr0_x86_64:
1016   case lldb_dr1_x86_64:
1017   case lldb_dr2_x86_64:
1018   case lldb_dr3_x86_64:
1019   case lldb_dr4_x86_64:
1020   case lldb_dr5_x86_64:
1021   case lldb_dr6_x86_64:
1022   case lldb_dr7_x86_64:
1023     m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
1024     break;
1025   default:
1026     llvm_unreachable("Reading unknown/unsupported register");
1027   }
1028 
1029   if (set == XStateRegSet)
1030     m_xstate.xs_xstate_bv |= new_xstate_bv;
1031 
1032   return WriteRegisterSet(set);
1033 }
1034 
1035 Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
1036     lldb::DataBufferSP &data_sp) {
1037   Status error;
1038 
1039   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
1040   error = ReadRegisterSet(GPRegSet);
1041   if (error.Fail())
1042     return error;
1043 
1044   uint8_t *dst = data_sp->GetBytes();
1045   ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
1046   dst += GetRegisterInfoInterface().GetGPRSize();
1047 
1048   return error;
1049 }
1050 
1051 Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
1052     const lldb::DataBufferSP &data_sp) {
1053   Status error;
1054 
1055   if (!data_sp) {
1056     error.SetErrorStringWithFormat(
1057         "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided",
1058         __FUNCTION__);
1059     return error;
1060   }
1061 
1062   if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
1063     error.SetErrorStringWithFormat(
1064         "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched "
1065         "data size, expected %zu, actual %" PRIu64,
1066         __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
1067     return error;
1068   }
1069 
1070   uint8_t *src = data_sp->GetBytes();
1071   if (src == nullptr) {
1072     error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s "
1073                                    "DataBuffer::GetBytes() returned a null "
1074                                    "pointer",
1075                                    __FUNCTION__);
1076     return error;
1077   }
1078   ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
1079 
1080   error = WriteRegisterSet(GPRegSet);
1081   if (error.Fail())
1082     return error;
1083   src += GetRegisterInfoInterface().GetGPRSize();
1084 
1085   return error;
1086 }
1087 
1088 int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
1089   assert(num >= 0 && num <= 7);
1090   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1091   case llvm::Triple::x86:
1092     return lldb_dr0_i386 + num;
1093   case llvm::Triple::x86_64:
1094     return lldb_dr0_x86_64 + num;
1095   default:
1096     llvm_unreachable("Unhandled target architecture.");
1097   }
1098 }
1099 
1100 llvm::Error NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
1101     NativeRegisterContextNetBSD &source) {
1102   auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
1103   Status res = r_source.ReadRegisterSet(DBRegSet);
1104   if (!res.Fail()) {
1105     // copy dbregs only if any watchpoints were set
1106     if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
1107       return llvm::Error::success();
1108 
1109     m_dbr = r_source.m_dbr;
1110     res = WriteRegisterSet(DBRegSet);
1111   }
1112   return res.ToError();
1113 }
1114 
1115 #endif // defined(__x86_64__)
1116