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