1 //===-- NativeRegisterContextLinux_x86_64.cpp -----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #if defined(__i386__) || defined(__x86_64__)
10
11 #include "NativeRegisterContextLinux_x86_64.h"
12
13 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Utility/DataBufferHeap.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/RegisterValue.h"
17 #include "lldb/Utility/Status.h"
18
19 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
20 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
21 #include <cpuid.h>
22 #include <linux/elf.h>
23
24 // Newer toolchains define __get_cpuid_count in cpuid.h, but some
25 // older-but-still-supported ones (e.g. gcc 5.4.0) don't, so we
26 // define it locally here, following the definition in clang/lib/Headers.
get_cpuid_count(unsigned int __leaf,unsigned int __subleaf,unsigned int * __eax,unsigned int * __ebx,unsigned int * __ecx,unsigned int * __edx)27 static inline int get_cpuid_count(unsigned int __leaf,
28 unsigned int __subleaf,
29 unsigned int *__eax, unsigned int *__ebx,
30 unsigned int *__ecx, unsigned int *__edx)
31 {
32 unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, nullptr);
33
34 if (__max_leaf == 0 || __max_leaf < __leaf)
35 return 0;
36
37 __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
38 return 1;
39 }
40
41 using namespace lldb_private;
42 using namespace lldb_private::process_linux;
43
44 // 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,NativeThreadProtocol & native_thread)252 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
253 const ArchSpec &target_arch, NativeThreadProtocol &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 m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),
296 m_reg_info(), m_gpr_x86_64() {
297 // Set up data about ranges of valid registers.
298 switch (target_arch.GetMachine()) {
299 case llvm::Triple::x86:
300 m_reg_info.num_registers = k_num_registers_i386;
301 m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
302 m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
303 m_reg_info.num_avx_registers = k_num_avx_registers_i386;
304 m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
305 m_reg_info.last_gpr = k_last_gpr_i386;
306 m_reg_info.first_fpr = k_first_fpr_i386;
307 m_reg_info.last_fpr = k_last_fpr_i386;
308 m_reg_info.first_st = lldb_st0_i386;
309 m_reg_info.last_st = lldb_st7_i386;
310 m_reg_info.first_mm = lldb_mm0_i386;
311 m_reg_info.last_mm = lldb_mm7_i386;
312 m_reg_info.first_xmm = lldb_xmm0_i386;
313 m_reg_info.last_xmm = lldb_xmm7_i386;
314 m_reg_info.first_ymm = lldb_ymm0_i386;
315 m_reg_info.last_ymm = lldb_ymm7_i386;
316 m_reg_info.first_mpxr = lldb_bnd0_i386;
317 m_reg_info.last_mpxr = lldb_bnd3_i386;
318 m_reg_info.first_mpxc = lldb_bndcfgu_i386;
319 m_reg_info.last_mpxc = lldb_bndstatus_i386;
320 m_reg_info.first_dr = lldb_dr0_i386;
321 m_reg_info.last_dr = lldb_dr7_i386;
322 m_reg_info.gpr_flags = lldb_eflags_i386;
323 break;
324 case llvm::Triple::x86_64:
325 m_reg_info.num_registers = k_num_registers_x86_64;
326 m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
327 m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
328 m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
329 m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64;
330 m_reg_info.last_gpr = k_last_gpr_x86_64;
331 m_reg_info.first_fpr = k_first_fpr_x86_64;
332 m_reg_info.last_fpr = k_last_fpr_x86_64;
333 m_reg_info.first_st = lldb_st0_x86_64;
334 m_reg_info.last_st = lldb_st7_x86_64;
335 m_reg_info.first_mm = lldb_mm0_x86_64;
336 m_reg_info.last_mm = lldb_mm7_x86_64;
337 m_reg_info.first_xmm = lldb_xmm0_x86_64;
338 m_reg_info.last_xmm = lldb_xmm15_x86_64;
339 m_reg_info.first_ymm = lldb_ymm0_x86_64;
340 m_reg_info.last_ymm = lldb_ymm15_x86_64;
341 m_reg_info.first_mpxr = lldb_bnd0_x86_64;
342 m_reg_info.last_mpxr = lldb_bnd3_x86_64;
343 m_reg_info.first_mpxc = lldb_bndcfgu_x86_64;
344 m_reg_info.last_mpxc = lldb_bndstatus_x86_64;
345 m_reg_info.first_dr = lldb_dr0_x86_64;
346 m_reg_info.last_dr = lldb_dr7_x86_64;
347 m_reg_info.gpr_flags = lldb_rflags_x86_64;
348 break;
349 default:
350 assert(false && "Unhandled target architecture.");
351 break;
352 }
353
354 std::size_t xstate_size = GetXSTATESize();
355 m_xstate.reset(static_cast<FPR *>(std::malloc(xstate_size)));
356 m_iovec.iov_base = m_xstate.get();
357 m_iovec.iov_len = xstate_size;
358
359 // Clear out the FPR state.
360 ::memset(m_xstate.get(), 0, xstate_size);
361
362 // Store byte offset of fctrl (i.e. first register of FPR)
363 const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
364 m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
365 }
366
367 // CONSIDER after local and llgs debugging are merged, register set support can
368 // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
GetRegisterSetCount() const369 uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
370 uint32_t sets = 0;
371 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
372 if (IsRegisterSetAvailable(set_index))
373 ++sets;
374 }
375
376 return sets;
377 }
378
GetUserRegisterCount() const379 uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {
380 uint32_t count = 0;
381 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
382 const RegisterSet *set = GetRegisterSet(set_index);
383 if (set)
384 count += set->num_registers;
385 }
386 return count;
387 }
388
389 const RegisterSet *
GetRegisterSet(uint32_t set_index) const390 NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {
391 if (!IsRegisterSetAvailable(set_index))
392 return nullptr;
393
394 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
395 case llvm::Triple::x86:
396 return &g_reg_sets_i386[set_index];
397 case llvm::Triple::x86_64:
398 return &g_reg_sets_x86_64[set_index];
399 default:
400 assert(false && "Unhandled target architecture.");
401 return nullptr;
402 }
403
404 return nullptr;
405 }
406
407 Status
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)408 NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
409 RegisterValue ®_value) {
410 Status error;
411
412 if (!reg_info) {
413 error.SetErrorString("reg_info NULL");
414 return error;
415 }
416
417 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
418 if (reg == LLDB_INVALID_REGNUM) {
419 // This is likely an internal register for lldb use only and should not be
420 // directly queried.
421 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
422 "register, cannot read directly",
423 reg_info->name);
424 return error;
425 }
426
427 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
428 error = ReadFPR();
429 if (error.Fail())
430 return error;
431 } else {
432 uint32_t full_reg = reg;
433 bool is_subreg = reg_info->invalidate_regs &&
434 (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
435
436 if (is_subreg) {
437 // Read the full aligned 64-bit register.
438 full_reg = reg_info->invalidate_regs[0];
439 }
440
441 error = ReadRegisterRaw(full_reg, reg_value);
442
443 if (error.Success()) {
444 // If our read was not aligned (for ah,bh,ch,dh), shift our returned
445 // value one byte to the right.
446 if (is_subreg && (reg_info->byte_offset & 0x1))
447 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
448
449 // If our return byte size was greater than the return value reg size,
450 // then use the type specified by reg_info rather than the uint64_t
451 // default
452 if (reg_value.GetByteSize() > reg_info->byte_size)
453 reg_value.SetType(reg_info);
454 }
455 return error;
456 }
457
458 if (reg_info->encoding == lldb::eEncodingVector) {
459 lldb::ByteOrder byte_order = GetByteOrder();
460
461 if (byte_order != lldb::eByteOrderInvalid) {
462 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
463 reg_value.SetBytes(
464 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
465 reg_info->byte_size, byte_order);
466 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
467 reg_value.SetBytes(
468 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
469 reg_info->byte_size, byte_order);
470 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
471 reg_value.SetBytes(
472 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
473 reg_info->byte_size, byte_order);
474 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
475 // Concatenate ymm using the register halves in xmm.bytes and
476 // ymmh.bytes
477 if (CopyXSTATEtoYMM(reg, byte_order))
478 reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
479 reg_info->byte_size, byte_order);
480 else {
481 error.SetErrorString("failed to copy ymm register value");
482 return error;
483 }
484 }
485 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
486 if (CopyXSTATEtoMPX(reg))
487 reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
488 reg_info->byte_size, byte_order);
489 else {
490 error.SetErrorString("failed to copy mpx register value");
491 return error;
492 }
493 }
494 if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
495 if (CopyXSTATEtoMPX(reg))
496 reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
497 reg_info->byte_size, byte_order);
498 else {
499 error.SetErrorString("failed to copy mpx register value");
500 return error;
501 }
502 }
503
504 if (reg_value.GetType() != RegisterValue::eTypeBytes)
505 error.SetErrorString(
506 "write failed - type was expected to be RegisterValue::eTypeBytes");
507
508 return error;
509 }
510
511 error.SetErrorString("byte order is invalid");
512 return error;
513 }
514
515 // Get pointer to m_xstate->fxsave variable and set the data from it.
516
517 // Byte offsets of all registers are calculated wrt 'UserArea' structure.
518 // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
519 // and stores them in 'm_fpr' (of type FPR structure). To extract values of
520 // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
521 // structure.
522
523 // Since, FPR structure is also one of the member of UserArea structure.
524 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
525 // byte_offset(fctrl wrt UserArea)
526 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR));
527 uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
528 m_fctrl_offset_in_userarea;
529
530 if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) {
531 reg_value.SetUInt16(AbridgedToFullTagWord(
532 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
533 return error;
534 }
535
536 switch (reg_info->byte_size) {
537 case 1:
538 reg_value.SetUInt8(*(uint8_t *)src);
539 break;
540 case 2:
541 reg_value.SetUInt16(*(uint16_t *)src);
542 break;
543 case 4:
544 reg_value.SetUInt32(*(uint32_t *)src);
545 break;
546 case 8:
547 reg_value.SetUInt64(*(uint64_t *)src);
548 break;
549 default:
550 assert(false && "Unhandled data size.");
551 error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
552 reg_info->byte_size);
553 break;
554 }
555
556 return error;
557 }
558
UpdateXSTATEforWrite(uint32_t reg_index)559 void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
560 uint32_t reg_index) {
561 XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;
562 if (IsFPR(reg_index)) {
563 // IsFPR considers both %st and %xmm registers as floating point, but these
564 // map to two features. Set both flags, just in case.
565 xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
566 } else if (IsAVX(reg_index)) {
567 // Lower bytes of some %ymm registers are shared with %xmm registers.
568 xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
569 } else if (IsMPX(reg_index)) {
570 // MPX registers map to two XSAVE features.
571 xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
572 }
573 }
574
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)575 Status NativeRegisterContextLinux_x86_64::WriteRegister(
576 const RegisterInfo *reg_info, const RegisterValue ®_value) {
577 assert(reg_info && "reg_info is null");
578
579 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
580 if (reg_index == LLDB_INVALID_REGNUM)
581 return Status("no lldb regnum for %s", reg_info && reg_info->name
582 ? reg_info->name
583 : "<unknown register>");
584
585 UpdateXSTATEforWrite(reg_index);
586
587 if (IsGPR(reg_index) || IsDR(reg_index))
588 return WriteRegisterRaw(reg_index, reg_value);
589
590 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
591 if (reg_info->encoding == lldb::eEncodingVector) {
592 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
593 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
594 reg_value.GetBytes(), reg_value.GetByteSize());
595
596 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
597 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
598 reg_value.GetBytes(), reg_value.GetByteSize());
599
600 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
601 ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
602 reg_value.GetBytes(), reg_value.GetByteSize());
603
604 if (reg_index >= m_reg_info.first_ymm &&
605 reg_index <= m_reg_info.last_ymm) {
606 // Store ymm register content, and split into the register halves in
607 // xmm.bytes and ymmh.bytes
608 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
609 reg_value.GetBytes(), reg_value.GetByteSize());
610 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
611 return Status("CopyYMMtoXSTATE() failed");
612 }
613
614 if (reg_index >= m_reg_info.first_mpxr &&
615 reg_index <= m_reg_info.last_mpxr) {
616 ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
617 reg_value.GetBytes(), reg_value.GetByteSize());
618 if (!CopyMPXtoXSTATE(reg_index))
619 return Status("CopyMPXtoXSTATE() failed");
620 }
621
622 if (reg_index >= m_reg_info.first_mpxc &&
623 reg_index <= m_reg_info.last_mpxc) {
624 ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
625 reg_value.GetBytes(), reg_value.GetByteSize());
626 if (!CopyMPXtoXSTATE(reg_index))
627 return Status("CopyMPXtoXSTATE() failed");
628 }
629 } else {
630 // Get pointer to m_xstate->fxsave variable and set the data to it.
631
632 // Byte offsets of all registers are calculated wrt 'UserArea' structure.
633 // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
634 // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
635 // registers should be written in m_fpr at byte offsets calculated wrt
636 // FPR structure.
637
638 // Since, FPR structure is also one of the member of UserArea structure.
639 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
640 // byte_offset(fctrl wrt UserArea)
641 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
642 sizeof(FPR));
643 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
644 m_fctrl_offset_in_userarea;
645
646 if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag))
647 m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
648 else {
649 switch (reg_info->byte_size) {
650 case 1:
651 *(uint8_t *)dst = reg_value.GetAsUInt8();
652 break;
653 case 2:
654 *(uint16_t *)dst = reg_value.GetAsUInt16();
655 break;
656 case 4:
657 *(uint32_t *)dst = reg_value.GetAsUInt32();
658 break;
659 case 8:
660 *(uint64_t *)dst = reg_value.GetAsUInt64();
661 break;
662 default:
663 assert(false && "Unhandled data size.");
664 return Status("unhandled register data size %" PRIu32,
665 reg_info->byte_size);
666 }
667 }
668 }
669
670 Status error = WriteFPR();
671 if (error.Fail())
672 return error;
673
674 if (IsAVX(reg_index)) {
675 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
676 return Status("CopyYMMtoXSTATE() failed");
677 }
678
679 if (IsMPX(reg_index)) {
680 if (!CopyMPXtoXSTATE(reg_index))
681 return Status("CopyMPXtoXSTATE() failed");
682 }
683 return Status();
684 }
685 return Status("failed - register wasn't recognized to be a GPR or an FPR, "
686 "write strategy unknown");
687 }
688
ReadAllRegisterValues(lldb::DataBufferSP & data_sp)689 Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
690 lldb::DataBufferSP &data_sp) {
691 Status error;
692
693 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
694 error = ReadGPR();
695 if (error.Fail())
696 return error;
697
698 error = ReadFPR();
699 if (error.Fail())
700 return error;
701
702 uint8_t *dst = data_sp->GetBytes();
703 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
704 dst += GetRegisterInfoInterface().GetGPRSize();
705 if (m_xstate_type == XStateType::FXSAVE)
706 ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));
707 else if (m_xstate_type == XStateType::XSAVE) {
708 lldb::ByteOrder byte_order = GetByteOrder();
709
710 if (IsCPUFeatureAvailable(RegSet::avx)) {
711 // Assemble the YMM register content from the register halves.
712 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
713 ++reg) {
714 if (!CopyXSTATEtoYMM(reg, byte_order)) {
715 error.SetErrorStringWithFormat(
716 "NativeRegisterContextLinux_x86_64::%s "
717 "CopyXSTATEtoYMM() failed for reg num "
718 "%" PRIu32,
719 __FUNCTION__, reg);
720 return error;
721 }
722 }
723 }
724
725 if (IsCPUFeatureAvailable(RegSet::mpx)) {
726 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
727 ++reg) {
728 if (!CopyXSTATEtoMPX(reg)) {
729 error.SetErrorStringWithFormat(
730 "NativeRegisterContextLinux_x86_64::%s "
731 "CopyXSTATEtoMPX() failed for reg num "
732 "%" PRIu32,
733 __FUNCTION__, reg);
734 return error;
735 }
736 }
737 }
738 // Copy the extended register state including the assembled ymm registers.
739 ::memcpy(dst, m_xstate.get(), sizeof(FPR));
740 } else {
741 assert(false && "how do we save the floating point registers?");
742 error.SetErrorString("unsure how to save the floating point registers");
743 }
744 /** The following code is specific to Linux x86 based architectures,
745 * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
746 * -1 to solve the bug 23659, such a setting prevents the automatic
747 * decrement of the instruction pointer which was causing the SIGILL
748 * exception.
749 * **/
750
751 RegisterValue value((uint64_t)-1);
752 const RegisterInfo *reg_info =
753 GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
754 if (reg_info == nullptr)
755 reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
756
757 if (reg_info != nullptr)
758 return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
759
760 return error;
761 }
762
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)763 Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
764 const lldb::DataBufferSP &data_sp) {
765 Status error;
766
767 if (!data_sp) {
768 error.SetErrorStringWithFormat(
769 "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
770 __FUNCTION__);
771 return error;
772 }
773
774 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
775 error.SetErrorStringWithFormatv(
776 "data_sp contained mismatched data size, expected {0}, actual {1}",
777 REG_CONTEXT_SIZE, data_sp->GetByteSize());
778 return error;
779 }
780
781 uint8_t *src = data_sp->GetBytes();
782 if (src == nullptr) {
783 error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
784 "DataBuffer::GetBytes() returned a null "
785 "pointer",
786 __FUNCTION__);
787 return error;
788 }
789 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
790
791 error = WriteGPR();
792 if (error.Fail())
793 return error;
794
795 src += GetRegisterInfoInterface().GetGPRSize();
796 if (m_xstate_type == XStateType::FXSAVE)
797 ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));
798 else if (m_xstate_type == XStateType::XSAVE)
799 ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));
800
801 error = WriteFPR();
802 if (error.Fail())
803 return error;
804
805 if (m_xstate_type == XStateType::XSAVE) {
806 lldb::ByteOrder byte_order = GetByteOrder();
807
808 if (IsCPUFeatureAvailable(RegSet::avx)) {
809 // Parse the YMM register content from the register halves.
810 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
811 ++reg) {
812 if (!CopyYMMtoXSTATE(reg, byte_order)) {
813 error.SetErrorStringWithFormat(
814 "NativeRegisterContextLinux_x86_64::%s "
815 "CopyYMMtoXSTATE() failed for reg num "
816 "%" PRIu32,
817 __FUNCTION__, reg);
818 return error;
819 }
820 }
821 }
822
823 if (IsCPUFeatureAvailable(RegSet::mpx)) {
824 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
825 ++reg) {
826 if (!CopyMPXtoXSTATE(reg)) {
827 error.SetErrorStringWithFormat(
828 "NativeRegisterContextLinux_x86_64::%s "
829 "CopyMPXtoXSTATE() failed for reg num "
830 "%" PRIu32,
831 __FUNCTION__, reg);
832 return error;
833 }
834 }
835 }
836 }
837
838 return error;
839 }
840
IsCPUFeatureAvailable(RegSet feature_code) const841 bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
842 RegSet feature_code) const {
843 if (m_xstate_type == XStateType::Invalid) {
844 if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())
845 return false;
846 }
847 switch (feature_code) {
848 case RegSet::gpr:
849 case RegSet::fpu:
850 return true;
851 case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
852 // reading in the XCR0 area of XSAVE.
853 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
854 return true;
855 break;
856 case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
857 // reading in the XCR0 area of XSAVE.
858 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
859 return true;
860 break;
861 }
862 return false;
863 }
864
IsRegisterSetAvailable(uint32_t set_index) const865 bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
866 uint32_t set_index) const {
867 uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
868
869 switch (static_cast<RegSet>(set_index)) {
870 case RegSet::gpr:
871 case RegSet::fpu:
872 return (set_index < num_sets);
873 case RegSet::avx:
874 return IsCPUFeatureAvailable(RegSet::avx);
875 case RegSet::mpx:
876 return IsCPUFeatureAvailable(RegSet::mpx);
877 }
878 return false;
879 }
880
IsGPR(uint32_t reg_index) const881 bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
882 // GPRs come first.
883 return reg_index <= m_reg_info.last_gpr;
884 }
885
IsFPR(uint32_t reg_index) const886 bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
887 return (m_reg_info.first_fpr <= reg_index &&
888 reg_index <= m_reg_info.last_fpr);
889 }
890
IsDR(uint32_t reg_index) const891 bool NativeRegisterContextLinux_x86_64::IsDR(uint32_t reg_index) const {
892 return (m_reg_info.first_dr <= reg_index &&
893 reg_index <= m_reg_info.last_dr);
894 }
895
WriteFPR()896 Status NativeRegisterContextLinux_x86_64::WriteFPR() {
897 switch (m_xstate_type) {
898 case XStateType::FXSAVE:
899 return WriteRegisterSet(
900 &m_iovec, sizeof(m_xstate->fxsave),
901 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
902 case XStateType::XSAVE:
903 return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
904 default:
905 return Status("Unrecognized FPR type.");
906 }
907 }
908
IsAVX(uint32_t reg_index) const909 bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
910 if (!IsCPUFeatureAvailable(RegSet::avx))
911 return false;
912 return (m_reg_info.first_ymm <= reg_index &&
913 reg_index <= m_reg_info.last_ymm);
914 }
915
CopyXSTATEtoYMM(uint32_t reg_index,lldb::ByteOrder byte_order)916 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
917 uint32_t reg_index, lldb::ByteOrder byte_order) {
918 if (!IsAVX(reg_index))
919 return false;
920
921 if (byte_order == lldb::eByteOrderLittle) {
922 uint32_t reg_no = reg_index - m_reg_info.first_ymm;
923 m_ymm_set.ymm[reg_no] = XStateToYMM(
924 m_xstate->fxsave.xmm[reg_no].bytes,
925 m_xstate->xsave.ymmh[reg_no].bytes);
926 return true;
927 }
928
929 return false; // unsupported or invalid byte order
930 }
931
CopyYMMtoXSTATE(uint32_t reg,lldb::ByteOrder byte_order)932 bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
933 uint32_t reg, lldb::ByteOrder byte_order) {
934 if (!IsAVX(reg))
935 return false;
936
937 if (byte_order == lldb::eByteOrderLittle) {
938 uint32_t reg_no = reg - m_reg_info.first_ymm;
939 YMMToXState(m_ymm_set.ymm[reg_no],
940 m_xstate->fxsave.xmm[reg_no].bytes,
941 m_xstate->xsave.ymmh[reg_no].bytes);
942 return true;
943 }
944
945 return false; // unsupported or invalid byte order
946 }
947
GetFPRBuffer()948 void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
949 switch (m_xstate_type) {
950 case XStateType::FXSAVE:
951 return &m_xstate->fxsave;
952 case XStateType::XSAVE:
953 return &m_iovec;
954 default:
955 return nullptr;
956 }
957 }
958
GetFPRSize()959 size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
960 switch (m_xstate_type) {
961 case XStateType::FXSAVE:
962 return sizeof(m_xstate->fxsave);
963 case XStateType::XSAVE:
964 return sizeof(m_iovec);
965 default:
966 return 0;
967 }
968 }
969
ReadFPR()970 Status NativeRegisterContextLinux_x86_64::ReadFPR() {
971 Status error;
972
973 // Probe XSAVE and if it is not supported fall back to FXSAVE.
974 if (m_xstate_type != XStateType::FXSAVE) {
975 error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
976 if (!error.Fail()) {
977 m_xstate_type = XStateType::XSAVE;
978 return error;
979 }
980 }
981 error = ReadRegisterSet(
982 &m_iovec, sizeof(m_xstate->xsave),
983 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
984 if (!error.Fail()) {
985 m_xstate_type = XStateType::FXSAVE;
986 return error;
987 }
988 return Status("Unrecognized FPR type.");
989 }
990
IsMPX(uint32_t reg_index) const991 bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {
992 if (!IsCPUFeatureAvailable(RegSet::mpx))
993 return false;
994 return (m_reg_info.first_mpxr <= reg_index &&
995 reg_index <= m_reg_info.last_mpxc);
996 }
997
CopyXSTATEtoMPX(uint32_t reg)998 bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
999 if (!IsMPX(reg))
1000 return false;
1001
1002 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1003 ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
1004 m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1005 sizeof(MPXReg));
1006 } else {
1007 ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
1008 m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1009 sizeof(MPXCsr));
1010 }
1011 return true;
1012 }
1013
CopyMPXtoXSTATE(uint32_t reg)1014 bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
1015 if (!IsMPX(reg))
1016 return false;
1017
1018 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1019 ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1020 m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
1021 } else {
1022 ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1023 m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
1024 }
1025 return true;
1026 }
1027
1028 uint32_t
GetPtraceOffset(uint32_t reg_index)1029 NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
1030 // If register is MPX, remove extra factor from gdb offset
1031 return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1032 (IsMPX(reg_index) ? 128 : 0);
1033 }
1034
1035 llvm::Optional<NativeRegisterContextLinux::SyscallData>
GetSyscallData()1036 NativeRegisterContextLinux_x86_64::GetSyscallData() {
1037 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1038 case llvm::Triple::x86: {
1039 static const uint8_t Int80[] = {0xcd, 0x80};
1040 static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386,
1041 lldb_edx_i386, lldb_esi_i386, lldb_edi_i386,
1042 lldb_ebp_i386};
1043 return SyscallData{Int80, Args, lldb_eax_i386};
1044 }
1045 case llvm::Triple::x86_64: {
1046 static const uint8_t Syscall[] = {0x0f, 0x05};
1047 static const uint32_t Args[] = {
1048 lldb_rax_x86_64, lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rdx_x86_64,
1049 lldb_r10_x86_64, lldb_r8_x86_64, lldb_r9_x86_64};
1050 return SyscallData{Syscall, Args, lldb_rax_x86_64};
1051 }
1052 default:
1053 llvm_unreachable("Unhandled architecture!");
1054 }
1055 }
1056
1057 llvm::Optional<NativeRegisterContextLinux::MmapData>
GetMmapData()1058 NativeRegisterContextLinux_x86_64::GetMmapData() {
1059 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1060 case llvm::Triple::x86:
1061 return MmapData{192, 91};
1062 case llvm::Triple::x86_64:
1063 return MmapData{9, 11};
1064 default:
1065 llvm_unreachable("Unhandled architecture!");
1066 }
1067 }
1068
1069 #endif // defined(__i386__) || defined(__x86_64__)
1070