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