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 = (uint64_t)m_gpr.regs[_REG_FS];
543     break;
544   case lldb_gs_x86_64:
545     reg_value = (uint64_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 = (uint64_t)m_gpr.regs[_REG_DS];
552     break;
553   case lldb_es_x86_64:
554     reg_value = (uint64_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 = (uint32_t)m_gpr.r_fs;
592     break;
593   case lldb_gs_x86_64:
594     reg_value = (uint32_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 = (uint32_t)m_gpr.r_ds;
601     break;
602   case lldb_es_x86_64:
603     reg_value = (uint32_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   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
758   case llvm::Triple::x86_64:
759     break;
760   case llvm::Triple::x86:
761     reg = RegNumX86ToX86_64(reg);
762     break;
763   default:
764     llvm_unreachable("Unhandled target architecture.");
765   }
766 
767   error = ReadRegisterSet(set);
768   if (error.Fail())
769     return error;
770 
771   switch (reg) {
772 #if defined(__x86_64__)
773   case lldb_rax_x86_64:
774     m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
775     break;
776   case lldb_rbx_x86_64:
777     m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
778     break;
779   case lldb_rcx_x86_64:
780     m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
781     break;
782   case lldb_rdx_x86_64:
783     m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
784     break;
785   case lldb_rdi_x86_64:
786     m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
787     break;
788   case lldb_rsi_x86_64:
789     m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
790     break;
791   case lldb_rbp_x86_64:
792     m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
793     break;
794   case lldb_rsp_x86_64:
795     m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
796     break;
797   case lldb_r8_x86_64:
798     m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
799     break;
800   case lldb_r9_x86_64:
801     m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
802     break;
803   case lldb_r10_x86_64:
804     m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
805     break;
806   case lldb_r11_x86_64:
807     m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
808     break;
809   case lldb_r12_x86_64:
810     m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
811     break;
812   case lldb_r13_x86_64:
813     m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
814     break;
815   case lldb_r14_x86_64:
816     m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
817     break;
818   case lldb_r15_x86_64:
819     m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
820     break;
821   case lldb_rip_x86_64:
822     m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
823     break;
824   case lldb_rflags_x86_64:
825     m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
826     break;
827   case lldb_cs_x86_64:
828     m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
829     break;
830   case lldb_fs_x86_64:
831     m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64();
832     break;
833   case lldb_gs_x86_64:
834     m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64();
835     break;
836   case lldb_ss_x86_64:
837     m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
838     break;
839   case lldb_ds_x86_64:
840     m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64();
841     break;
842   case lldb_es_x86_64:
843     m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64();
844     break;
845 #else
846   case lldb_rax_x86_64:
847     m_gpr.r_eax = reg_value.GetAsUInt32();
848     break;
849   case lldb_rbx_x86_64:
850     m_gpr.r_ebx = reg_value.GetAsUInt32();
851     break;
852   case lldb_rcx_x86_64:
853     m_gpr.r_ecx = reg_value.GetAsUInt32();
854     break;
855   case lldb_rdx_x86_64:
856     m_gpr.r_edx = reg_value.GetAsUInt32();
857     break;
858   case lldb_rdi_x86_64:
859     m_gpr.r_edi = reg_value.GetAsUInt32();
860     break;
861   case lldb_rsi_x86_64:
862     m_gpr.r_esi = reg_value.GetAsUInt32();
863     break;
864   case lldb_rsp_x86_64:
865     m_gpr.r_esp = reg_value.GetAsUInt32();
866     break;
867   case lldb_rbp_x86_64:
868     m_gpr.r_ebp = reg_value.GetAsUInt32();
869     break;
870   case lldb_rip_x86_64:
871     m_gpr.r_eip = reg_value.GetAsUInt32();
872     break;
873   case lldb_rflags_x86_64:
874     m_gpr.r_eflags = reg_value.GetAsUInt32();
875     break;
876   case lldb_cs_x86_64:
877     m_gpr.r_cs = reg_value.GetAsUInt32();
878     break;
879   case lldb_fs_x86_64:
880     m_gpr.r_fs = reg_value.GetAsUInt32();
881     break;
882   case lldb_gs_x86_64:
883     m_gpr.r_gs = reg_value.GetAsUInt32();
884     break;
885   case lldb_ss_x86_64:
886     m_gpr.r_ss = reg_value.GetAsUInt32();
887     break;
888   case lldb_ds_x86_64:
889     m_gpr.r_ds = reg_value.GetAsUInt32();
890     break;
891   case lldb_es_x86_64:
892     m_gpr.r_es = reg_value.GetAsUInt32();
893     break;
894 #endif
895   case lldb_fctrl_x86_64:
896     m_xstate.xs_fxsave.fx_cw = reg_value.GetAsUInt16();
897     break;
898   case lldb_fstat_x86_64:
899     m_xstate.xs_fxsave.fx_sw = reg_value.GetAsUInt16();
900     break;
901   case lldb_ftag_x86_64:
902     m_xstate.xs_fxsave.fx_tw = reg_value.GetAsUInt16();
903     break;
904   case lldb_fop_x86_64:
905     m_xstate.xs_fxsave.fx_opcode = reg_value.GetAsUInt16();
906     break;
907   case lldb_fiseg_x86_64:
908     m_xstate.xs_fxsave.fx_ip.fa_32.fa_seg = reg_value.GetAsUInt32();
909     break;
910   case lldb_fioff_x86_64:
911     m_xstate.xs_fxsave.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
912     break;
913   case lldb_foseg_x86_64:
914     m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32();
915     break;
916   case lldb_fooff_x86_64:
917     m_xstate.xs_fxsave.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
918     break;
919   case lldb_mxcsr_x86_64:
920     m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32();
921     break;
922   case lldb_mxcsrmask_x86_64:
923     m_xstate.xs_fxsave.fx_mxcsr_mask = reg_value.GetAsUInt32();
924     break;
925   case lldb_st0_x86_64:
926   case lldb_st1_x86_64:
927   case lldb_st2_x86_64:
928   case lldb_st3_x86_64:
929   case lldb_st4_x86_64:
930   case lldb_st5_x86_64:
931   case lldb_st6_x86_64:
932   case lldb_st7_x86_64:
933     ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_st0_x86_64],
934              reg_value.GetBytes(), reg_value.GetByteSize());
935     break;
936   case lldb_mm0_x86_64:
937   case lldb_mm1_x86_64:
938   case lldb_mm2_x86_64:
939   case lldb_mm3_x86_64:
940   case lldb_mm4_x86_64:
941   case lldb_mm5_x86_64:
942   case lldb_mm6_x86_64:
943   case lldb_mm7_x86_64:
944     ::memcpy(&m_xstate.xs_fxsave.fx_87_ac[reg - lldb_mm0_x86_64],
945              reg_value.GetBytes(), reg_value.GetByteSize());
946     break;
947   case lldb_xmm0_x86_64:
948   case lldb_xmm1_x86_64:
949   case lldb_xmm2_x86_64:
950   case lldb_xmm3_x86_64:
951   case lldb_xmm4_x86_64:
952   case lldb_xmm5_x86_64:
953   case lldb_xmm6_x86_64:
954   case lldb_xmm7_x86_64:
955   case lldb_xmm8_x86_64:
956   case lldb_xmm9_x86_64:
957   case lldb_xmm10_x86_64:
958   case lldb_xmm11_x86_64:
959   case lldb_xmm12_x86_64:
960   case lldb_xmm13_x86_64:
961   case lldb_xmm14_x86_64:
962   case lldb_xmm15_x86_64:
963     if (!(m_xstate.xs_rfbm & XCR0_SSE)) {
964       error.SetErrorStringWithFormat(
965           "register \"%s\" not supported by CPU/kernel", reg_info->name);
966     } else {
967       ::memcpy(&m_xstate.xs_fxsave.fx_xmm[reg - lldb_xmm0_x86_64],
968                reg_value.GetBytes(), reg_value.GetByteSize());
969     }
970     break;
971   case lldb_ymm0_x86_64:
972   case lldb_ymm1_x86_64:
973   case lldb_ymm2_x86_64:
974   case lldb_ymm3_x86_64:
975   case lldb_ymm4_x86_64:
976   case lldb_ymm5_x86_64:
977   case lldb_ymm6_x86_64:
978   case lldb_ymm7_x86_64:
979   case lldb_ymm8_x86_64:
980   case lldb_ymm9_x86_64:
981   case lldb_ymm10_x86_64:
982   case lldb_ymm11_x86_64:
983   case lldb_ymm12_x86_64:
984   case lldb_ymm13_x86_64:
985   case lldb_ymm14_x86_64:
986   case lldb_ymm15_x86_64:
987     if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
988         !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
989       error.SetErrorStringWithFormat(
990           "register \"%s\" not supported by CPU/kernel", reg_info->name);
991     } else {
992       uint32_t reg_index = reg - lldb_ymm0_x86_64;
993       YMMReg ymm;
994       ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
995       YMMToXState(ymm, m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
996                   m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
997     }
998     break;
999   case lldb_dr0_x86_64:
1000   case lldb_dr1_x86_64:
1001   case lldb_dr2_x86_64:
1002   case lldb_dr3_x86_64:
1003   case lldb_dr4_x86_64:
1004   case lldb_dr5_x86_64:
1005   case lldb_dr6_x86_64:
1006   case lldb_dr7_x86_64:
1007     m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
1008     break;
1009   default:
1010     llvm_unreachable("Reading unknown/unsupported register");
1011   }
1012 
1013   return WriteRegisterSet(set);
1014 }
1015 
1016 Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
1017     lldb::DataBufferSP &data_sp) {
1018   Status error;
1019 
1020   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
1021   error = ReadRegisterSet(GPRegSet);
1022   if (error.Fail())
1023     return error;
1024 
1025   uint8_t *dst = data_sp->GetBytes();
1026   ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
1027   dst += GetRegisterInfoInterface().GetGPRSize();
1028 
1029   return error;
1030 }
1031 
1032 Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
1033     const lldb::DataBufferSP &data_sp) {
1034   Status error;
1035 
1036   if (!data_sp) {
1037     error.SetErrorStringWithFormat(
1038         "NativeRegisterContextNetBSD_x86_64::%s invalid data_sp provided",
1039         __FUNCTION__);
1040     return error;
1041   }
1042 
1043   if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
1044     error.SetErrorStringWithFormat(
1045         "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched "
1046         "data size, expected %zu, actual %" PRIu64,
1047         __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
1048     return error;
1049   }
1050 
1051   uint8_t *src = data_sp->GetBytes();
1052   if (src == nullptr) {
1053     error.SetErrorStringWithFormat("NativeRegisterContextNetBSD_x86_64::%s "
1054                                    "DataBuffer::GetBytes() returned a null "
1055                                    "pointer",
1056                                    __FUNCTION__);
1057     return error;
1058   }
1059   ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
1060 
1061   error = WriteRegisterSet(GPRegSet);
1062   if (error.Fail())
1063     return error;
1064   src += GetRegisterInfoInterface().GetGPRSize();
1065 
1066   return error;
1067 }
1068 
1069 int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
1070   assert(num >= 0 && num <= 7);
1071   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1072   case llvm::Triple::x86:
1073     return lldb_dr0_i386 + num;
1074   case llvm::Triple::x86_64:
1075     return lldb_dr0_x86_64 + num;
1076   default:
1077     llvm_unreachable("Unhandled target architecture.");
1078   }
1079 }
1080 
1081 Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
1082     NativeRegisterContextNetBSD &source) {
1083   auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
1084   Status res = r_source.ReadRegisterSet(DBRegSet);
1085   if (!res.Fail()) {
1086     // copy dbregs only if any watchpoints were set
1087     if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
1088       return res;
1089 
1090     m_dbr = r_source.m_dbr;
1091     res = WriteRegisterSet(DBRegSet);
1092   }
1093   return res;
1094 }
1095 
1096 #endif // defined(__x86_64__)
1097