LLDB mainline
NativeRegisterContextLinux_x86.cpp
Go to the documentation of this file.
1//===-- NativeRegisterContextLinux_x86.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 ==
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 ==
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 ==
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 ==
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[] = {
112 x86_64_with_base::lldb_r8d, // Low 32 bits or r8
113 x86_64_with_base::lldb_r9d, // Low 32 bits or r9
114 x86_64_with_base::lldb_r10d, // Low 32 bits or r10
115 x86_64_with_base::lldb_r11d, // Low 32 bits or r11
116 x86_64_with_base::lldb_r12d, // Low 32 bits or r12
117 x86_64_with_base::lldb_r13d, // Low 32 bits or r13
118 x86_64_with_base::lldb_r14d, // Low 32 bits or r14
119 x86_64_with_base::lldb_r15d, // Low 32 bits or r15
122 x86_64_with_base::lldb_r8w, // Low 16 bits or r8
123 x86_64_with_base::lldb_r9w, // Low 16 bits or r9
124 x86_64_with_base::lldb_r10w, // Low 16 bits or r10
125 x86_64_with_base::lldb_r11w, // Low 16 bits or r11
126 x86_64_with_base::lldb_r12w, // Low 16 bits or r12
127 x86_64_with_base::lldb_r13w, // Low 16 bits or r13
128 x86_64_with_base::lldb_r14w, // Low 16 bits or r14
129 x86_64_with_base::lldb_r15w, // Low 16 bits or r15
133 x86_64_with_base::lldb_r8l, // Low 8 bits or r8
134 x86_64_with_base::lldb_r9l, // Low 8 bits or r9
135 x86_64_with_base::lldb_r10l, // Low 8 bits or r10
136 x86_64_with_base::lldb_r11l, // Low 8 bits or r11
137 x86_64_with_base::lldb_r12l, // Low 8 bits or r12
138 x86_64_with_base::lldb_r13l, // Low 8 bits or r13
139 x86_64_with_base::lldb_r14l, // Low 8 bits or r14
140 x86_64_with_base::lldb_r15l, // Low 8 bits or r15
141 LLDB_INVALID_REGNUM // register sets need to end with this flag
142};
143static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
144 1 ==
146 "g_gpr_regnums_x86_64 has wrong number of register infos");
147
148// x86 64-bit floating point registers.
149static const uint32_t g_fpu_regnums_x86_64[] = {
165 LLDB_INVALID_REGNUM // register sets need to end with this flag
166};
167static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
168 1 ==
170 "g_fpu_regnums_x86_64 has wrong number of register infos");
171
172// x86 64-bit AVX registers.
173static const uint32_t g_avx_regnums_x86_64[] = {
178 LLDB_INVALID_REGNUM // register sets need to end with this flag
179};
180static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
181 1 ==
183 "g_avx_regnums_x86_64 has wrong number of register infos");
184
185// x86 64-bit MPX registers.
186static const uint32_t g_mpx_regnums_x86_64[] = {
189 LLDB_INVALID_REGNUM // register sets need to end with this flag
190};
191static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
192 1 ==
194 "g_mpx_regnums_x86_64 has wrong number of register infos");
195
196// Number of register sets provided by this context.
197constexpr unsigned k_num_extended_register_sets = 2, k_num_register_sets = 4;
198
199// Register sets for x86 32-bit.
201 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
203 {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
204 g_fpu_regnums_i386},
205 {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
207 { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
208 g_mpx_regnums_i386}};
209
210// Register sets for x86 64-bit.
212 {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers,
214 {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers,
215 g_fpu_regnums_x86_64},
216 {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers,
218 { "Memory Protection Extensions", "mpx", x86_64_with_base::k_num_mpx_registers,
219 g_mpx_regnums_x86_64}};
220
221#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
222
223// Required ptrace defines.
224
225// Support ptrace extensions even when compiled without required kernel support
226#ifndef NT_X86_XSTATE
227#define NT_X86_XSTATE 0x202
228#endif
229#ifndef NT_PRXFPREG
230#define NT_PRXFPREG 0x46e62b7f
231#endif
232
233// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
234// use NT_PRXFPREG.
235static inline unsigned int fxsr_regset(const ArchSpec &arch) {
236 return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
237}
238
239// Required MPX define.
240
241// Support MPX extensions also if compiled with compiler without MPX support.
242#ifndef bit_MPX
243#define bit_MPX 0x4000
244#endif
245
246// XCR0 extended register sets masks.
247#define mask_XSTATE_AVX (1ULL << 2)
248#define mask_XSTATE_BNDREGS (1ULL << 3)
249#define mask_XSTATE_BNDCFG (1ULL << 4)
250#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
251
252std::unique_ptr<NativeRegisterContextLinux>
254 const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
255 return std::unique_ptr<NativeRegisterContextLinux>(
256 new NativeRegisterContextLinux_x86(target_arch, native_thread));
257}
258
259llvm::Expected<ArchSpec>
261 return DetermineArchitectureViaGPR(
263}
264
265// NativeRegisterContextLinux_x86 members.
266
267static std::unique_ptr<RegisterContextLinux_x86>
268CreateRegisterInfoInterface(const ArchSpec &target_arch) {
269 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
270 // 32-bit hosts run with a RegisterContextLinux_i386 context.
271 return std::make_unique<RegisterContextLinux_i386>(target_arch);
272 } else {
273 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
274 "Register setting path assumes this is a 64-bit host");
275 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
276 // x86_64 register context.
277 return std::make_unique<RegisterContextLinux_x86_64>(target_arch);
278 }
279}
280
281// Return the size of the XSTATE area supported on this cpu. It is necessary to
282// allocate the full size of the area even if we do not use/recognise all of it
283// because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if
284// we do not pass it a buffer of sufficient size. The size is always at least
285// sizeof(FPR) so that the allocated buffer can be safely cast to FPR*.
286static std::size_t GetXSTATESize() {
287 unsigned int eax, ebx, ecx, edx;
288 // First check whether the XSTATE are is supported at all.
289 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE))
290 return sizeof(FPR);
291
292 // Then fetch the maximum size of the area.
293 if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx))
294 return sizeof(FPR);
295 return std::max<std::size_t>(ecx, sizeof(FPR));
296}
297
298NativeRegisterContextLinux_x86::NativeRegisterContextLinux_x86(
299 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
301 native_thread, CreateRegisterInfoInterface(target_arch).release()),
302 NativeRegisterContextLinux(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 = x86_64_with_base::k_num_registers;
334 m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers;
335 m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers;
336 m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers;
337 m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers;
338 m_reg_info.last_gpr = x86_64_with_base::k_last_gpr;
339 m_reg_info.first_fpr = x86_64_with_base::k_first_fpr;
340 m_reg_info.last_fpr = x86_64_with_base::k_last_fpr;
341 m_reg_info.first_st = x86_64_with_base::lldb_st0;
342 m_reg_info.last_st = x86_64_with_base::lldb_st7;
343 m_reg_info.first_mm = x86_64_with_base::lldb_mm0;
344 m_reg_info.last_mm = x86_64_with_base::lldb_mm7;
345 m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0;
346 m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15;
347 m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0;
348 m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15;
349 m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0;
350 m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3;
351 m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu;
352 m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus;
353 m_reg_info.first_dr = x86_64_with_base::lldb_dr0;
354 m_reg_info.last_dr = x86_64_with_base::lldb_dr7;
355 m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags;
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::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::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::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::ReadRegister(const RegisterInfo *reg_info,
417 RegisterValue &reg_value) {
419
420 if (!reg_info) {
421 error = Status::FromErrorString("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.
430 "register \"%s\" is an internal-only lldb "
431 "register, cannot read directly",
432 reg_info->name);
433 return error;
434 }
435
436 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
437 error = ReadFPR();
438 if (error.Fail())
439 return error;
440 } else {
441 uint32_t full_reg = reg;
442 bool is_subreg = reg_info->invalidate_regs &&
443 (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
444
445 if (is_subreg) {
446 // Read the full aligned 64-bit register.
447 full_reg = reg_info->invalidate_regs[0];
448 }
449
450 error = ReadRegisterRaw(full_reg, reg_value);
451
452 if (error.Success()) {
453 // If our read was not aligned (for ah,bh,ch,dh), shift our returned
454 // value one byte to the right.
455 if (is_subreg && (reg_info->byte_offset & 0x1))
456 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
457
458 // If our return byte size was greater than the return value reg size,
459 // then use the type specified by reg_info rather than the uint64_t
460 // default
461 if (reg_value.GetByteSize() > reg_info->byte_size)
462 reg_value.SetType(*reg_info);
463 }
464 return error;
465 }
466
467 if (reg_info->encoding == lldb::eEncodingVector) {
468 lldb::ByteOrder byte_order = GetByteOrder();
469
470 if (byte_order != lldb::eByteOrderInvalid) {
471 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
472 reg_value.SetBytes(
473 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
474 reg_info->byte_size, byte_order);
475 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
476 reg_value.SetBytes(
477 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
478 reg_info->byte_size, byte_order);
479 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
480 reg_value.SetBytes(
481 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
482 reg_info->byte_size, byte_order);
483 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
484 // Concatenate ymm using the register halves in xmm.bytes and
485 // ymmh.bytes
486 if (CopyXSTATEtoYMM(reg, byte_order))
487 reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
488 reg_info->byte_size, byte_order);
489 else {
490 error = Status::FromErrorString("failed to copy ymm register value");
491 return error;
492 }
493 }
494 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
495 if (CopyXSTATEtoMPX(reg))
496 reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
497 reg_info->byte_size, byte_order);
498 else {
499 error = Status::FromErrorString("failed to copy mpx register value");
500 return error;
501 }
502 }
503 if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
504 if (CopyXSTATEtoMPX(reg))
505 reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
506 reg_info->byte_size, byte_order);
507 else {
508 error = Status::FromErrorString("failed to copy mpx register value");
509 return error;
510 }
511 }
512
513 if (reg_value.GetType() != RegisterValue::eTypeBytes)
515 "write failed - type was expected to be RegisterValue::eTypeBytes");
516
517 return error;
518 }
519
520 error = Status::FromErrorString("byte order is invalid");
521 return error;
522 }
523
524 // Get pointer to m_xstate->fxsave variable and set the data from it.
525
526 // Byte offsets of all registers are calculated wrt 'UserArea' structure.
527 // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
528 // and stores them in 'm_fpr' (of type FPR structure). To extract values of
529 // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
530 // structure.
531
532 // Since, FPR structure is also one of the member of UserArea structure.
533 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
534 // byte_offset(fctrl wrt UserArea)
535 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR));
536 uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
537 m_fctrl_offset_in_userarea;
538
539 if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) {
541 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
542 return error;
543 }
544
545 switch (reg_info->byte_size) {
546 case 1:
547 reg_value.SetUInt8(*(uint8_t *)src);
548 break;
549 case 2:
550 reg_value.SetUInt16(*(uint16_t *)src);
551 break;
552 case 4:
553 reg_value.SetUInt32(*(uint32_t *)src);
554 break;
555 case 8:
556 reg_value.SetUInt64(*(uint64_t *)src);
557 break;
558 default:
559 assert(false && "Unhandled data size.");
560 error = Status::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,
561 reg_info->byte_size);
562 break;
563 }
564
565 return error;
566}
567
568void NativeRegisterContextLinux_x86::UpdateXSTATEforWrite(
569 uint32_t reg_index) {
570 XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;
571 if (IsFPR(reg_index)) {
572 // IsFPR considers both %st and %xmm registers as floating point, but these
573 // map to two features. Set both flags, just in case.
575 } else if (IsAVX(reg_index)) {
576 // Lower bytes of some %ymm registers are shared with %xmm registers.
578 } else if (IsMPX(reg_index)) {
579 // MPX registers map to two XSAVE features.
581 }
582}
583
584Status NativeRegisterContextLinux_x86::WriteRegister(
585 const RegisterInfo *reg_info, const RegisterValue &reg_value) {
586 assert(reg_info && "reg_info is null");
587
588 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
589 if (reg_index == LLDB_INVALID_REGNUM)
591 "no lldb regnum for %s",
592 reg_info && reg_info->name ? reg_info->name : "<unknown register>");
593
594 UpdateXSTATEforWrite(reg_index);
595
596 if (IsGPR(reg_index) || IsDR(reg_index))
597 return WriteRegisterRaw(reg_index, reg_value);
598
599 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
600 if (reg_info->encoding == lldb::eEncodingVector) {
601 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
602 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
603 reg_value.GetBytes(), reg_value.GetByteSize());
604
605 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
606 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
607 reg_value.GetBytes(), reg_value.GetByteSize());
608
609 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
610 ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
611 reg_value.GetBytes(), reg_value.GetByteSize());
612
613 if (reg_index >= m_reg_info.first_ymm &&
614 reg_index <= m_reg_info.last_ymm) {
615 // Store ymm register content, and split into the register halves in
616 // xmm.bytes and ymmh.bytes
617 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
618 reg_value.GetBytes(), reg_value.GetByteSize());
619 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
620 return Status::FromErrorString("CopyYMMtoXSTATE() failed");
621 }
622
623 if (reg_index >= m_reg_info.first_mpxr &&
624 reg_index <= m_reg_info.last_mpxr) {
625 ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
626 reg_value.GetBytes(), reg_value.GetByteSize());
627 if (!CopyMPXtoXSTATE(reg_index))
628 return Status::FromErrorString("CopyMPXtoXSTATE() failed");
629 }
630
631 if (reg_index >= m_reg_info.first_mpxc &&
632 reg_index <= m_reg_info.last_mpxc) {
633 ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
634 reg_value.GetBytes(), reg_value.GetByteSize());
635 if (!CopyMPXtoXSTATE(reg_index))
636 return Status::FromErrorString("CopyMPXtoXSTATE() failed");
637 }
638 } else {
639 // Get pointer to m_xstate->fxsave variable and set the data to it.
640
641 // Byte offsets of all registers are calculated wrt 'UserArea' structure.
642 // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
643 // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
644 // registers should be written in m_fpr at byte offsets calculated wrt
645 // FPR structure.
646
647 // Since, FPR structure is also one of the member of UserArea structure.
648 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
649 // byte_offset(fctrl wrt UserArea)
650 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
651 sizeof(FPR));
652 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
653 m_fctrl_offset_in_userarea;
654
655 if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag))
656 m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
657 else {
658 switch (reg_info->byte_size) {
659 case 1:
660 *(uint8_t *)dst = reg_value.GetAsUInt8();
661 break;
662 case 2:
663 *(uint16_t *)dst = reg_value.GetAsUInt16();
664 break;
665 case 4:
666 *(uint32_t *)dst = reg_value.GetAsUInt32();
667 break;
668 case 8:
669 *(uint64_t *)dst = reg_value.GetAsUInt64();
670 break;
671 default:
672 assert(false && "Unhandled data size.");
674 "unhandled register data size %" PRIu32, reg_info->byte_size);
675 }
676 }
677 }
678
679 Status error = WriteFPR();
680 if (error.Fail())
681 return error;
682
683 if (IsAVX(reg_index)) {
684 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
685 return Status::FromErrorString("CopyYMMtoXSTATE() failed");
686 }
687
688 if (IsMPX(reg_index)) {
689 if (!CopyMPXtoXSTATE(reg_index))
690 return Status::FromErrorString("CopyMPXtoXSTATE() failed");
691 }
692 return Status();
693 }
695 "failed - register wasn't recognized to be a GPR or an FPR, "
696 "write strategy unknown");
697}
698
699Status NativeRegisterContextLinux_x86::ReadAllRegisterValues(
702
703 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
704 error = ReadGPR();
705 if (error.Fail())
706 return error;
707
708 error = ReadFPR();
709 if (error.Fail())
710 return error;
711
712 uint8_t *dst = data_sp->GetBytes();
713 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
714 dst += GetRegisterInfoInterface().GetGPRSize();
715 if (m_xstate_type == XStateType::FXSAVE)
716 ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));
717 else if (m_xstate_type == XStateType::XSAVE) {
718 lldb::ByteOrder byte_order = GetByteOrder();
719
720 if (IsCPUFeatureAvailable(RegSet::avx)) {
721 // Assemble the YMM register content from the register halves.
722 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
723 ++reg) {
724 if (!CopyXSTATEtoYMM(reg, byte_order)) {
726 "NativeRegisterContextLinux_x86::%s "
727 "CopyXSTATEtoYMM() failed for reg num "
728 "%" PRIu32,
729 __FUNCTION__, reg);
730 return error;
731 }
732 }
733 }
734
735 if (IsCPUFeatureAvailable(RegSet::mpx)) {
736 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
737 ++reg) {
738 if (!CopyXSTATEtoMPX(reg)) {
740 "NativeRegisterContextLinux_x86::%s "
741 "CopyXSTATEtoMPX() failed for reg num "
742 "%" PRIu32,
743 __FUNCTION__, reg);
744 return error;
745 }
746 }
747 }
748 // Copy the extended register state including the assembled ymm registers.
749 ::memcpy(dst, m_xstate.get(), sizeof(FPR));
750 } else {
751 assert(false && "how do we save the floating point registers?");
753 "unsure how to save the floating point registers");
754 }
755 /** The following code is specific to Linux x86 based architectures,
756 * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
757 * -1 to solve the bug 23659, such a setting prevents the automatic
758 * decrement of the instruction pointer which was causing the SIGILL
759 * exception.
760 * **/
761
762 RegisterValue value((uint64_t)-1);
763 const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();
764 return DoWriteRegisterValue(info.byte_offset, info.name, value);
765
766 return error;
767}
768
769Status NativeRegisterContextLinux_x86::WriteAllRegisterValues(
770 const lldb::DataBufferSP &data_sp) {
772
773 if (!data_sp) {
775 "NativeRegisterContextLinux_x86::%s invalid data_sp provided",
776 __FUNCTION__);
777 return error;
778 }
779
780 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
782 "data_sp contained mismatched data size, expected {0}, actual {1}",
783 REG_CONTEXT_SIZE, data_sp->GetByteSize());
784 return error;
785 }
786
787 const uint8_t *src = data_sp->GetBytes();
788 if (src == nullptr) {
790 "NativeRegisterContextLinux_x86::%s "
791 "DataBuffer::GetBytes() returned a null "
792 "pointer",
793 __FUNCTION__);
794 return error;
795 }
796 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
797
798 error = WriteGPR();
799 if (error.Fail())
800 return error;
801
802 src += GetRegisterInfoInterface().GetGPRSize();
803 if (m_xstate_type == XStateType::FXSAVE)
804 ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));
805 else if (m_xstate_type == XStateType::XSAVE)
806 ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));
807
808 error = WriteFPR();
809 if (error.Fail())
810 return error;
811
812 if (m_xstate_type == XStateType::XSAVE) {
813 lldb::ByteOrder byte_order = GetByteOrder();
814
815 if (IsCPUFeatureAvailable(RegSet::avx)) {
816 // Parse the YMM register content from the register halves.
817 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
818 ++reg) {
819 if (!CopyYMMtoXSTATE(reg, byte_order)) {
821 "NativeRegisterContextLinux_x86::%s "
822 "CopyYMMtoXSTATE() failed for reg num "
823 "%" PRIu32,
824 __FUNCTION__, reg);
825 return error;
826 }
827 }
828 }
829
830 if (IsCPUFeatureAvailable(RegSet::mpx)) {
831 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
832 ++reg) {
833 if (!CopyMPXtoXSTATE(reg)) {
835 "NativeRegisterContextLinux_x86::%s "
836 "CopyMPXtoXSTATE() failed for reg num "
837 "%" PRIu32,
838 __FUNCTION__, reg);
839 return error;
840 }
841 }
842 }
843 }
844
845 return error;
846}
847
848bool NativeRegisterContextLinux_x86::IsCPUFeatureAvailable(
849 RegSet feature_code) const {
850 if (m_xstate_type == XStateType::Invalid) {
851 if (const_cast<NativeRegisterContextLinux_x86 *>(this)->ReadFPR().Fail())
852 return false;
853 }
854 switch (feature_code) {
855 case RegSet::gpr:
856 case RegSet::fpu:
857 return true;
858 case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
859 // reading in the XCR0 area of XSAVE.
860 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
861 return true;
862 break;
863 case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
864 // reading in the XCR0 area of XSAVE.
865 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
866 return true;
867 break;
868 }
869 return false;
870}
871
872bool NativeRegisterContextLinux_x86::IsRegisterSetAvailable(
873 uint32_t set_index) const {
875
876 switch (static_cast<RegSet>(set_index)) {
877 case RegSet::gpr:
878 case RegSet::fpu:
879 return (set_index < num_sets);
880 case RegSet::avx:
881 return IsCPUFeatureAvailable(RegSet::avx);
882 case RegSet::mpx:
883 return IsCPUFeatureAvailable(RegSet::mpx);
884 }
885 return false;
886}
887
888bool NativeRegisterContextLinux_x86::IsGPR(uint32_t reg_index) const {
889 // GPRs come first.
890 return reg_index <= m_reg_info.last_gpr;
891}
892
893bool NativeRegisterContextLinux_x86::IsFPR(uint32_t reg_index) const {
894 return (m_reg_info.first_fpr <= reg_index &&
895 reg_index <= m_reg_info.last_fpr);
896}
897
898bool NativeRegisterContextLinux_x86::IsDR(uint32_t reg_index) const {
899 return (m_reg_info.first_dr <= reg_index &&
900 reg_index <= m_reg_info.last_dr);
901}
902
903Status NativeRegisterContextLinux_x86::WriteFPR() {
904 switch (m_xstate_type) {
905 case XStateType::FXSAVE:
906 return WriteRegisterSet(
907 &m_iovec, sizeof(m_xstate->fxsave),
908 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
909 case XStateType::XSAVE:
910 return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
911 default:
912 return Status::FromErrorString("Unrecognized FPR type.");
913 }
914}
915
916bool NativeRegisterContextLinux_x86::IsAVX(uint32_t reg_index) const {
917 if (!IsCPUFeatureAvailable(RegSet::avx))
918 return false;
919 return (m_reg_info.first_ymm <= reg_index &&
920 reg_index <= m_reg_info.last_ymm);
921}
922
923bool NativeRegisterContextLinux_x86::CopyXSTATEtoYMM(
924 uint32_t reg_index, lldb::ByteOrder byte_order) {
925 if (!IsAVX(reg_index))
926 return false;
927
928 if (byte_order == lldb::eByteOrderLittle) {
929 uint32_t reg_no = reg_index - m_reg_info.first_ymm;
930 m_ymm_set.ymm[reg_no] = XStateToYMM(
931 m_xstate->fxsave.xmm[reg_no].bytes,
932 m_xstate->xsave.ymmh[reg_no].bytes);
933 return true;
934 }
935
936 return false; // unsupported or invalid byte order
937}
938
939bool NativeRegisterContextLinux_x86::CopyYMMtoXSTATE(
940 uint32_t reg, lldb::ByteOrder byte_order) {
941 if (!IsAVX(reg))
942 return false;
943
944 if (byte_order == lldb::eByteOrderLittle) {
945 uint32_t reg_no = reg - m_reg_info.first_ymm;
946 YMMToXState(m_ymm_set.ymm[reg_no],
947 m_xstate->fxsave.xmm[reg_no].bytes,
948 m_xstate->xsave.ymmh[reg_no].bytes);
949 return true;
950 }
951
952 return false; // unsupported or invalid byte order
953}
954
955void *NativeRegisterContextLinux_x86::GetFPRBuffer() {
956 switch (m_xstate_type) {
957 case XStateType::FXSAVE:
958 return &m_xstate->fxsave;
959 case XStateType::XSAVE:
960 return &m_iovec;
961 default:
962 return nullptr;
963 }
964}
965
966size_t NativeRegisterContextLinux_x86::GetFPRSize() {
967 switch (m_xstate_type) {
968 case XStateType::FXSAVE:
969 return sizeof(m_xstate->fxsave);
970 case XStateType::XSAVE:
971 return sizeof(m_iovec);
972 default:
973 return 0;
974 }
975}
976
977Status NativeRegisterContextLinux_x86::ReadFPR() {
979
980 // Probe XSAVE and if it is not supported fall back to FXSAVE.
981 if (m_xstate_type != XStateType::FXSAVE) {
982 error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
983 if (!error.Fail()) {
984 m_xstate_type = XStateType::XSAVE;
985 return error;
986 }
987 }
988 error = ReadRegisterSet(
989 &m_iovec, sizeof(m_xstate->xsave),
990 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
991 if (!error.Fail()) {
992 m_xstate_type = XStateType::FXSAVE;
993 return error;
994 }
995 return Status::FromErrorString("Unrecognized FPR type.");
996}
997
998bool NativeRegisterContextLinux_x86::IsMPX(uint32_t reg_index) const {
999 if (!IsCPUFeatureAvailable(RegSet::mpx))
1000 return false;
1001 return (m_reg_info.first_mpxr <= reg_index &&
1002 reg_index <= m_reg_info.last_mpxc);
1003}
1004
1005bool NativeRegisterContextLinux_x86::CopyXSTATEtoMPX(uint32_t reg) {
1006 if (!IsMPX(reg))
1007 return false;
1008
1009 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1010 ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
1011 m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1012 sizeof(MPXReg));
1013 } else {
1014 ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
1015 m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1016 sizeof(MPXCsr));
1017 }
1018 return true;
1019}
1020
1021bool NativeRegisterContextLinux_x86::CopyMPXtoXSTATE(uint32_t reg) {
1022 if (!IsMPX(reg))
1023 return false;
1024
1025 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1026 ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1027 m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
1028 } else {
1029 ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1030 m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
1031 }
1032 return true;
1033}
1034
1035uint32_t
1036NativeRegisterContextLinux_x86::GetPtraceOffset(uint32_t reg_index) {
1037 // If register is MPX, remove extra factor from gdb offset
1038 return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1039 (IsMPX(reg_index) ? 128 : 0);
1040}
1041
1042std::optional<NativeRegisterContextLinux::SyscallData>
1043NativeRegisterContextLinux_x86::GetSyscallData() {
1044 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1045 case llvm::Triple::x86: {
1046 static const uint8_t Int80[] = {0xcd, 0x80};
1047 static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386,
1050 return SyscallData{Int80, Args, lldb_eax_i386};
1051 }
1052 case llvm::Triple::x86_64: {
1053 static const uint8_t Syscall[] = {0x0f, 0x05};
1054 static const uint32_t Args[] = {
1057 return SyscallData{Syscall, Args, x86_64_with_base::lldb_rax};
1058 }
1059 default:
1060 llvm_unreachable("Unhandled architecture!");
1061 }
1062}
1063
1064std::optional<NativeRegisterContextLinux::MmapData>
1065NativeRegisterContextLinux_x86::GetMmapData() {
1066 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1067 case llvm::Triple::x86:
1068 return MmapData{192, 91};
1069 case llvm::Triple::x86_64:
1070 return MmapData{9, 11};
1071 default:
1072 llvm_unreachable("Unhandled architecture!");
1073 }
1074}
1075
1076const RegisterInfo *NativeRegisterContextLinux_x86::GetDR(int num) const {
1077 assert(num >= 0 && num <= 7);
1078 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1079 case llvm::Triple::x86:
1080 return GetRegisterInfoAtIndex(lldb_dr0_i386 + num);
1081 case llvm::Triple::x86_64:
1082 return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num);
1083 default:
1084 llvm_unreachable("Unhandled target architecture.");
1085 }
1086}
1087
1088#endif // defined(__i386__) || defined(__x86_64__)
static llvm::raw_ostream & error(Stream &strm)
#define REG_CONTEXT_SIZE
struct _FPR FPR
static const RegisterSet g_reg_sets_i386[]
static const uint32_t g_gpr_regnums_x86_64[]
const uint32_t g_gpr_regnums_i386[]
static const RegisterSet g_reg_sets_x86_64[]
const uint32_t g_avx_regnums_i386[]
static const uint32_t g_avx_regnums_x86_64[]
@ k_num_extended_register_sets
A subclass of DataBuffer that stores a data buffer on the heap.
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
void SetType(RegisterValue::Type type)
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static std::unique_ptr< NativeRegisterContextLinux > CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch, NativeThreadLinux &native_thread)
static llvm::Expected< ArchSpec > DetermineArchitecture(lldb::tid_t tid)
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
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.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t tid_t
Definition lldb-types.h:84
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
uint32_t * invalidate_regs
List of registers (terminated with LLDB_INVALID_REGNUM).
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.