1 //===-- NativeRegisterContextLinux_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 "NativeRegisterContextLinux_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/RegisterContextLinux_i386.h"
20 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
21 #include <cpuid.h>
22 #include <linux/elf.h>
23 
24 // Newer toolchains define __get_cpuid_count in cpuid.h, but some
25 // older-but-still-supported ones (e.g. gcc 5.4.0) don't, so we
26 // define it locally here, following the definition in clang/lib/Headers.
get_cpuid_count(unsigned int __leaf,unsigned int __subleaf,unsigned int * __eax,unsigned int * __ebx,unsigned int * __ecx,unsigned int * __edx)27 static inline int get_cpuid_count(unsigned int __leaf,
28                                   unsigned int __subleaf,
29                                   unsigned int *__eax, unsigned int *__ebx,
30                                   unsigned int *__ecx, unsigned int *__edx)
31 {
32   unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, nullptr);
33 
34   if (__max_leaf == 0 || __max_leaf < __leaf)
35     return 0;
36 
37   __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
38   return 1;
39 }
40 
41 using namespace lldb_private;
42 using namespace lldb_private::process_linux;
43 
44 // Private namespace.
45 
46 namespace {
47 // x86 32-bit general purpose registers.
48 const uint32_t g_gpr_regnums_i386[] = {
49     lldb_eax_i386,      lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,
50     lldb_edi_i386,      lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,
51     lldb_eip_i386,      lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,
52     lldb_gs_i386,       lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,
53     lldb_ax_i386,       lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,
54     lldb_di_i386,       lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,
55     lldb_ah_i386,       lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,
56     lldb_al_i386,       lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,
57     LLDB_INVALID_REGNUM // register sets need to end with this flag
58 };
59 static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
60                       1 ==
61                   k_num_gpr_registers_i386,
62               "g_gpr_regnums_i386 has wrong number of register infos");
63 
64 // x86 32-bit floating point registers.
65 const uint32_t g_fpu_regnums_i386[] = {
66     lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,
67     lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,
68     lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,
69     lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,
70     lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,
71     lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,
72     lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,
73     lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,
74     lldb_xmm6_i386,     lldb_xmm7_i386,
75     LLDB_INVALID_REGNUM // register sets need to end with this flag
76 };
77 static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
78                       1 ==
79                   k_num_fpr_registers_i386,
80               "g_fpu_regnums_i386 has wrong number of register infos");
81 
82 // x86 32-bit AVX registers.
83 const uint32_t g_avx_regnums_i386[] = {
84     lldb_ymm0_i386,     lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
85     lldb_ymm4_i386,     lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
86     LLDB_INVALID_REGNUM // register sets need to end with this flag
87 };
88 static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
89                       1 ==
90                   k_num_avx_registers_i386,
91               " g_avx_regnums_i386 has wrong number of register infos");
92 
93 // x64 32-bit MPX registers.
94 static const uint32_t g_mpx_regnums_i386[] = {
95     lldb_bnd0_i386,     lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386,
96     lldb_bndcfgu_i386,  lldb_bndstatus_i386,
97     LLDB_INVALID_REGNUM // register sets need to end with this flag
98 };
99 static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
100                       1 ==
101                   k_num_mpx_registers_i386,
102               "g_mpx_regnums_x86_64 has wrong number of register infos");
103 
104 // x86 64-bit general purpose registers.
105 static const uint32_t g_gpr_regnums_x86_64[] = {
106     lldb_rax_x86_64,    lldb_rbx_x86_64,    lldb_rcx_x86_64, lldb_rdx_x86_64,
107     lldb_rdi_x86_64,    lldb_rsi_x86_64,    lldb_rbp_x86_64, lldb_rsp_x86_64,
108     lldb_r8_x86_64,     lldb_r9_x86_64,     lldb_r10_x86_64, lldb_r11_x86_64,
109     lldb_r12_x86_64,    lldb_r13_x86_64,    lldb_r14_x86_64, lldb_r15_x86_64,
110     lldb_rip_x86_64,    lldb_rflags_x86_64, lldb_cs_x86_64,  lldb_fs_x86_64,
111     lldb_gs_x86_64,     lldb_ss_x86_64,     lldb_ds_x86_64,  lldb_es_x86_64,
112     lldb_eax_x86_64,    lldb_ebx_x86_64,    lldb_ecx_x86_64, lldb_edx_x86_64,
113     lldb_edi_x86_64,    lldb_esi_x86_64,    lldb_ebp_x86_64, lldb_esp_x86_64,
114     lldb_r8d_x86_64,  // Low 32 bits or r8
115     lldb_r9d_x86_64,  // Low 32 bits or r9
116     lldb_r10d_x86_64, // Low 32 bits or r10
117     lldb_r11d_x86_64, // Low 32 bits or r11
118     lldb_r12d_x86_64, // Low 32 bits or r12
119     lldb_r13d_x86_64, // Low 32 bits or r13
120     lldb_r14d_x86_64, // Low 32 bits or r14
121     lldb_r15d_x86_64, // Low 32 bits or r15
122     lldb_ax_x86_64,     lldb_bx_x86_64,     lldb_cx_x86_64,  lldb_dx_x86_64,
123     lldb_di_x86_64,     lldb_si_x86_64,     lldb_bp_x86_64,  lldb_sp_x86_64,
124     lldb_r8w_x86_64,  // Low 16 bits or r8
125     lldb_r9w_x86_64,  // Low 16 bits or r9
126     lldb_r10w_x86_64, // Low 16 bits or r10
127     lldb_r11w_x86_64, // Low 16 bits or r11
128     lldb_r12w_x86_64, // Low 16 bits or r12
129     lldb_r13w_x86_64, // Low 16 bits or r13
130     lldb_r14w_x86_64, // Low 16 bits or r14
131     lldb_r15w_x86_64, // Low 16 bits or r15
132     lldb_ah_x86_64,     lldb_bh_x86_64,     lldb_ch_x86_64,  lldb_dh_x86_64,
133     lldb_al_x86_64,     lldb_bl_x86_64,     lldb_cl_x86_64,  lldb_dl_x86_64,
134     lldb_dil_x86_64,    lldb_sil_x86_64,    lldb_bpl_x86_64, lldb_spl_x86_64,
135     lldb_r8l_x86_64,    // Low 8 bits or r8
136     lldb_r9l_x86_64,    // Low 8 bits or r9
137     lldb_r10l_x86_64,   // Low 8 bits or r10
138     lldb_r11l_x86_64,   // Low 8 bits or r11
139     lldb_r12l_x86_64,   // Low 8 bits or r12
140     lldb_r13l_x86_64,   // Low 8 bits or r13
141     lldb_r14l_x86_64,   // Low 8 bits or r14
142     lldb_r15l_x86_64,   // Low 8 bits or r15
143     LLDB_INVALID_REGNUM // register sets need to end with this flag
144 };
145 static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
146                       1 ==
147                   k_num_gpr_registers_x86_64,
148               "g_gpr_regnums_x86_64 has wrong number of register infos");
149 
150 // x86 64-bit floating point registers.
151 static const uint32_t g_fpu_regnums_x86_64[] = {
152     lldb_fctrl_x86_64,     lldb_fstat_x86_64, lldb_ftag_x86_64,
153     lldb_fop_x86_64,       lldb_fiseg_x86_64, lldb_fioff_x86_64,
154     lldb_foseg_x86_64,     lldb_fooff_x86_64, lldb_mxcsr_x86_64,
155     lldb_mxcsrmask_x86_64, lldb_st0_x86_64,   lldb_st1_x86_64,
156     lldb_st2_x86_64,       lldb_st3_x86_64,   lldb_st4_x86_64,
157     lldb_st5_x86_64,       lldb_st6_x86_64,   lldb_st7_x86_64,
158     lldb_mm0_x86_64,       lldb_mm1_x86_64,   lldb_mm2_x86_64,
159     lldb_mm3_x86_64,       lldb_mm4_x86_64,   lldb_mm5_x86_64,
160     lldb_mm6_x86_64,       lldb_mm7_x86_64,   lldb_xmm0_x86_64,
161     lldb_xmm1_x86_64,      lldb_xmm2_x86_64,  lldb_xmm3_x86_64,
162     lldb_xmm4_x86_64,      lldb_xmm5_x86_64,  lldb_xmm6_x86_64,
163     lldb_xmm7_x86_64,      lldb_xmm8_x86_64,  lldb_xmm9_x86_64,
164     lldb_xmm10_x86_64,     lldb_xmm11_x86_64, lldb_xmm12_x86_64,
165     lldb_xmm13_x86_64,     lldb_xmm14_x86_64, lldb_xmm15_x86_64,
166     LLDB_INVALID_REGNUM // register sets need to end with this flag
167 };
168 static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
169                       1 ==
170                   k_num_fpr_registers_x86_64,
171               "g_fpu_regnums_x86_64 has wrong number of register infos");
172 
173 // x86 64-bit AVX registers.
174 static const uint32_t g_avx_regnums_x86_64[] = {
175     lldb_ymm0_x86_64,   lldb_ymm1_x86_64,  lldb_ymm2_x86_64,  lldb_ymm3_x86_64,
176     lldb_ymm4_x86_64,   lldb_ymm5_x86_64,  lldb_ymm6_x86_64,  lldb_ymm7_x86_64,
177     lldb_ymm8_x86_64,   lldb_ymm9_x86_64,  lldb_ymm10_x86_64, lldb_ymm11_x86_64,
178     lldb_ymm12_x86_64,  lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
179     LLDB_INVALID_REGNUM // register sets need to end with this flag
180 };
181 static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
182                       1 ==
183                   k_num_avx_registers_x86_64,
184               "g_avx_regnums_x86_64 has wrong number of register infos");
185 
186 // x86 64-bit MPX registers.
187 static const uint32_t g_mpx_regnums_x86_64[] = {
188     lldb_bnd0_x86_64,    lldb_bnd1_x86_64,    lldb_bnd2_x86_64,
189     lldb_bnd3_x86_64,    lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
190     LLDB_INVALID_REGNUM // register sets need to end with this flag
191 };
192 static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
193                       1 ==
194                   k_num_mpx_registers_x86_64,
195               "g_mpx_regnums_x86_64 has wrong number of register infos");
196 
197 // Number of register sets provided by this context.
198 enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 };
199 
200 // Register sets for x86 32-bit.
201 static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
202     {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
203      g_gpr_regnums_i386},
204     {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
205      g_fpu_regnums_i386},
206     {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
207      g_avx_regnums_i386},
208     { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
209      g_mpx_regnums_i386}};
210 
211 // Register sets for x86 64-bit.
212 static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
213     {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
214      g_gpr_regnums_x86_64},
215     {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
216      g_fpu_regnums_x86_64},
217     {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
218      g_avx_regnums_x86_64},
219     { "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
220      g_mpx_regnums_x86_64}};
221 }
222 
223 #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
224 
225 // Required ptrace defines.
226 
227 // Support ptrace extensions even when compiled without required kernel support
228 #ifndef NT_X86_XSTATE
229 #define NT_X86_XSTATE 0x202
230 #endif
231 #ifndef NT_PRXFPREG
232 #define NT_PRXFPREG 0x46e62b7f
233 #endif
234 
235 // On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
236 // use NT_PRXFPREG.
fxsr_regset(const ArchSpec & arch)237 static inline unsigned int fxsr_regset(const ArchSpec &arch) {
238   return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
239 }
240 
241 // Required MPX define.
242 
243 // Support MPX extensions also if compiled with compiler without MPX support.
244 #ifndef bit_MPX
245 #define bit_MPX 0x4000
246 #endif
247 
248 // XCR0 extended register sets masks.
249 #define mask_XSTATE_AVX (1ULL << 2)
250 #define mask_XSTATE_BNDREGS (1ULL << 3)
251 #define mask_XSTATE_BNDCFG (1ULL << 4)
252 #define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
253 
254 std::unique_ptr<NativeRegisterContextLinux>
CreateHostNativeRegisterContextLinux(const ArchSpec & target_arch,NativeThreadProtocol & native_thread)255 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
256     const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
257   return std::unique_ptr<NativeRegisterContextLinux>(
258       new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
259 }
260 
261 // NativeRegisterContextLinux_x86_64 members.
262 
263 static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec & target_arch)264 CreateRegisterInfoInterface(const ArchSpec &target_arch) {
265   if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
266     // 32-bit hosts run with a RegisterContextLinux_i386 context.
267     return new RegisterContextLinux_i386(target_arch);
268   } else {
269     assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
270            "Register setting path assumes this is a 64-bit host");
271     // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
272     // x86_64 register context.
273     return new RegisterContextLinux_x86_64(target_arch);
274   }
275 }
276 
277 // Return the size of the XSTATE area supported on this cpu. It is necessary to
278 // allocate the full size of the area even if we do not use/recognise all of it
279 // because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if
280 // we do not pass it a buffer of sufficient size. The size is always at least
281 // sizeof(FPR) so that the allocated buffer can be safely cast to FPR*.
GetXSTATESize()282 static std::size_t GetXSTATESize() {
283   unsigned int eax, ebx, ecx, edx;
284   // First check whether the XSTATE are is supported at all.
285   if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE))
286     return sizeof(FPR);
287 
288   // Then fetch the maximum size of the area.
289   if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx))
290     return sizeof(FPR);
291   return std::max<std::size_t>(ecx, sizeof(FPR));
292 }
293 
NativeRegisterContextLinux_x86_64(const ArchSpec & target_arch,NativeThreadProtocol & native_thread)294 NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
295     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
296     : NativeRegisterContextLinux(native_thread,
297                                  CreateRegisterInfoInterface(target_arch)),
298       m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),
299       m_reg_info(), m_gpr_x86_64() {
300   // Set up data about ranges of valid registers.
301   switch (target_arch.GetMachine()) {
302   case llvm::Triple::x86:
303     m_reg_info.num_registers = k_num_registers_i386;
304     m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
305     m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
306     m_reg_info.num_avx_registers = k_num_avx_registers_i386;
307     m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
308     m_reg_info.last_gpr = k_last_gpr_i386;
309     m_reg_info.first_fpr = k_first_fpr_i386;
310     m_reg_info.last_fpr = k_last_fpr_i386;
311     m_reg_info.first_st = lldb_st0_i386;
312     m_reg_info.last_st = lldb_st7_i386;
313     m_reg_info.first_mm = lldb_mm0_i386;
314     m_reg_info.last_mm = lldb_mm7_i386;
315     m_reg_info.first_xmm = lldb_xmm0_i386;
316     m_reg_info.last_xmm = lldb_xmm7_i386;
317     m_reg_info.first_ymm = lldb_ymm0_i386;
318     m_reg_info.last_ymm = lldb_ymm7_i386;
319     m_reg_info.first_mpxr = lldb_bnd0_i386;
320     m_reg_info.last_mpxr = lldb_bnd3_i386;
321     m_reg_info.first_mpxc = lldb_bndcfgu_i386;
322     m_reg_info.last_mpxc = lldb_bndstatus_i386;
323     m_reg_info.first_dr = lldb_dr0_i386;
324     m_reg_info.gpr_flags = lldb_eflags_i386;
325     break;
326   case llvm::Triple::x86_64:
327     m_reg_info.num_registers = k_num_registers_x86_64;
328     m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
329     m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
330     m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
331     m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64;
332     m_reg_info.last_gpr = k_last_gpr_x86_64;
333     m_reg_info.first_fpr = k_first_fpr_x86_64;
334     m_reg_info.last_fpr = k_last_fpr_x86_64;
335     m_reg_info.first_st = lldb_st0_x86_64;
336     m_reg_info.last_st = lldb_st7_x86_64;
337     m_reg_info.first_mm = lldb_mm0_x86_64;
338     m_reg_info.last_mm = lldb_mm7_x86_64;
339     m_reg_info.first_xmm = lldb_xmm0_x86_64;
340     m_reg_info.last_xmm = lldb_xmm15_x86_64;
341     m_reg_info.first_ymm = lldb_ymm0_x86_64;
342     m_reg_info.last_ymm = lldb_ymm15_x86_64;
343     m_reg_info.first_mpxr = lldb_bnd0_x86_64;
344     m_reg_info.last_mpxr = lldb_bnd3_x86_64;
345     m_reg_info.first_mpxc = lldb_bndcfgu_x86_64;
346     m_reg_info.last_mpxc = lldb_bndstatus_x86_64;
347     m_reg_info.first_dr = lldb_dr0_x86_64;
348     m_reg_info.gpr_flags = lldb_rflags_x86_64;
349     break;
350   default:
351     assert(false && "Unhandled target architecture.");
352     break;
353   }
354 
355   std::size_t xstate_size = GetXSTATESize();
356   m_xstate.reset(static_cast<FPR *>(std::malloc(xstate_size)));
357   m_iovec.iov_base = m_xstate.get();
358   m_iovec.iov_len = xstate_size;
359 
360   // Clear out the FPR state.
361   ::memset(m_xstate.get(), 0, xstate_size);
362 
363   // Store byte offset of fctrl (i.e. first register of FPR)
364   const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
365   m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
366 }
367 
368 // CONSIDER after local and llgs debugging are merged, register set support can
369 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
GetRegisterSetCount() const370 uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
371   uint32_t sets = 0;
372   for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
373     if (IsRegisterSetAvailable(set_index))
374       ++sets;
375   }
376 
377   return sets;
378 }
379 
GetUserRegisterCount() const380 uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {
381   uint32_t count = 0;
382   for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
383     const RegisterSet *set = GetRegisterSet(set_index);
384     if (set)
385       count += set->num_registers;
386   }
387   return count;
388 }
389 
390 const RegisterSet *
GetRegisterSet(uint32_t set_index) const391 NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {
392   if (!IsRegisterSetAvailable(set_index))
393     return nullptr;
394 
395   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
396   case llvm::Triple::x86:
397     return &g_reg_sets_i386[set_index];
398   case llvm::Triple::x86_64:
399     return &g_reg_sets_x86_64[set_index];
400   default:
401     assert(false && "Unhandled target architecture.");
402     return nullptr;
403   }
404 
405   return nullptr;
406 }
407 
408 Status
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)409 NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
410                                                 RegisterValue &reg_value) {
411   Status error;
412 
413   if (!reg_info) {
414     error.SetErrorString("reg_info NULL");
415     return error;
416   }
417 
418   const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
419   if (reg == LLDB_INVALID_REGNUM) {
420     // This is likely an internal register for lldb use only and should not be
421     // directly queried.
422     error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
423                                    "register, cannot read directly",
424                                    reg_info->name);
425     return error;
426   }
427 
428   if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
429     error = ReadFPR();
430     if (error.Fail())
431       return error;
432   } else {
433     uint32_t full_reg = reg;
434     bool is_subreg = reg_info->invalidate_regs &&
435                      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
436 
437     if (is_subreg) {
438       // Read the full aligned 64-bit register.
439       full_reg = reg_info->invalidate_regs[0];
440     }
441 
442     error = ReadRegisterRaw(full_reg, reg_value);
443 
444     if (error.Success()) {
445       // If our read was not aligned (for ah,bh,ch,dh), shift our returned
446       // value one byte to the right.
447       if (is_subreg && (reg_info->byte_offset & 0x1))
448         reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
449 
450       // If our return byte size was greater than the return value reg size,
451       // then use the type specified by reg_info rather than the uint64_t
452       // default
453       if (reg_value.GetByteSize() > reg_info->byte_size)
454         reg_value.SetType(reg_info);
455     }
456     return error;
457   }
458 
459   if (reg_info->encoding == lldb::eEncodingVector) {
460     lldb::ByteOrder byte_order = GetByteOrder();
461 
462     if (byte_order != lldb::eByteOrderInvalid) {
463       if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
464         reg_value.SetBytes(
465             m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
466             reg_info->byte_size, byte_order);
467       if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
468         reg_value.SetBytes(
469             m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
470             reg_info->byte_size, byte_order);
471       if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
472         reg_value.SetBytes(
473             m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
474             reg_info->byte_size, byte_order);
475       if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
476         // Concatenate ymm using the register halves in xmm.bytes and
477         // ymmh.bytes
478         if (CopyXSTATEtoYMM(reg, byte_order))
479           reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
480                              reg_info->byte_size, byte_order);
481         else {
482           error.SetErrorString("failed to copy ymm register value");
483           return error;
484         }
485       }
486       if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
487         if (CopyXSTATEtoMPX(reg))
488           reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
489                              reg_info->byte_size, byte_order);
490         else {
491           error.SetErrorString("failed to copy mpx register value");
492           return error;
493         }
494       }
495       if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
496         if (CopyXSTATEtoMPX(reg))
497           reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
498                              reg_info->byte_size, byte_order);
499         else {
500           error.SetErrorString("failed to copy mpx register value");
501           return error;
502         }
503       }
504 
505       if (reg_value.GetType() != RegisterValue::eTypeBytes)
506         error.SetErrorString(
507             "write failed - type was expected to be RegisterValue::eTypeBytes");
508 
509       return error;
510     }
511 
512     error.SetErrorString("byte order is invalid");
513     return error;
514   }
515 
516   // Get pointer to m_xstate->fxsave variable and set the data from it.
517 
518   // Byte offsets of all registers are calculated wrt 'UserArea' structure.
519   // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
520   // and stores them in 'm_fpr' (of type FPR structure). To extract values of
521   // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
522   // structure.
523 
524   // Since, FPR structure is also one of the member of UserArea structure.
525   // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
526   // byte_offset(fctrl wrt UserArea)
527   assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR));
528   uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
529                  m_fctrl_offset_in_userarea;
530   switch (reg_info->byte_size) {
531   case 1:
532     reg_value.SetUInt8(*(uint8_t *)src);
533     break;
534   case 2:
535     reg_value.SetUInt16(*(uint16_t *)src);
536     break;
537   case 4:
538     reg_value.SetUInt32(*(uint32_t *)src);
539     break;
540   case 8:
541     reg_value.SetUInt64(*(uint64_t *)src);
542     break;
543   default:
544     assert(false && "Unhandled data size.");
545     error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
546                                    reg_info->byte_size);
547     break;
548   }
549 
550   return error;
551 }
552 
UpdateXSTATEforWrite(uint32_t reg_index)553 void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
554     uint32_t reg_index) {
555   XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;
556   if (IsFPR(reg_index)) {
557     // IsFPR considers both %st and %xmm registers as floating point, but these
558     // map to two features. Set both flags, just in case.
559     xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
560   } else if (IsAVX(reg_index)) {
561     // Lower bytes of some %ymm registers are shared with %xmm registers.
562     xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
563   } else if (IsMPX(reg_index)) {
564     // MPX registers map to two XSAVE features.
565     xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
566   }
567 }
568 
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)569 Status NativeRegisterContextLinux_x86_64::WriteRegister(
570     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
571   assert(reg_info && "reg_info is null");
572 
573   const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
574   if (reg_index == LLDB_INVALID_REGNUM)
575     return Status("no lldb regnum for %s", reg_info && reg_info->name
576                                                ? reg_info->name
577                                                : "<unknown register>");
578 
579   UpdateXSTATEforWrite(reg_index);
580 
581   if (IsGPR(reg_index))
582     return WriteRegisterRaw(reg_index, reg_value);
583 
584   if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
585     if (reg_info->encoding == lldb::eEncodingVector) {
586       if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
587         ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
588                  reg_value.GetBytes(), reg_value.GetByteSize());
589 
590       if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
591         ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
592                  reg_value.GetBytes(), reg_value.GetByteSize());
593 
594       if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
595         ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
596                  reg_value.GetBytes(), reg_value.GetByteSize());
597 
598       if (reg_index >= m_reg_info.first_ymm &&
599           reg_index <= m_reg_info.last_ymm) {
600         // Store ymm register content, and split into the register halves in
601         // xmm.bytes and ymmh.bytes
602         ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
603                  reg_value.GetBytes(), reg_value.GetByteSize());
604         if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
605           return Status("CopyYMMtoXSTATE() failed");
606       }
607 
608       if (reg_index >= m_reg_info.first_mpxr &&
609           reg_index <= m_reg_info.last_mpxr) {
610         ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
611                  reg_value.GetBytes(), reg_value.GetByteSize());
612         if (!CopyMPXtoXSTATE(reg_index))
613           return Status("CopyMPXtoXSTATE() failed");
614       }
615 
616       if (reg_index >= m_reg_info.first_mpxc &&
617           reg_index <= m_reg_info.last_mpxc) {
618         ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
619                  reg_value.GetBytes(), reg_value.GetByteSize());
620         if (!CopyMPXtoXSTATE(reg_index))
621           return Status("CopyMPXtoXSTATE() failed");
622       }
623     } else {
624       // Get pointer to m_xstate->fxsave variable and set the data to it.
625 
626       // Byte offsets of all registers are calculated wrt 'UserArea' structure.
627       // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
628       // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
629       // registers should be written in m_fpr at byte offsets calculated wrt
630       // FPR structure.
631 
632       // Since, FPR structure is also one of the member of UserArea structure.
633       // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
634       // byte_offset(fctrl wrt UserArea)
635       assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
636              sizeof(FPR));
637       uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
638                      m_fctrl_offset_in_userarea;
639       switch (reg_info->byte_size) {
640       case 1:
641         *(uint8_t *)dst = reg_value.GetAsUInt8();
642         break;
643       case 2:
644         *(uint16_t *)dst = reg_value.GetAsUInt16();
645         break;
646       case 4:
647         *(uint32_t *)dst = reg_value.GetAsUInt32();
648         break;
649       case 8:
650         *(uint64_t *)dst = reg_value.GetAsUInt64();
651         break;
652       default:
653         assert(false && "Unhandled data size.");
654         return Status("unhandled register data size %" PRIu32,
655                       reg_info->byte_size);
656       }
657     }
658 
659     Status error = WriteFPR();
660     if (error.Fail())
661       return error;
662 
663     if (IsAVX(reg_index)) {
664       if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
665         return Status("CopyYMMtoXSTATE() failed");
666     }
667 
668     if (IsMPX(reg_index)) {
669       if (!CopyMPXtoXSTATE(reg_index))
670         return Status("CopyMPXtoXSTATE() failed");
671     }
672     return Status();
673   }
674   return Status("failed - register wasn't recognized to be a GPR or an FPR, "
675                 "write strategy unknown");
676 }
677 
ReadAllRegisterValues(lldb::DataBufferSP & data_sp)678 Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
679     lldb::DataBufferSP &data_sp) {
680   Status error;
681 
682   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
683   error = ReadGPR();
684   if (error.Fail())
685     return error;
686 
687   error = ReadFPR();
688   if (error.Fail())
689     return error;
690 
691   uint8_t *dst = data_sp->GetBytes();
692   ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
693   dst += GetRegisterInfoInterface().GetGPRSize();
694   if (m_xstate_type == XStateType::FXSAVE)
695     ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));
696   else if (m_xstate_type == XStateType::XSAVE) {
697     lldb::ByteOrder byte_order = GetByteOrder();
698 
699     if (IsCPUFeatureAvailable(RegSet::avx)) {
700       // Assemble the YMM register content from the register halves.
701       for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
702            ++reg) {
703         if (!CopyXSTATEtoYMM(reg, byte_order)) {
704           error.SetErrorStringWithFormat(
705               "NativeRegisterContextLinux_x86_64::%s "
706               "CopyXSTATEtoYMM() failed for reg num "
707               "%" PRIu32,
708               __FUNCTION__, reg);
709           return error;
710         }
711       }
712     }
713 
714     if (IsCPUFeatureAvailable(RegSet::mpx)) {
715       for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
716            ++reg) {
717         if (!CopyXSTATEtoMPX(reg)) {
718           error.SetErrorStringWithFormat(
719               "NativeRegisterContextLinux_x86_64::%s "
720               "CopyXSTATEtoMPX() failed for reg num "
721               "%" PRIu32,
722               __FUNCTION__, reg);
723           return error;
724         }
725       }
726     }
727     // Copy the extended register state including the assembled ymm registers.
728     ::memcpy(dst, m_xstate.get(), sizeof(FPR));
729   } else {
730     assert(false && "how do we save the floating point registers?");
731     error.SetErrorString("unsure how to save the floating point registers");
732   }
733   /** The following code is specific to Linux x86 based architectures,
734    *  where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
735    *  -1 to solve the bug 23659, such a setting prevents the automatic
736    *  decrement of the instruction pointer which was causing the SIGILL
737    *  exception.
738    * **/
739 
740   RegisterValue value((uint64_t)-1);
741   const RegisterInfo *reg_info =
742       GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
743   if (reg_info == nullptr)
744     reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
745 
746   if (reg_info != nullptr)
747     return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
748 
749   return error;
750 }
751 
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)752 Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
753     const lldb::DataBufferSP &data_sp) {
754   Status error;
755 
756   if (!data_sp) {
757     error.SetErrorStringWithFormat(
758         "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
759         __FUNCTION__);
760     return error;
761   }
762 
763   if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
764     error.SetErrorStringWithFormatv(
765         "data_sp contained mismatched data size, expected {0}, actual {1}",
766         REG_CONTEXT_SIZE, data_sp->GetByteSize());
767     return error;
768   }
769 
770   uint8_t *src = data_sp->GetBytes();
771   if (src == nullptr) {
772     error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
773                                    "DataBuffer::GetBytes() returned a null "
774                                    "pointer",
775                                    __FUNCTION__);
776     return error;
777   }
778   ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
779 
780   error = WriteGPR();
781   if (error.Fail())
782     return error;
783 
784   src += GetRegisterInfoInterface().GetGPRSize();
785   if (m_xstate_type == XStateType::FXSAVE)
786     ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));
787   else if (m_xstate_type == XStateType::XSAVE)
788     ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));
789 
790   error = WriteFPR();
791   if (error.Fail())
792     return error;
793 
794   if (m_xstate_type == XStateType::XSAVE) {
795     lldb::ByteOrder byte_order = GetByteOrder();
796 
797     if (IsCPUFeatureAvailable(RegSet::avx)) {
798       // Parse the YMM register content from the register halves.
799       for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
800            ++reg) {
801         if (!CopyYMMtoXSTATE(reg, byte_order)) {
802           error.SetErrorStringWithFormat(
803               "NativeRegisterContextLinux_x86_64::%s "
804               "CopyYMMtoXSTATE() failed for reg num "
805               "%" PRIu32,
806               __FUNCTION__, reg);
807           return error;
808         }
809       }
810     }
811 
812     if (IsCPUFeatureAvailable(RegSet::mpx)) {
813       for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
814            ++reg) {
815         if (!CopyMPXtoXSTATE(reg)) {
816           error.SetErrorStringWithFormat(
817               "NativeRegisterContextLinux_x86_64::%s "
818               "CopyMPXtoXSTATE() failed for reg num "
819               "%" PRIu32,
820               __FUNCTION__, reg);
821           return error;
822         }
823       }
824     }
825   }
826 
827   return error;
828 }
829 
IsCPUFeatureAvailable(RegSet feature_code) const830 bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
831     RegSet feature_code) const {
832   if (m_xstate_type == XStateType::Invalid) {
833     if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())
834       return false;
835   }
836   switch (feature_code) {
837   case RegSet::gpr:
838   case RegSet::fpu:
839     return true;
840   case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
841                     // reading in the XCR0 area of XSAVE.
842     if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
843       return true;
844      break;
845   case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
846                     // reading in the XCR0 area of XSAVE.
847     if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
848       return true;
849     break;
850   }
851   return false;
852 }
853 
IsRegisterSetAvailable(uint32_t set_index) const854 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
855     uint32_t set_index) const {
856   uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
857 
858   switch (static_cast<RegSet>(set_index)) {
859   case RegSet::gpr:
860   case RegSet::fpu:
861     return (set_index < num_sets);
862   case RegSet::avx:
863     return IsCPUFeatureAvailable(RegSet::avx);
864   case RegSet::mpx:
865     return IsCPUFeatureAvailable(RegSet::mpx);
866   }
867   return false;
868 }
869 
IsGPR(uint32_t reg_index) const870 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
871   // GPRs come first.
872   return reg_index <= m_reg_info.last_gpr;
873 }
874 
IsFPR(uint32_t reg_index) const875 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
876   return (m_reg_info.first_fpr <= reg_index &&
877           reg_index <= m_reg_info.last_fpr);
878 }
879 
WriteFPR()880 Status NativeRegisterContextLinux_x86_64::WriteFPR() {
881   switch (m_xstate_type) {
882   case XStateType::FXSAVE:
883     return WriteRegisterSet(
884         &m_iovec, sizeof(m_xstate->fxsave),
885         fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
886   case XStateType::XSAVE:
887     return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
888   default:
889     return Status("Unrecognized FPR type.");
890   }
891 }
892 
IsAVX(uint32_t reg_index) const893 bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
894   if (!IsCPUFeatureAvailable(RegSet::avx))
895     return false;
896   return (m_reg_info.first_ymm <= reg_index &&
897           reg_index <= m_reg_info.last_ymm);
898 }
899 
CopyXSTATEtoYMM(uint32_t reg_index,lldb::ByteOrder byte_order)900 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
901     uint32_t reg_index, lldb::ByteOrder byte_order) {
902   if (!IsAVX(reg_index))
903     return false;
904 
905   if (byte_order == lldb::eByteOrderLittle) {
906     uint32_t reg_no = reg_index - m_reg_info.first_ymm;
907     m_ymm_set.ymm[reg_no] = XStateToYMM(
908         m_xstate->fxsave.xmm[reg_no].bytes,
909         m_xstate->xsave.ymmh[reg_no].bytes);
910     return true;
911   }
912 
913   return false; // unsupported or invalid byte order
914 }
915 
CopyYMMtoXSTATE(uint32_t reg,lldb::ByteOrder byte_order)916 bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
917     uint32_t reg, lldb::ByteOrder byte_order) {
918   if (!IsAVX(reg))
919     return false;
920 
921   if (byte_order == lldb::eByteOrderLittle) {
922     uint32_t reg_no = reg - m_reg_info.first_ymm;
923     YMMToXState(m_ymm_set.ymm[reg_no],
924         m_xstate->fxsave.xmm[reg_no].bytes,
925         m_xstate->xsave.ymmh[reg_no].bytes);
926     return true;
927   }
928 
929   return false; // unsupported or invalid byte order
930 }
931 
GetFPRBuffer()932 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
933   switch (m_xstate_type) {
934   case XStateType::FXSAVE:
935     return &m_xstate->fxsave;
936   case XStateType::XSAVE:
937     return &m_iovec;
938   default:
939     return nullptr;
940   }
941 }
942 
GetFPRSize()943 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
944   switch (m_xstate_type) {
945   case XStateType::FXSAVE:
946     return sizeof(m_xstate->fxsave);
947   case XStateType::XSAVE:
948     return sizeof(m_iovec);
949   default:
950     return 0;
951   }
952 }
953 
ReadFPR()954 Status NativeRegisterContextLinux_x86_64::ReadFPR() {
955   Status error;
956 
957   // Probe XSAVE and if it is not supported fall back to FXSAVE.
958   if (m_xstate_type != XStateType::FXSAVE) {
959     error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
960     if (!error.Fail()) {
961       m_xstate_type = XStateType::XSAVE;
962       return error;
963     }
964   }
965   error = ReadRegisterSet(
966       &m_iovec, sizeof(m_xstate->xsave),
967       fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
968   if (!error.Fail()) {
969     m_xstate_type = XStateType::FXSAVE;
970     return error;
971   }
972   return Status("Unrecognized FPR type.");
973 }
974 
IsMPX(uint32_t reg_index) const975 bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {
976   if (!IsCPUFeatureAvailable(RegSet::mpx))
977     return false;
978   return (m_reg_info.first_mpxr <= reg_index &&
979           reg_index <= m_reg_info.last_mpxc);
980 }
981 
CopyXSTATEtoMPX(uint32_t reg)982 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
983   if (!IsMPX(reg))
984     return false;
985 
986   if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
987     ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
988              m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
989              sizeof(MPXReg));
990   } else {
991     ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
992              m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
993              sizeof(MPXCsr));
994   }
995   return true;
996 }
997 
CopyMPXtoXSTATE(uint32_t reg)998 bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
999   if (!IsMPX(reg))
1000     return false;
1001 
1002   if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1003     ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1004              m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
1005   } else {
1006     ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1007              m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
1008   }
1009   return true;
1010 }
1011 
IsWatchpointHit(uint32_t wp_index,bool & is_hit)1012 Status NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
1013                                                           bool &is_hit) {
1014   if (wp_index >= NumSupportedHardwareWatchpoints())
1015     return Status("Watchpoint index out of range");
1016 
1017   RegisterValue reg_value;
1018   Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
1019   if (error.Fail()) {
1020     is_hit = false;
1021     return error;
1022   }
1023 
1024   uint64_t status_bits = reg_value.GetAsUInt64();
1025 
1026   is_hit = status_bits & (1 << wp_index);
1027 
1028   return error;
1029 }
1030 
GetWatchpointHitIndex(uint32_t & wp_index,lldb::addr_t trap_addr)1031 Status NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(
1032     uint32_t &wp_index, lldb::addr_t trap_addr) {
1033   uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
1034   for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
1035     bool is_hit;
1036     Status error = IsWatchpointHit(wp_index, is_hit);
1037     if (error.Fail()) {
1038       wp_index = LLDB_INVALID_INDEX32;
1039       return error;
1040     } else if (is_hit) {
1041       return error;
1042     }
1043   }
1044   wp_index = LLDB_INVALID_INDEX32;
1045   return Status();
1046 }
1047 
IsWatchpointVacant(uint32_t wp_index,bool & is_vacant)1048 Status NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
1049                                                              bool &is_vacant) {
1050   if (wp_index >= NumSupportedHardwareWatchpoints())
1051     return Status("Watchpoint index out of range");
1052 
1053   RegisterValue reg_value;
1054   Status error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
1055   if (error.Fail()) {
1056     is_vacant = false;
1057     return error;
1058   }
1059 
1060   uint64_t control_bits = reg_value.GetAsUInt64();
1061 
1062   is_vacant = !(control_bits & (1 << (2 * wp_index)));
1063 
1064   return error;
1065 }
1066 
SetHardwareWatchpointWithIndex(lldb::addr_t addr,size_t size,uint32_t watch_flags,uint32_t wp_index)1067 Status NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
1068     lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
1069 
1070   if (wp_index >= NumSupportedHardwareWatchpoints())
1071     return Status("Watchpoint index out of range");
1072 
1073   // Read only watchpoints aren't supported on x86_64. Fall back to read/write
1074   // waitchpoints instead.
1075   // TODO: Add logic to detect when a write happens and ignore that watchpoint
1076   // hit.
1077   if (watch_flags == 0x2)
1078     watch_flags = 0x3;
1079 
1080   if (watch_flags != 0x1 && watch_flags != 0x3)
1081     return Status("Invalid read/write bits for watchpoint");
1082 
1083   if (size != 1 && size != 2 && size != 4 && size != 8)
1084     return Status("Invalid size for watchpoint");
1085 
1086   bool is_vacant;
1087   Status error = IsWatchpointVacant(wp_index, is_vacant);
1088   if (error.Fail())
1089     return error;
1090   if (!is_vacant)
1091     return Status("Watchpoint index not vacant");
1092 
1093   RegisterValue reg_value;
1094   error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
1095   if (error.Fail())
1096     return error;
1097 
1098   // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
1099   uint64_t enable_bit = 1 << (2 * wp_index);
1100 
1101   // set bits 16-17, 20-21, 24-25, or 28-29
1102   // with 0b01 for write, and 0b11 for read/write
1103   uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
1104 
1105   // set bits 18-19, 22-23, 26-27, or 30-31
1106   // with 0b00, 0b01, 0b10, or 0b11
1107   // for 1, 2, 8 (if supported), or 4 bytes, respectively
1108   uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
1109 
1110   uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
1111 
1112   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1113 
1114   control_bits |= enable_bit | rw_bits | size_bits;
1115 
1116   error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
1117   if (error.Fail())
1118     return error;
1119 
1120   error =
1121       WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
1122   if (error.Fail())
1123     return error;
1124 
1125   error.Clear();
1126   return error;
1127 }
1128 
ClearHardwareWatchpoint(uint32_t wp_index)1129 bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
1130     uint32_t wp_index) {
1131   if (wp_index >= NumSupportedHardwareWatchpoints())
1132     return false;
1133 
1134   RegisterValue reg_value;
1135 
1136   // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0, 1, 2, or 3 of
1137   // the debug status register (DR6)
1138   Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
1139   if (error.Fail())
1140     return false;
1141   uint64_t bit_mask = 1 << wp_index;
1142   uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
1143   error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
1144   if (error.Fail())
1145     return false;
1146 
1147   // for watchpoints 0, 1, 2, or 3, respectively, clear bits {0-1,16-19},
1148   // {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} of the debug control register
1149   // (DR7)
1150   error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
1151   if (error.Fail())
1152     return false;
1153   bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
1154   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1155   return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
1156       .Success();
1157 }
1158 
ClearAllHardwareWatchpoints()1159 Status NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
1160   RegisterValue reg_value;
1161 
1162   // clear bits {0-4} of the debug status register (DR6)
1163   Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
1164   if (error.Fail())
1165     return error;
1166   uint64_t bit_mask = 0xF;
1167   uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
1168   error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
1169   if (error.Fail())
1170     return error;
1171 
1172   // clear bits {0-7,16-31} of the debug control register (DR7)
1173   error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
1174   if (error.Fail())
1175     return error;
1176   bit_mask = 0xFF | (0xFFFF << 16);
1177   uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
1178   return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
1179 }
1180 
SetHardwareWatchpoint(lldb::addr_t addr,size_t size,uint32_t watch_flags)1181 uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
1182     lldb::addr_t addr, size_t size, uint32_t watch_flags) {
1183   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1184   const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1185   for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
1186     bool is_vacant;
1187     Status error = IsWatchpointVacant(wp_index, is_vacant);
1188     if (is_vacant) {
1189       error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
1190       if (error.Success())
1191         return wp_index;
1192     }
1193     if (error.Fail() && log) {
1194       LLDB_LOGF(log, "NativeRegisterContextLinux_x86_64::%s Error: %s",
1195                 __FUNCTION__, error.AsCString());
1196     }
1197   }
1198   return LLDB_INVALID_INDEX32;
1199 }
1200 
1201 lldb::addr_t
GetWatchpointAddress(uint32_t wp_index)1202 NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) {
1203   if (wp_index >= NumSupportedHardwareWatchpoints())
1204     return LLDB_INVALID_ADDRESS;
1205   RegisterValue reg_value;
1206   if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
1207     return LLDB_INVALID_ADDRESS;
1208   return reg_value.GetAsUInt64();
1209 }
1210 
NumSupportedHardwareWatchpoints()1211 uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
1212   // Available debug address registers: dr0, dr1, dr2, dr3
1213   return 4;
1214 }
1215 
1216 uint32_t
GetPtraceOffset(uint32_t reg_index)1217 NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
1218   // If register is MPX, remove extra factor from gdb offset
1219   return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1220          (IsMPX(reg_index) ? 128 : 0);
1221 }
1222 
1223 #endif // defined(__i386__) || defined(__x86_64__)
1224