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 
534   if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) {
535     reg_value.SetUInt16(AbridgedToFullTagWord(
536         m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
537     return error;
538   }
539 
540   switch (reg_info->byte_size) {
541   case 1:
542     reg_value.SetUInt8(*(uint8_t *)src);
543     break;
544   case 2:
545     reg_value.SetUInt16(*(uint16_t *)src);
546     break;
547   case 4:
548     reg_value.SetUInt32(*(uint32_t *)src);
549     break;
550   case 8:
551     reg_value.SetUInt64(*(uint64_t *)src);
552     break;
553   default:
554     assert(false && "Unhandled data size.");
555     error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
556                                    reg_info->byte_size);
557     break;
558   }
559 
560   return error;
561 }
562 
563 void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
564     uint32_t reg_index) {
565   XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;
566   if (IsFPR(reg_index)) {
567     // IsFPR considers both %st and %xmm registers as floating point, but these
568     // map to two features. Set both flags, just in case.
569     xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
570   } else if (IsAVX(reg_index)) {
571     // Lower bytes of some %ymm registers are shared with %xmm registers.
572     xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
573   } else if (IsMPX(reg_index)) {
574     // MPX registers map to two XSAVE features.
575     xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
576   }
577 }
578 
579 Status NativeRegisterContextLinux_x86_64::WriteRegister(
580     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
581   assert(reg_info && "reg_info is null");
582 
583   const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
584   if (reg_index == LLDB_INVALID_REGNUM)
585     return Status("no lldb regnum for %s", reg_info && reg_info->name
586                                                ? reg_info->name
587                                                : "<unknown register>");
588 
589   UpdateXSTATEforWrite(reg_index);
590 
591   if (IsGPR(reg_index) || IsDR(reg_index))
592     return WriteRegisterRaw(reg_index, reg_value);
593 
594   if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
595     if (reg_info->encoding == lldb::eEncodingVector) {
596       if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
597         ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
598                  reg_value.GetBytes(), reg_value.GetByteSize());
599 
600       if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
601         ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
602                  reg_value.GetBytes(), reg_value.GetByteSize());
603 
604       if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
605         ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
606                  reg_value.GetBytes(), reg_value.GetByteSize());
607 
608       if (reg_index >= m_reg_info.first_ymm &&
609           reg_index <= m_reg_info.last_ymm) {
610         // Store ymm register content, and split into the register halves in
611         // xmm.bytes and ymmh.bytes
612         ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
613                  reg_value.GetBytes(), reg_value.GetByteSize());
614         if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
615           return Status("CopyYMMtoXSTATE() failed");
616       }
617 
618       if (reg_index >= m_reg_info.first_mpxr &&
619           reg_index <= m_reg_info.last_mpxr) {
620         ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
621                  reg_value.GetBytes(), reg_value.GetByteSize());
622         if (!CopyMPXtoXSTATE(reg_index))
623           return Status("CopyMPXtoXSTATE() failed");
624       }
625 
626       if (reg_index >= m_reg_info.first_mpxc &&
627           reg_index <= m_reg_info.last_mpxc) {
628         ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
629                  reg_value.GetBytes(), reg_value.GetByteSize());
630         if (!CopyMPXtoXSTATE(reg_index))
631           return Status("CopyMPXtoXSTATE() failed");
632       }
633     } else {
634       // Get pointer to m_xstate->fxsave variable and set the data to it.
635 
636       // Byte offsets of all registers are calculated wrt 'UserArea' structure.
637       // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
638       // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
639       // registers should be written in m_fpr at byte offsets calculated wrt
640       // FPR structure.
641 
642       // Since, FPR structure is also one of the member of UserArea structure.
643       // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
644       // byte_offset(fctrl wrt UserArea)
645       assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
646              sizeof(FPR));
647       uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
648                      m_fctrl_offset_in_userarea;
649 
650       if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag))
651         m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
652       else {
653         switch (reg_info->byte_size) {
654         case 1:
655           *(uint8_t *)dst = reg_value.GetAsUInt8();
656           break;
657         case 2:
658           *(uint16_t *)dst = reg_value.GetAsUInt16();
659           break;
660         case 4:
661           *(uint32_t *)dst = reg_value.GetAsUInt32();
662           break;
663         case 8:
664           *(uint64_t *)dst = reg_value.GetAsUInt64();
665           break;
666         default:
667           assert(false && "Unhandled data size.");
668           return Status("unhandled register data size %" PRIu32,
669                         reg_info->byte_size);
670         }
671       }
672     }
673 
674     Status error = WriteFPR();
675     if (error.Fail())
676       return error;
677 
678     if (IsAVX(reg_index)) {
679       if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
680         return Status("CopyYMMtoXSTATE() failed");
681     }
682 
683     if (IsMPX(reg_index)) {
684       if (!CopyMPXtoXSTATE(reg_index))
685         return Status("CopyMPXtoXSTATE() failed");
686     }
687     return Status();
688   }
689   return Status("failed - register wasn't recognized to be a GPR or an FPR, "
690                 "write strategy unknown");
691 }
692 
693 Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
694     lldb::DataBufferSP &data_sp) {
695   Status error;
696 
697   data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
698   error = ReadGPR();
699   if (error.Fail())
700     return error;
701 
702   error = ReadFPR();
703   if (error.Fail())
704     return error;
705 
706   uint8_t *dst = data_sp->GetBytes();
707   ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
708   dst += GetRegisterInfoInterface().GetGPRSize();
709   if (m_xstate_type == XStateType::FXSAVE)
710     ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));
711   else if (m_xstate_type == XStateType::XSAVE) {
712     lldb::ByteOrder byte_order = GetByteOrder();
713 
714     if (IsCPUFeatureAvailable(RegSet::avx)) {
715       // Assemble the YMM register content from the register halves.
716       for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
717            ++reg) {
718         if (!CopyXSTATEtoYMM(reg, byte_order)) {
719           error.SetErrorStringWithFormat(
720               "NativeRegisterContextLinux_x86_64::%s "
721               "CopyXSTATEtoYMM() failed for reg num "
722               "%" PRIu32,
723               __FUNCTION__, reg);
724           return error;
725         }
726       }
727     }
728 
729     if (IsCPUFeatureAvailable(RegSet::mpx)) {
730       for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
731            ++reg) {
732         if (!CopyXSTATEtoMPX(reg)) {
733           error.SetErrorStringWithFormat(
734               "NativeRegisterContextLinux_x86_64::%s "
735               "CopyXSTATEtoMPX() failed for reg num "
736               "%" PRIu32,
737               __FUNCTION__, reg);
738           return error;
739         }
740       }
741     }
742     // Copy the extended register state including the assembled ymm registers.
743     ::memcpy(dst, m_xstate.get(), sizeof(FPR));
744   } else {
745     assert(false && "how do we save the floating point registers?");
746     error.SetErrorString("unsure how to save the floating point registers");
747   }
748   /** The following code is specific to Linux x86 based architectures,
749    *  where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
750    *  -1 to solve the bug 23659, such a setting prevents the automatic
751    *  decrement of the instruction pointer which was causing the SIGILL
752    *  exception.
753    * **/
754 
755   RegisterValue value((uint64_t)-1);
756   const RegisterInfo *reg_info =
757       GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
758   if (reg_info == nullptr)
759     reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
760 
761   if (reg_info != nullptr)
762     return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
763 
764   return error;
765 }
766 
767 Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
768     const lldb::DataBufferSP &data_sp) {
769   Status error;
770 
771   if (!data_sp) {
772     error.SetErrorStringWithFormat(
773         "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
774         __FUNCTION__);
775     return error;
776   }
777 
778   if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
779     error.SetErrorStringWithFormatv(
780         "data_sp contained mismatched data size, expected {0}, actual {1}",
781         REG_CONTEXT_SIZE, data_sp->GetByteSize());
782     return error;
783   }
784 
785   uint8_t *src = data_sp->GetBytes();
786   if (src == nullptr) {
787     error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
788                                    "DataBuffer::GetBytes() returned a null "
789                                    "pointer",
790                                    __FUNCTION__);
791     return error;
792   }
793   ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
794 
795   error = WriteGPR();
796   if (error.Fail())
797     return error;
798 
799   src += GetRegisterInfoInterface().GetGPRSize();
800   if (m_xstate_type == XStateType::FXSAVE)
801     ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));
802   else if (m_xstate_type == XStateType::XSAVE)
803     ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));
804 
805   error = WriteFPR();
806   if (error.Fail())
807     return error;
808 
809   if (m_xstate_type == XStateType::XSAVE) {
810     lldb::ByteOrder byte_order = GetByteOrder();
811 
812     if (IsCPUFeatureAvailable(RegSet::avx)) {
813       // Parse the YMM register content from the register halves.
814       for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
815            ++reg) {
816         if (!CopyYMMtoXSTATE(reg, byte_order)) {
817           error.SetErrorStringWithFormat(
818               "NativeRegisterContextLinux_x86_64::%s "
819               "CopyYMMtoXSTATE() failed for reg num "
820               "%" PRIu32,
821               __FUNCTION__, reg);
822           return error;
823         }
824       }
825     }
826 
827     if (IsCPUFeatureAvailable(RegSet::mpx)) {
828       for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
829            ++reg) {
830         if (!CopyMPXtoXSTATE(reg)) {
831           error.SetErrorStringWithFormat(
832               "NativeRegisterContextLinux_x86_64::%s "
833               "CopyMPXtoXSTATE() failed for reg num "
834               "%" PRIu32,
835               __FUNCTION__, reg);
836           return error;
837         }
838       }
839     }
840   }
841 
842   return error;
843 }
844 
845 bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
846     RegSet feature_code) const {
847   if (m_xstate_type == XStateType::Invalid) {
848     if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())
849       return false;
850   }
851   switch (feature_code) {
852   case RegSet::gpr:
853   case RegSet::fpu:
854     return true;
855   case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
856                     // reading in the XCR0 area of XSAVE.
857     if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
858       return true;
859      break;
860   case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
861                     // reading in the XCR0 area of XSAVE.
862     if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
863       return true;
864     break;
865   }
866   return false;
867 }
868 
869 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
870     uint32_t set_index) const {
871   uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
872 
873   switch (static_cast<RegSet>(set_index)) {
874   case RegSet::gpr:
875   case RegSet::fpu:
876     return (set_index < num_sets);
877   case RegSet::avx:
878     return IsCPUFeatureAvailable(RegSet::avx);
879   case RegSet::mpx:
880     return IsCPUFeatureAvailable(RegSet::mpx);
881   }
882   return false;
883 }
884 
885 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
886   // GPRs come first.
887   return reg_index <= m_reg_info.last_gpr;
888 }
889 
890 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
891   return (m_reg_info.first_fpr <= reg_index &&
892           reg_index <= m_reg_info.last_fpr);
893 }
894 
895 bool NativeRegisterContextLinux_x86_64::IsDR(uint32_t reg_index) const {
896   return (m_reg_info.first_dr <= reg_index &&
897           reg_index <= m_reg_info.last_dr);
898 }
899 
900 Status NativeRegisterContextLinux_x86_64::WriteFPR() {
901   switch (m_xstate_type) {
902   case XStateType::FXSAVE:
903     return WriteRegisterSet(
904         &m_iovec, sizeof(m_xstate->fxsave),
905         fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
906   case XStateType::XSAVE:
907     return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
908   default:
909     return Status("Unrecognized FPR type.");
910   }
911 }
912 
913 bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
914   if (!IsCPUFeatureAvailable(RegSet::avx))
915     return false;
916   return (m_reg_info.first_ymm <= reg_index &&
917           reg_index <= m_reg_info.last_ymm);
918 }
919 
920 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
921     uint32_t reg_index, lldb::ByteOrder byte_order) {
922   if (!IsAVX(reg_index))
923     return false;
924 
925   if (byte_order == lldb::eByteOrderLittle) {
926     uint32_t reg_no = reg_index - m_reg_info.first_ymm;
927     m_ymm_set.ymm[reg_no] = XStateToYMM(
928         m_xstate->fxsave.xmm[reg_no].bytes,
929         m_xstate->xsave.ymmh[reg_no].bytes);
930     return true;
931   }
932 
933   return false; // unsupported or invalid byte order
934 }
935 
936 bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
937     uint32_t reg, lldb::ByteOrder byte_order) {
938   if (!IsAVX(reg))
939     return false;
940 
941   if (byte_order == lldb::eByteOrderLittle) {
942     uint32_t reg_no = reg - m_reg_info.first_ymm;
943     YMMToXState(m_ymm_set.ymm[reg_no],
944         m_xstate->fxsave.xmm[reg_no].bytes,
945         m_xstate->xsave.ymmh[reg_no].bytes);
946     return true;
947   }
948 
949   return false; // unsupported or invalid byte order
950 }
951 
952 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
953   switch (m_xstate_type) {
954   case XStateType::FXSAVE:
955     return &m_xstate->fxsave;
956   case XStateType::XSAVE:
957     return &m_iovec;
958   default:
959     return nullptr;
960   }
961 }
962 
963 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
964   switch (m_xstate_type) {
965   case XStateType::FXSAVE:
966     return sizeof(m_xstate->fxsave);
967   case XStateType::XSAVE:
968     return sizeof(m_iovec);
969   default:
970     return 0;
971   }
972 }
973 
974 Status NativeRegisterContextLinux_x86_64::ReadFPR() {
975   Status error;
976 
977   // Probe XSAVE and if it is not supported fall back to FXSAVE.
978   if (m_xstate_type != XStateType::FXSAVE) {
979     error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
980     if (!error.Fail()) {
981       m_xstate_type = XStateType::XSAVE;
982       return error;
983     }
984   }
985   error = ReadRegisterSet(
986       &m_iovec, sizeof(m_xstate->xsave),
987       fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
988   if (!error.Fail()) {
989     m_xstate_type = XStateType::FXSAVE;
990     return error;
991   }
992   return Status("Unrecognized FPR type.");
993 }
994 
995 bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {
996   if (!IsCPUFeatureAvailable(RegSet::mpx))
997     return false;
998   return (m_reg_info.first_mpxr <= reg_index &&
999           reg_index <= m_reg_info.last_mpxc);
1000 }
1001 
1002 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
1003   if (!IsMPX(reg))
1004     return false;
1005 
1006   if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1007     ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
1008              m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1009              sizeof(MPXReg));
1010   } else {
1011     ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
1012              m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1013              sizeof(MPXCsr));
1014   }
1015   return true;
1016 }
1017 
1018 bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
1019   if (!IsMPX(reg))
1020     return false;
1021 
1022   if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1023     ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1024              m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
1025   } else {
1026     ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1027              m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
1028   }
1029   return true;
1030 }
1031 
1032 uint32_t
1033 NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
1034   // If register is MPX, remove extra factor from gdb offset
1035   return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1036          (IsMPX(reg_index) ? 128 : 0);
1037 }
1038 
1039 llvm::Optional<NativeRegisterContextLinux::SyscallData>
1040 NativeRegisterContextLinux_x86_64::GetSyscallData() {
1041   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1042   case llvm::Triple::x86: {
1043     static const uint8_t Int80[] = {0xcd, 0x80};
1044     static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386,
1045                                     lldb_edx_i386, lldb_esi_i386, lldb_edi_i386,
1046                                     lldb_ebp_i386};
1047     return SyscallData{Int80, Args, lldb_eax_i386};
1048   }
1049   case llvm::Triple::x86_64: {
1050     static const uint8_t Syscall[] = {0x0f, 0x05};
1051     static const uint32_t Args[] = {
1052         lldb_rax_x86_64, lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rdx_x86_64,
1053         lldb_r10_x86_64, lldb_r8_x86_64,  lldb_r9_x86_64};
1054     return SyscallData{Syscall, Args, lldb_rax_x86_64};
1055   }
1056   default:
1057     llvm_unreachable("Unhandled architecture!");
1058   }
1059 }
1060 
1061 llvm::Optional<NativeRegisterContextLinux::MmapData>
1062 NativeRegisterContextLinux_x86_64::GetMmapData() {
1063   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1064   case llvm::Triple::x86:
1065     return MmapData{192, 91};
1066   case llvm::Triple::x86_64:
1067     return MmapData{9, 11};
1068   default:
1069     llvm_unreachable("Unhandled architecture!");
1070   }
1071 }
1072 
1073 #endif // defined(__i386__) || defined(__x86_64__)
1074