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