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