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.SetErrorString(
"reg_info NULL");
430 error.SetErrorStringWithFormat(
"register \"%s\" is an internal-only lldb "
431 "register, cannot read directly",
436 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
441 uint32_t full_reg = reg;
450 error = ReadRegisterRaw(full_reg, reg_value);
452 if (
error.Success()) {
471 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
473 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
475 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
477 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
479 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
481 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
483 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
486 if (CopyXSTATEtoYMM(reg, byte_order))
487 reg_value.
SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
490 error.SetErrorString(
"failed to copy ymm register value");
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,
499 error.SetErrorString(
"failed to copy mpx register value");
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,
508 error.SetErrorString(
"failed to copy mpx register value");
513 if (reg_value.
GetType() != RegisterValue::eTypeBytes)
514 error.SetErrorString(
515 "write failed - type was expected to be RegisterValue::eTypeBytes");
520 error.SetErrorString(
"byte order is invalid");
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;
539 if (src ==
reinterpret_cast<uint8_t *
>(&m_xstate->fxsave.ftag)) {
541 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
547 reg_value.
SetUInt8(*(uint8_t *)src);
559 assert(
false &&
"Unhandled data size.");
560 error.SetErrorStringWithFormat(
"unhandled byte size: %" PRIu32,
568void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
569 uint32_t reg_index) {
571 if (IsFPR(reg_index)) {
574 xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
575 }
else if (IsAVX(reg_index)) {
577 xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
578 }
else if (IsMPX(reg_index)) {
580 xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
584Status NativeRegisterContextLinux_x86_64::WriteRegister(
586 assert(reg_info &&
"reg_info is null");
590 return Status(
"no lldb regnum for %s", reg_info && reg_info->
name
592 :
"<unknown register>");
594 UpdateXSTATEforWrite(reg_index);
596 if (IsGPR(reg_index) || IsDR(reg_index))
597 return WriteRegisterRaw(reg_index, reg_value);
599 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
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,
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,
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,
613 if (reg_index >= m_reg_info.first_ymm &&
614 reg_index <= m_reg_info.last_ymm) {
617 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
619 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
620 return Status(
"CopyYMMtoXSTATE() failed");
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,
627 if (!CopyMPXtoXSTATE(reg_index))
628 return Status(
"CopyMPXtoXSTATE() failed");
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,
635 if (!CopyMPXtoXSTATE(reg_index))
636 return Status(
"CopyMPXtoXSTATE() failed");
650 assert((reg_info->
byte_offset - m_fctrl_offset_in_userarea) <
652 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->
byte_offset -
653 m_fctrl_offset_in_userarea;
655 if (dst ==
reinterpret_cast<uint8_t *
>(&m_xstate->fxsave.ftag))
672 assert(
false &&
"Unhandled data size.");
673 return Status(
"unhandled register data size %" PRIu32,
683 if (IsAVX(reg_index)) {
684 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
685 return Status(
"CopyYMMtoXSTATE() failed");
688 if (IsMPX(reg_index)) {
689 if (!CopyMPXtoXSTATE(reg_index))
690 return Status(
"CopyMPXtoXSTATE() failed");
694 return Status(
"failed - register wasn't recognized to be a GPR or an FPR, "
695 "write strategy unknown");
698Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
711 uint8_t *dst = data_sp->GetBytes();
712 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
713 dst += GetRegisterInfoInterface().GetGPRSize();
714 if (m_xstate_type == XStateType::FXSAVE)
715 ::memcpy(dst, &m_xstate->fxsave,
sizeof(m_xstate->fxsave));
716 else if (m_xstate_type == XStateType::XSAVE) {
719 if (IsCPUFeatureAvailable(RegSet::avx)) {
721 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
723 if (!CopyXSTATEtoYMM(reg, byte_order)) {
724 error.SetErrorStringWithFormat(
725 "NativeRegisterContextLinux_x86_64::%s "
726 "CopyXSTATEtoYMM() failed for reg num "
734 if (IsCPUFeatureAvailable(RegSet::mpx)) {
735 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
737 if (!CopyXSTATEtoMPX(reg)) {
738 error.SetErrorStringWithFormat(
739 "NativeRegisterContextLinux_x86_64::%s "
740 "CopyXSTATEtoMPX() failed for reg num "
748 ::memcpy(dst, m_xstate.get(),
sizeof(
FPR));
750 assert(
false &&
"how do we save the floating point registers?");
751 error.SetErrorString(
"unsure how to save the floating point registers");
761 const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();
767Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
772 error.SetErrorStringWithFormat(
773 "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
779 error.SetErrorStringWithFormatv(
780 "data_sp contained mismatched data size, expected {0}, actual {1}",
785 const uint8_t *src = data_sp->GetBytes();
786 if (src ==
nullptr) {
787 error.SetErrorStringWithFormat(
"NativeRegisterContextLinux_x86_64::%s "
788 "DataBuffer::GetBytes() returned a null "
793 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
799 src += GetRegisterInfoInterface().GetGPRSize();
800 if (m_xstate_type == XStateType::FXSAVE)
801 ::memcpy(&m_xstate->fxsave, src,
sizeof(m_xstate->fxsave));
802 else if (m_xstate_type == XStateType::XSAVE)
803 ::memcpy(&m_xstate->xsave, src,
sizeof(m_xstate->xsave));
809 if (m_xstate_type == XStateType::XSAVE) {
812 if (IsCPUFeatureAvailable(RegSet::avx)) {
814 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
816 if (!CopyYMMtoXSTATE(reg, byte_order)) {
817 error.SetErrorStringWithFormat(
818 "NativeRegisterContextLinux_x86_64::%s "
819 "CopyYMMtoXSTATE() failed for reg num "
827 if (IsCPUFeatureAvailable(RegSet::mpx)) {
828 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
830 if (!CopyMPXtoXSTATE(reg)) {
831 error.SetErrorStringWithFormat(
832 "NativeRegisterContextLinux_x86_64::%s "
833 "CopyMPXtoXSTATE() failed for reg num "
845bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
846 RegSet feature_code)
const {
847 if (m_xstate_type == XStateType::Invalid) {
848 if (
const_cast<NativeRegisterContextLinux_x86_64 *
>(
this)->ReadFPR().Fail())
851 switch (feature_code) {
857 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
862 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
869bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
870 uint32_t set_index)
const {
873 switch (
static_cast<RegSet
>(set_index)) {
876 return (set_index < num_sets);
878 return IsCPUFeatureAvailable(RegSet::avx);
880 return IsCPUFeatureAvailable(RegSet::mpx);
885bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index)
const {
887 return reg_index <= m_reg_info.last_gpr;
890bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index)
const {
891 return (m_reg_info.first_fpr <= reg_index &&
892 reg_index <= m_reg_info.last_fpr);
895bool NativeRegisterContextLinux_x86_64::IsDR(uint32_t reg_index)
const {
896 return (m_reg_info.first_dr <= reg_index &&
897 reg_index <= m_reg_info.last_dr);
900Status NativeRegisterContextLinux_x86_64::WriteFPR() {
901 switch (m_xstate_type) {
902 case XStateType::FXSAVE:
903 return WriteRegisterSet(
904 &m_iovec,
sizeof(m_xstate->fxsave),
905 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
906 case XStateType::XSAVE:
907 return WriteRegisterSet(&m_iovec,
sizeof(m_xstate->xsave), NT_X86_XSTATE);
909 return Status(
"Unrecognized FPR type.");
913bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index)
const {
914 if (!IsCPUFeatureAvailable(RegSet::avx))
916 return (m_reg_info.first_ymm <= reg_index &&
917 reg_index <= m_reg_info.last_ymm);
920bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
922 if (!IsAVX(reg_index))
926 uint32_t reg_no = reg_index - m_reg_info.first_ymm;
928 m_xstate->fxsave.xmm[reg_no].bytes,
929 m_xstate->xsave.ymmh[reg_no].bytes);
936bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
942 uint32_t reg_no = reg - m_reg_info.first_ymm;
944 m_xstate->fxsave.xmm[reg_no].bytes,
945 m_xstate->xsave.ymmh[reg_no].bytes);
952void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
953 switch (m_xstate_type) {
954 case XStateType::FXSAVE:
955 return &m_xstate->fxsave;
956 case XStateType::XSAVE:
963size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
964 switch (m_xstate_type) {
965 case XStateType::FXSAVE:
966 return sizeof(m_xstate->fxsave);
967 case XStateType::XSAVE:
968 return sizeof(m_iovec);
974Status NativeRegisterContextLinux_x86_64::ReadFPR() {
978 if (m_xstate_type != XStateType::FXSAVE) {
979 error = ReadRegisterSet(&m_iovec,
sizeof(m_xstate->xsave), NT_X86_XSTATE);
981 m_xstate_type = XStateType::XSAVE;
985 error = ReadRegisterSet(
986 &m_iovec,
sizeof(m_xstate->xsave),
987 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
989 m_xstate_type = XStateType::FXSAVE;
992 return Status(
"Unrecognized FPR type.");
995bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index)
const {
996 if (!IsCPUFeatureAvailable(RegSet::mpx))
998 return (m_reg_info.first_mpxr <= reg_index &&
999 reg_index <= m_reg_info.last_mpxc);
1002bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
1006 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1007 ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
1008 m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1011 ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
1012 m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1018bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
1022 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1023 ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1024 m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
sizeof(
MPXReg));
1026 ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1027 m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
sizeof(
MPXCsr));
1033NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
1035 return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1036 (IsMPX(reg_index) ? 128 : 0);
1039std::optional<NativeRegisterContextLinux::SyscallData>
1040NativeRegisterContextLinux_x86_64::GetSyscallData() {
1041 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1042 case llvm::Triple::x86: {
1043 static const uint8_t Int80[] = {0xcd, 0x80};
1049 case llvm::Triple::x86_64: {
1050 static const uint8_t Syscall[] = {0x0f, 0x05};
1051 static const uint32_t
Args[] = {
1052 x86_64_with_base::lldb_rax, x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_rdx,
1053 x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r9};
1054 return SyscallData{Syscall,
Args, x86_64_with_base::lldb_rax};
1057 llvm_unreachable(
"Unhandled architecture!");
1061std::optional<NativeRegisterContextLinux::MmapData>
1062NativeRegisterContextLinux_x86_64::GetMmapData() {
1063 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1064 case llvm::Triple::x86:
1065 return MmapData{192, 91};
1066 case llvm::Triple::x86_64:
1067 return MmapData{9, 11};
1069 llvm_unreachable(
"Unhandled architecture!");
1073const RegisterInfo *NativeRegisterContextLinux_x86_64::GetDR(
int num)
const {
1074 assert(num >= 0 && num <= 7);
1075 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1076 case llvm::Triple::x86:
1077 return GetRegisterInfoAtIndex(lldb_dr0_i386 + num);
1078 case llvm::Triple::x86_64:
1079 return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num);
1081 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)
YMMReg XStateToYMM(const void *xmm_bytes, const void *ymmh_bytes)
@ k_num_avx_registers_i386
@ k_num_fpr_registers_i386
@ k_num_mpx_registers_i386
@ k_num_gpr_registers_i386
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.