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