9#if defined(__i386__) || defined(__x86_64__)
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)
32 unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000,
nullptr);
34 if (__max_leaf == 0 || __max_leaf < __leaf)
37 __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
58 k_num_gpr_registers_i386,
59 "g_gpr_regnums_i386 has wrong number of register infos");
62static const uint32_t g_fpu_regnums_i386[] = {
74static_assert((
sizeof(g_fpu_regnums_i386) /
sizeof(g_fpu_regnums_i386[0])) -
76 k_num_fpr_registers_i386,
77 "g_fpu_regnums_i386 has wrong number of register infos");
87 k_num_avx_registers_i386,
88 " g_avx_regnums_i386 has wrong number of register infos");
91static const uint32_t g_mpx_regnums_i386[] = {
96static_assert((
sizeof(g_mpx_regnums_i386) /
sizeof(g_mpx_regnums_i386[0])) -
98 k_num_mpx_registers_i386,
99 "g_mpx_regnums_x86_64 has wrong number of register infos");
103 x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rbx, x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_rdx,
104 x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_rsp,
105 x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9, x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r11,
106 x86_64_with_base::lldb_r12, x86_64_with_base::lldb_r13, x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r15,
107 x86_64_with_base::lldb_rip, x86_64_with_base::lldb_rflags, x86_64_with_base::lldb_cs, x86_64_with_base::lldb_fs,
108 x86_64_with_base::lldb_gs, x86_64_with_base::lldb_ss, x86_64_with_base::lldb_fs_base, x86_64_with_base::lldb_gs_base,
109 x86_64_with_base::lldb_ds, x86_64_with_base::lldb_es,
110 x86_64_with_base::lldb_eax, x86_64_with_base::lldb_ebx, x86_64_with_base::lldb_ecx, x86_64_with_base::lldb_edx,
111 x86_64_with_base::lldb_edi, x86_64_with_base::lldb_esi, x86_64_with_base::lldb_ebp, x86_64_with_base::lldb_esp,
112 x86_64_with_base::lldb_r8d,
113 x86_64_with_base::lldb_r9d,
114 x86_64_with_base::lldb_r10d,
115 x86_64_with_base::lldb_r11d,
116 x86_64_with_base::lldb_r12d,
117 x86_64_with_base::lldb_r13d,
118 x86_64_with_base::lldb_r14d,
119 x86_64_with_base::lldb_r15d,
120 x86_64_with_base::lldb_ax, x86_64_with_base::lldb_bx, x86_64_with_base::lldb_cx, x86_64_with_base::lldb_dx,
121 x86_64_with_base::lldb_di, x86_64_with_base::lldb_si, x86_64_with_base::lldb_bp, x86_64_with_base::lldb_sp,
122 x86_64_with_base::lldb_r8w,
123 x86_64_with_base::lldb_r9w,
124 x86_64_with_base::lldb_r10w,
125 x86_64_with_base::lldb_r11w,
126 x86_64_with_base::lldb_r12w,
127 x86_64_with_base::lldb_r13w,
128 x86_64_with_base::lldb_r14w,
129 x86_64_with_base::lldb_r15w,
130 x86_64_with_base::lldb_ah, x86_64_with_base::lldb_bh, x86_64_with_base::lldb_ch, x86_64_with_base::lldb_dh,
131 x86_64_with_base::lldb_al, x86_64_with_base::lldb_bl, x86_64_with_base::lldb_cl, x86_64_with_base::lldb_dl,
132 x86_64_with_base::lldb_dil, x86_64_with_base::lldb_sil, x86_64_with_base::lldb_bpl, x86_64_with_base::lldb_spl,
133 x86_64_with_base::lldb_r8l,
134 x86_64_with_base::lldb_r9l,
135 x86_64_with_base::lldb_r10l,
136 x86_64_with_base::lldb_r11l,
137 x86_64_with_base::lldb_r12l,
138 x86_64_with_base::lldb_r13l,
139 x86_64_with_base::lldb_r14l,
140 x86_64_with_base::lldb_r15l,
145 x86_64_with_base::k_num_gpr_registers,
146 "g_gpr_regnums_x86_64 has wrong number of register infos");
149static const uint32_t g_fpu_regnums_x86_64[] = {
150 x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat, x86_64_with_base::lldb_ftag,
151 x86_64_with_base::lldb_fop, x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff,
152 x86_64_with_base::lldb_fip, x86_64_with_base::lldb_foseg, x86_64_with_base::lldb_fooff,
153 x86_64_with_base::lldb_fdp, x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask,
154 x86_64_with_base::lldb_st0, x86_64_with_base::lldb_st1, x86_64_with_base::lldb_st2,
155 x86_64_with_base::lldb_st3, x86_64_with_base::lldb_st4, x86_64_with_base::lldb_st5,
156 x86_64_with_base::lldb_st6, x86_64_with_base::lldb_st7, x86_64_with_base::lldb_mm0,
157 x86_64_with_base::lldb_mm1, x86_64_with_base::lldb_mm2, x86_64_with_base::lldb_mm3,
158 x86_64_with_base::lldb_mm4, x86_64_with_base::lldb_mm5, x86_64_with_base::lldb_mm6,
159 x86_64_with_base::lldb_mm7, x86_64_with_base::lldb_xmm0, x86_64_with_base::lldb_xmm1,
160 x86_64_with_base::lldb_xmm2, x86_64_with_base::lldb_xmm3, x86_64_with_base::lldb_xmm4,
161 x86_64_with_base::lldb_xmm5, x86_64_with_base::lldb_xmm6, x86_64_with_base::lldb_xmm7,
162 x86_64_with_base::lldb_xmm8, x86_64_with_base::lldb_xmm9, x86_64_with_base::lldb_xmm10,
163 x86_64_with_base::lldb_xmm11, x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13,
164 x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15,
167static_assert((
sizeof(g_fpu_regnums_x86_64) /
sizeof(g_fpu_regnums_x86_64[0])) -
169 x86_64_with_base::k_num_fpr_registers,
170 "g_fpu_regnums_x86_64 has wrong number of register infos");
174 x86_64_with_base::lldb_ymm0, x86_64_with_base::lldb_ymm1, x86_64_with_base::lldb_ymm2, x86_64_with_base::lldb_ymm3,
175 x86_64_with_base::lldb_ymm4, x86_64_with_base::lldb_ymm5, x86_64_with_base::lldb_ymm6, x86_64_with_base::lldb_ymm7,
176 x86_64_with_base::lldb_ymm8, x86_64_with_base::lldb_ymm9, x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11,
177 x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13, x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15,
182 x86_64_with_base::k_num_avx_registers,
183 "g_avx_regnums_x86_64 has wrong number of register infos");
186static const uint32_t g_mpx_regnums_x86_64[] = {
187 x86_64_with_base::lldb_bnd0, x86_64_with_base::lldb_bnd1, x86_64_with_base::lldb_bnd2,
188 x86_64_with_base::lldb_bnd3, x86_64_with_base::lldb_bndcfgu, x86_64_with_base::lldb_bndstatus,
191static_assert((
sizeof(g_mpx_regnums_x86_64) /
sizeof(g_mpx_regnums_x86_64[0])) -
193 x86_64_with_base::k_num_mpx_registers,
194 "g_mpx_regnums_x86_64 has wrong number of register infos");
208 g_mpx_regnums_i386}};
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}};
221#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
227#define NT_X86_XSTATE 0x202
230#define NT_PRXFPREG 0x46e62b7f
235static inline unsigned int fxsr_regset(
const ArchSpec &arch) {
243#define bit_MPX 0x4000
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)
252std::unique_ptr<NativeRegisterContextLinux>
253NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
255 return std::unique_ptr<NativeRegisterContextLinux>(
256 new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
259llvm::Expected<ArchSpec>
260NativeRegisterContextLinux::DetermineArchitecture(
lldb::tid_t tid) {
261 return DetermineArchitectureViaGPR(
267static std::unique_ptr<RegisterContextLinux_x86>
268CreateRegisterInfoInterface(
const ArchSpec &target_arch) {
269 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
271 return std::make_unique<RegisterContextLinux_i386>(target_arch);
273 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
274 "Register setting path assumes this is a 64-bit host");
277 return std::make_unique<RegisterContextLinux_x86_64>(target_arch);
286static std::size_t GetXSTATESize() {
295 return std::max<std::size_t>(
ecx,
sizeof(
FPR));
298NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
301 native_thread, CreateRegisterInfoInterface(target_arch).release()),
304 m_xstate_type(XStateType::
Invalid), m_ymm_set(), m_mpx_set(),
305 m_reg_info(), m_gpr_x86_64() {
308 case llvm::Triple::x86:
333 case llvm::Triple::x86_64:
334 m_reg_info.num_registers = x86_64_with_base::k_num_registers;
335 m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers;
336 m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers;
337 m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers;
338 m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers;
339 m_reg_info.last_gpr = x86_64_with_base::k_last_gpr;
340 m_reg_info.first_fpr = x86_64_with_base::k_first_fpr;
341 m_reg_info.last_fpr = x86_64_with_base::k_last_fpr;
342 m_reg_info.first_st = x86_64_with_base::lldb_st0;
343 m_reg_info.last_st = x86_64_with_base::lldb_st7;
344 m_reg_info.first_mm = x86_64_with_base::lldb_mm0;
345 m_reg_info.last_mm = x86_64_with_base::lldb_mm7;
346 m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0;
347 m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15;
348 m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0;
349 m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15;
350 m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0;
351 m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3;
352 m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu;
353 m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus;
354 m_reg_info.first_dr = x86_64_with_base::lldb_dr0;
355 m_reg_info.last_dr = x86_64_with_base::lldb_dr7;
356 m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags;
359 assert(
false &&
"Unhandled target architecture.");
363 std::size_t xstate_size = GetXSTATESize();
364 m_xstate.reset(
static_cast<FPR *
>(std::malloc(xstate_size)));
365 m_iovec.iov_base = m_xstate.get();
366 m_iovec.iov_len = xstate_size;
369 ::memset(m_xstate.get(), 0, xstate_size);
372 const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName(
"fctrl");
373 m_fctrl_offset_in_userarea = reg_info_fctrl->
byte_offset;
378uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount()
const {
381 if (IsRegisterSetAvailable(set_index))
388uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount()
const {
391 const RegisterSet *set = GetRegisterSet(set_index);
399NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index)
const {
400 if (!IsRegisterSetAvailable(set_index))
403 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
404 case llvm::Triple::x86:
406 case llvm::Triple::x86_64:
409 assert(
false &&
"Unhandled target architecture.");
417NativeRegisterContextLinux_x86_64::ReadRegister(
const RegisterInfo *reg_info,
422 error = Status::FromErrorString(
"reg_info NULL");
430 error = Status::FromErrorStringWithFormat(
431 "register \"%s\" is an internal-only lldb "
432 "register, cannot read directly",
437 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
442 uint32_t full_reg = reg;
451 error = ReadRegisterRaw(full_reg, reg_value);
453 if (
error.Success()) {
472 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
474 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
476 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
478 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
480 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
482 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
484 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
487 if (CopyXSTATEtoYMM(reg, byte_order))
488 reg_value.
SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
491 error = Status::FromErrorString(
"failed to copy ymm register value");
495 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
496 if (CopyXSTATEtoMPX(reg))
497 reg_value.
SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
500 error = Status::FromErrorString(
"failed to copy mpx register value");
504 if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
505 if (CopyXSTATEtoMPX(reg))
506 reg_value.
SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
509 error = Status::FromErrorString(
"failed to copy mpx register value");
514 if (reg_value.
GetType() != RegisterValue::eTypeBytes)
515 error = Status::FromErrorString(
516 "write failed - type was expected to be RegisterValue::eTypeBytes");
521 error = Status::FromErrorString(
"byte order is invalid");
536 assert((reg_info->
byte_offset - m_fctrl_offset_in_userarea) <
sizeof(
FPR));
537 uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->
byte_offset -
538 m_fctrl_offset_in_userarea;
540 if (src ==
reinterpret_cast<uint8_t *
>(&m_xstate->fxsave.ftag)) {
542 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
548 reg_value.
SetUInt8(*(uint8_t *)src);
560 assert(
false &&
"Unhandled data size.");
561 error = Status::FromErrorStringWithFormat(
"unhandled byte size: %" PRIu32,
569void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
570 uint32_t reg_index) {
572 if (IsFPR(reg_index)) {
575 xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
576 }
else if (IsAVX(reg_index)) {
578 xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
579 }
else if (IsMPX(reg_index)) {
581 xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
585Status NativeRegisterContextLinux_x86_64::WriteRegister(
587 assert(reg_info &&
"reg_info is null");
591 return Status::FromErrorStringWithFormat(
592 "no lldb regnum for %s",
593 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
595 UpdateXSTATEforWrite(reg_index);
597 if (IsGPR(reg_index) || IsDR(reg_index))
598 return WriteRegisterRaw(reg_index, reg_value);
600 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
602 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
603 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
606 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
607 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
610 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
611 ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
614 if (reg_index >= m_reg_info.first_ymm &&
615 reg_index <= m_reg_info.last_ymm) {
618 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
620 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
621 return Status::FromErrorString(
"CopyYMMtoXSTATE() failed");
624 if (reg_index >= m_reg_info.first_mpxr &&
625 reg_index <= m_reg_info.last_mpxr) {
626 ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
628 if (!CopyMPXtoXSTATE(reg_index))
629 return Status::FromErrorString(
"CopyMPXtoXSTATE() failed");
632 if (reg_index >= m_reg_info.first_mpxc &&
633 reg_index <= m_reg_info.last_mpxc) {
634 ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
636 if (!CopyMPXtoXSTATE(reg_index))
637 return Status::FromErrorString(
"CopyMPXtoXSTATE() failed");
651 assert((reg_info->
byte_offset - m_fctrl_offset_in_userarea) <
653 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->
byte_offset -
654 m_fctrl_offset_in_userarea;
656 if (dst ==
reinterpret_cast<uint8_t *
>(&m_xstate->fxsave.ftag))
673 assert(
false &&
"Unhandled data size.");
674 return Status::FromErrorStringWithFormat(
675 "unhandled register data size %" PRIu32, reg_info->
byte_size);
684 if (IsAVX(reg_index)) {
685 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
686 return Status::FromErrorString(
"CopyYMMtoXSTATE() failed");
689 if (IsMPX(reg_index)) {
690 if (!CopyMPXtoXSTATE(reg_index))
691 return Status::FromErrorString(
"CopyMPXtoXSTATE() failed");
695 return Status::FromErrorString(
696 "failed - register wasn't recognized to be a GPR or an FPR, "
697 "write strategy unknown");
700Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
713 uint8_t *dst = data_sp->GetBytes();
714 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
715 dst += GetRegisterInfoInterface().GetGPRSize();
716 if (m_xstate_type == XStateType::FXSAVE)
717 ::memcpy(dst, &m_xstate->fxsave,
sizeof(m_xstate->fxsave));
718 else if (m_xstate_type == XStateType::XSAVE) {
721 if (IsCPUFeatureAvailable(RegSet::avx)) {
723 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
725 if (!CopyXSTATEtoYMM(reg, byte_order)) {
726 error = Status::FromErrorStringWithFormat(
727 "NativeRegisterContextLinux_x86_64::%s "
728 "CopyXSTATEtoYMM() failed for reg num "
736 if (IsCPUFeatureAvailable(RegSet::mpx)) {
737 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
739 if (!CopyXSTATEtoMPX(reg)) {
740 error = Status::FromErrorStringWithFormat(
741 "NativeRegisterContextLinux_x86_64::%s "
742 "CopyXSTATEtoMPX() failed for reg num "
750 ::memcpy(dst, m_xstate.get(),
sizeof(
FPR));
752 assert(
false &&
"how do we save the floating point registers?");
753 error = Status::FromErrorString(
754 "unsure how to save the floating point registers");
764 const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();
770Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
775 error = Status::FromErrorStringWithFormat(
776 "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
782 error = Status::FromErrorStringWithFormatv(
783 "data_sp contained mismatched data size, expected {0}, actual {1}",
788 const uint8_t *src = data_sp->GetBytes();
789 if (src ==
nullptr) {
790 error = Status::FromErrorStringWithFormat(
791 "NativeRegisterContextLinux_x86_64::%s "
792 "DataBuffer::GetBytes() returned a null "
797 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
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));
813 if (m_xstate_type == XStateType::XSAVE) {
816 if (IsCPUFeatureAvailable(RegSet::avx)) {
818 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
820 if (!CopyYMMtoXSTATE(reg, byte_order)) {
821 error = Status::FromErrorStringWithFormat(
822 "NativeRegisterContextLinux_x86_64::%s "
823 "CopyYMMtoXSTATE() failed for reg num "
831 if (IsCPUFeatureAvailable(RegSet::mpx)) {
832 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
834 if (!CopyMPXtoXSTATE(reg)) {
835 error = Status::FromErrorStringWithFormat(
836 "NativeRegisterContextLinux_x86_64::%s "
837 "CopyMPXtoXSTATE() failed for reg num "
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())
855 switch (feature_code) {
861 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
866 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
873bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
874 uint32_t set_index)
const {
877 switch (
static_cast<RegSet
>(set_index)) {
880 return (set_index < num_sets);
882 return IsCPUFeatureAvailable(RegSet::avx);
884 return IsCPUFeatureAvailable(RegSet::mpx);
889bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index)
const {
891 return reg_index <= m_reg_info.last_gpr;
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);
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);
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);
913 return Status::FromErrorString(
"Unrecognized FPR type.");
917bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index)
const {
918 if (!IsCPUFeatureAvailable(RegSet::avx))
920 return (m_reg_info.first_ymm <= reg_index &&
921 reg_index <= m_reg_info.last_ymm);
924bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
926 if (!IsAVX(reg_index))
930 uint32_t reg_no = reg_index - m_reg_info.first_ymm;
932 m_xstate->fxsave.xmm[reg_no].bytes,
933 m_xstate->xsave.ymmh[reg_no].bytes);
940bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
946 uint32_t reg_no = reg - m_reg_info.first_ymm;
948 m_xstate->fxsave.xmm[reg_no].bytes,
949 m_xstate->xsave.ymmh[reg_no].bytes);
956void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
957 switch (m_xstate_type) {
958 case XStateType::FXSAVE:
959 return &m_xstate->fxsave;
960 case XStateType::XSAVE:
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);
978Status NativeRegisterContextLinux_x86_64::ReadFPR() {
982 if (m_xstate_type != XStateType::FXSAVE) {
983 error = ReadRegisterSet(&m_iovec,
sizeof(m_xstate->xsave), NT_X86_XSTATE);
985 m_xstate_type = XStateType::XSAVE;
989 error = ReadRegisterSet(
990 &m_iovec,
sizeof(m_xstate->xsave),
991 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
993 m_xstate_type = XStateType::FXSAVE;
996 return Status::FromErrorString(
"Unrecognized FPR type.");
999bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index)
const {
1000 if (!IsCPUFeatureAvailable(RegSet::mpx))
1002 return (m_reg_info.first_mpxr <= reg_index &&
1003 reg_index <= m_reg_info.last_mpxc);
1006bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
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,
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,
1022bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
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));
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));
1037NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
1039 return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1040 (IsMPX(reg_index) ? 128 : 0);
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};
1053 case llvm::Triple::x86_64: {
1054 static const uint8_t Syscall[] = {0x0f, 0x05};
1055 static const uint32_t
Args[] = {
1056 x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rdx,
1057 x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9};
1058 return SyscallData{Syscall,
Args, x86_64_with_base::lldb_rax};
1061 llvm_unreachable(
"Unhandled architecture!");
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};
1073 llvm_unreachable(
"Unhandled architecture!");
1077const RegisterInfo *NativeRegisterContextLinux_x86_64::GetDR(
int num)
const {
1078 assert(num >= 0 && num <= 7);
1079 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1080 case llvm::Triple::x86:
1081 return GetRegisterInfoAtIndex(lldb_dr0_i386 + num);
1082 case llvm::Triple::x86_64:
1083 return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num);
1085 llvm_unreachable(
"Unhandled target architecture.");
static llvm::raw_ostream & error(Stream &strm)
constexpr size_t k_num_register_sets
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
static size_t GetGPRSizeStatic()
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
A command line argument class.
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)
uint32_t GetByteSize() const
#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)
@ k_num_avx_registers_i386
@ k_num_fpr_registers_i386
@ k_num_mpx_registers_i386
@ k_num_gpr_registers_i386
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
@ 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.