9#if defined(__i386__) || defined(__x86_64__)
31#include <sys/ptrace.h>
33#ifndef PTRACE_GET_THREAD_AREA
34#define PTRACE_GET_THREAD_AREA 25
40static inline int get_cpuid_count(
unsigned int __leaf,
41 unsigned int __subleaf,
42 unsigned int *__eax,
unsigned int *__ebx,
43 unsigned int *__ecx,
unsigned int *__edx)
45 unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000,
nullptr);
47 if (__max_leaf == 0 || __max_leaf < __leaf)
50 __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
76 "g_gpr_regnums_i386 has wrong number of register infos");
79static const uint32_t g_fpu_regnums_i386[] = {
91static_assert((
sizeof(g_fpu_regnums_i386) /
sizeof(g_fpu_regnums_i386[0])) -
94 "g_fpu_regnums_i386 has wrong number of register infos");
105 " g_avx_regnums_i386 has wrong number of register infos");
108static const uint32_t g_mpx_regnums_i386[] = {
113static_assert((
sizeof(g_mpx_regnums_i386) /
sizeof(g_mpx_regnums_i386[0])) -
116 "g_mpx_regnums_x86_64 has wrong number of register infos");
163 "g_gpr_regnums_x86_64 has wrong number of register infos");
166static const uint32_t g_fpu_regnums_x86_64[] = {
184static_assert((
sizeof(g_fpu_regnums_x86_64) /
sizeof(g_fpu_regnums_x86_64[0])) -
187 "g_fpu_regnums_x86_64 has wrong number of register infos");
200 "g_avx_regnums_x86_64 has wrong number of register infos");
203static const uint32_t g_mpx_regnums_x86_64[] = {
208static_assert((
sizeof(g_mpx_regnums_x86_64) /
sizeof(g_mpx_regnums_x86_64[0])) -
211 "g_mpx_regnums_x86_64 has wrong number of register infos");
225 g_mpx_regnums_i386}};
232 g_fpu_regnums_x86_64},
236 g_mpx_regnums_x86_64}};
238#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
244#define NT_X86_XSTATE 0x202
247#define NT_PRXFPREG 0x46e62b7f
252static inline unsigned int fxsr_regset(
const ArchSpec &arch) {
253 return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
260#define bit_MPX 0x4000
264#define mask_XSTATE_AVX (1ULL << 2)
265#define mask_XSTATE_BNDREGS (1ULL << 3)
266#define mask_XSTATE_BNDCFG (1ULL << 4)
267#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
269std::unique_ptr<NativeRegisterContextLinux>
272 return std::unique_ptr<NativeRegisterContextLinux>(
273 new NativeRegisterContextLinux_x86(target_arch, native_thread));
276llvm::Expected<ArchSpec>
278 return DetermineArchitectureViaGPR(
284static std::unique_ptr<RegisterContextLinux_x86>
285CreateRegisterInfoInterface(
const ArchSpec &target_arch) {
286 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
288 return std::make_unique<RegisterContextLinux_i386>(target_arch);
290 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
291 "Register setting path assumes this is a 64-bit host");
294 return std::make_unique<RegisterContextLinux_x86_64>(target_arch);
303static std::size_t GetXSTATESize() {
312 return std::max<std::size_t>(
ecx,
sizeof(
FPR));
315NativeRegisterContextLinux_x86::NativeRegisterContextLinux_x86(
318 native_thread, CreateRegisterInfoInterface(target_arch).release()),
320 m_xstate_type(XStateType::
Invalid), m_ymm_set(), m_mpx_set(),
321 m_reg_info(), m_gpr_x86_64() {
323 switch (target_arch.GetMachine()) {
324 case llvm::Triple::x86: {
325 const RegisterInfoInterface ®ister_info = GetRegisterInfoInterface();
328 uint32_t byte_offset = 0;
329 for (uint32_t i = 0; i < register_info.GetUserRegisterCount(); ++i) {
330 const RegisterInfo &info = register_info.GetRegisterInfo()[i];
331 byte_offset = std::max(byte_offset, info.byte_offset + info.byte_size);
333 m_i386_thread_pointer_info = {
"gs_base",
339 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
340 LLDB_REGNUM_GENERIC_TP, LLDB_INVALID_REGNUM,
341 LLDB_INVALID_REGNUM},
346 m_reg_info.num_registers = k_num_registers_i386 + 1;
347 m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
348 m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
349 m_reg_info.num_avx_registers = k_num_avx_registers_i386;
350 m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
351 m_reg_info.last_gpr = k_last_gpr_i386;
352 m_reg_info.first_fpr = k_first_fpr_i386;
353 m_reg_info.last_fpr = k_last_fpr_i386;
354 m_reg_info.first_st = lldb_st0_i386;
355 m_reg_info.last_st = lldb_st7_i386;
356 m_reg_info.first_mm = lldb_mm0_i386;
357 m_reg_info.last_mm = lldb_mm7_i386;
358 m_reg_info.first_xmm = lldb_xmm0_i386;
359 m_reg_info.last_xmm = lldb_xmm7_i386;
360 m_reg_info.first_ymm = lldb_ymm0_i386;
361 m_reg_info.last_ymm = lldb_ymm7_i386;
362 m_reg_info.first_mpxr = lldb_bnd0_i386;
363 m_reg_info.last_mpxr = lldb_bnd3_i386;
364 m_reg_info.first_mpxc = lldb_bndcfgu_i386;
365 m_reg_info.last_mpxc = lldb_bndstatus_i386;
366 m_reg_info.first_dr = lldb_dr0_i386;
367 m_reg_info.last_dr = lldb_dr7_i386;
368 m_reg_info.gpr_flags = lldb_eflags_i386;
371 case llvm::Triple::x86_64:
397 assert(
false &&
"Unhandled target architecture.");
401 std::size_t xstate_size = GetXSTATESize();
402 m_xstate.reset(
static_cast<FPR *
>(std::malloc(xstate_size)));
403 m_iovec.iov_base = m_xstate.get();
404 m_iovec.iov_len = xstate_size;
407 ::memset(m_xstate.get(), 0, xstate_size);
410 const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName(
"fctrl");
411 m_fctrl_offset_in_userarea = reg_info_fctrl->
byte_offset;
414uint32_t NativeRegisterContextLinux_x86::GetRegisterCount()
const {
416 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
423NativeRegisterContextLinux_x86::GetRegisterInfoAtIndex(uint32_t reg)
const {
424 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
426 if (reg == k_i386_thread_pointer_index)
427 return &m_i386_thread_pointer_info;
429 if (reg > k_i386_thread_pointer_index)
437uint32_t NativeRegisterContextLinux_x86::GetRegisterSetCount()
const {
440 if (IsRegisterSetAvailable(set_index))
447uint32_t NativeRegisterContextLinux_x86::GetUserRegisterCount()
const {
450 const RegisterSet *set = GetRegisterSet(set_index);
454 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
461NativeRegisterContextLinux_x86::GetRegisterSet(uint32_t set_index)
const {
462 if (!IsRegisterSetAvailable(set_index))
465 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
466 case llvm::Triple::x86:
468 case llvm::Triple::x86_64:
471 assert(
false &&
"Unhandled target architecture.");
479NativeRegisterContextLinux_x86::ReadRegister(
const RegisterInfo *reg_info,
488 if (IsThreadPointer(*reg_info))
489 return ReadThreadPointer(reg_value);
496 "register \"%s\" is an internal-only lldb "
497 "register, cannot read directly",
502 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
507 uint32_t full_reg = reg;
516 error = ReadRegisterRaw(GetRegisterInfoIndex(full_reg), reg_value);
518 if (
error.Success()) {
537 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
539 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
541 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
543 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
545 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
547 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
549 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
552 if (CopyXSTATEtoYMM(reg, byte_order))
553 reg_value.
SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
560 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
561 if (CopyXSTATEtoMPX(reg))
562 reg_value.
SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
569 if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
570 if (CopyXSTATEtoMPX(reg))
571 reg_value.
SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
581 "write failed - type was expected to be RegisterValue::eTypeBytes");
601 assert((reg_info->
byte_offset - m_fctrl_offset_in_userarea) <
sizeof(
FPR));
602 uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->
byte_offset -
603 m_fctrl_offset_in_userarea;
605 if (src ==
reinterpret_cast<uint8_t *
>(&m_xstate->fxsave.ftag)) {
607 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
613 reg_value.
SetUInt8(*(uint8_t *)src);
625 assert(
false &&
"Unhandled data size.");
634void NativeRegisterContextLinux_x86::UpdateXSTATEforWrite(
635 uint32_t reg_index) {
637 if (IsFPR(reg_index)) {
641 }
else if (IsAVX(reg_index)) {
644 }
else if (IsMPX(reg_index)) {
650Status NativeRegisterContextLinux_x86::WriteRegister(
652 assert(reg_info &&
"reg_info is null");
654 if (IsThreadPointer(*reg_info))
660 "no lldb regnum for %s",
661 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
663 UpdateXSTATEforWrite(reg_index);
665 if (IsGPR(reg_index) || IsDR(reg_index))
666 return WriteRegisterRaw(GetRegisterInfoIndex(reg_index), reg_value);
668 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
670 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
671 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
674 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
675 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
678 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
679 ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
682 if (reg_index >= m_reg_info.first_ymm &&
683 reg_index <= m_reg_info.last_ymm) {
686 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
688 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
692 if (reg_index >= m_reg_info.first_mpxr &&
693 reg_index <= m_reg_info.last_mpxr) {
694 ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
696 if (!CopyMPXtoXSTATE(reg_index))
700 if (reg_index >= m_reg_info.first_mpxc &&
701 reg_index <= m_reg_info.last_mpxc) {
702 ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
704 if (!CopyMPXtoXSTATE(reg_index))
719 assert((reg_info->
byte_offset - m_fctrl_offset_in_userarea) <
721 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->
byte_offset -
722 m_fctrl_offset_in_userarea;
724 if (dst ==
reinterpret_cast<uint8_t *
>(&m_xstate->fxsave.ftag))
741 assert(
false &&
"Unhandled data size.");
743 "unhandled register data size %" PRIu32, reg_info->
byte_size);
752 if (IsAVX(reg_index)) {
753 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
757 if (IsMPX(reg_index)) {
758 if (!CopyMPXtoXSTATE(reg_index))
764 "failed - register wasn't recognized to be a GPR or an FPR, "
765 "write strategy unknown");
768Status NativeRegisterContextLinux_x86::ReadAllRegisterValues(
781 uint8_t *dst = data_sp->GetBytes();
782 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
783 dst += GetRegisterInfoInterface().GetGPRSize();
784 if (m_xstate_type == XStateType::FXSAVE)
785 ::memcpy(dst, &m_xstate->fxsave,
sizeof(m_xstate->fxsave));
786 else if (m_xstate_type == XStateType::XSAVE) {
789 if (IsCPUFeatureAvailable(RegSet::avx)) {
791 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
793 if (!CopyXSTATEtoYMM(reg, byte_order)) {
795 "NativeRegisterContextLinux_x86::%s "
796 "CopyXSTATEtoYMM() failed for reg num "
804 if (IsCPUFeatureAvailable(RegSet::mpx)) {
805 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
807 if (!CopyXSTATEtoMPX(reg)) {
809 "NativeRegisterContextLinux_x86::%s "
810 "CopyXSTATEtoMPX() failed for reg num "
818 ::memcpy(dst, m_xstate.get(),
sizeof(
FPR));
820 assert(
false &&
"how do we save the floating point registers?");
822 "unsure how to save the floating point registers");
832 const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();
838Status NativeRegisterContextLinux_x86::WriteAllRegisterValues(
844 "NativeRegisterContextLinux_x86::%s invalid data_sp provided",
851 "data_sp contained mismatched data size, expected {0}, actual {1}",
856 const uint8_t *src = data_sp->GetBytes();
857 if (src ==
nullptr) {
859 "NativeRegisterContextLinux_x86::%s "
860 "DataBuffer::GetBytes() returned a null "
865 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
871 src += GetRegisterInfoInterface().GetGPRSize();
872 if (m_xstate_type == XStateType::FXSAVE)
873 ::memcpy(&m_xstate->fxsave, src,
sizeof(m_xstate->fxsave));
874 else if (m_xstate_type == XStateType::XSAVE)
875 ::memcpy(&m_xstate->xsave, src,
sizeof(m_xstate->xsave));
881 if (m_xstate_type == XStateType::XSAVE) {
884 if (IsCPUFeatureAvailable(RegSet::avx)) {
886 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
888 if (!CopyYMMtoXSTATE(reg, byte_order)) {
890 "NativeRegisterContextLinux_x86::%s "
891 "CopyYMMtoXSTATE() failed for reg num "
899 if (IsCPUFeatureAvailable(RegSet::mpx)) {
900 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
902 if (!CopyMPXtoXSTATE(reg)) {
904 "NativeRegisterContextLinux_x86::%s "
905 "CopyMPXtoXSTATE() failed for reg num "
917bool NativeRegisterContextLinux_x86::IsCPUFeatureAvailable(
918 RegSet feature_code)
const {
919 if (m_xstate_type == XStateType::Invalid) {
920 if (
const_cast<NativeRegisterContextLinux_x86 *
>(
this)->ReadFPR().Fail())
923 switch (feature_code) {
929 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
934 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
941bool NativeRegisterContextLinux_x86::IsRegisterSetAvailable(
942 uint32_t set_index)
const {
945 switch (
static_cast<RegSet
>(set_index)) {
948 return (set_index < num_sets);
950 return IsCPUFeatureAvailable(RegSet::avx);
952 return IsCPUFeatureAvailable(RegSet::mpx);
957bool NativeRegisterContextLinux_x86::IsGPR(uint32_t reg_index)
const {
959 return reg_index <= m_reg_info.last_gpr;
962bool NativeRegisterContextLinux_x86::IsFPR(uint32_t reg_index)
const {
963 return (m_reg_info.first_fpr <= reg_index &&
964 reg_index <= m_reg_info.last_fpr);
967bool NativeRegisterContextLinux_x86::IsDR(uint32_t reg_index)
const {
968 return (m_reg_info.first_dr <= reg_index &&
969 reg_index <= m_reg_info.last_dr);
972Status NativeRegisterContextLinux_x86::WriteFPR() {
973 switch (m_xstate_type) {
974 case XStateType::FXSAVE:
975 return WriteRegisterSet(
976 &m_iovec,
sizeof(m_xstate->fxsave),
977 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
978 case XStateType::XSAVE:
979 return WriteRegisterSet(&m_iovec,
sizeof(m_xstate->xsave), NT_X86_XSTATE);
985bool NativeRegisterContextLinux_x86::IsAVX(uint32_t reg_index)
const {
986 if (!IsCPUFeatureAvailable(RegSet::avx))
988 return (m_reg_info.first_ymm <= reg_index &&
989 reg_index <= m_reg_info.last_ymm);
992bool NativeRegisterContextLinux_x86::CopyXSTATEtoYMM(
994 if (!IsAVX(reg_index))
998 uint32_t reg_no = reg_index - m_reg_info.first_ymm;
1000 m_xstate->fxsave.xmm[reg_no].bytes,
1001 m_xstate->xsave.ymmh[reg_no].bytes);
1008bool NativeRegisterContextLinux_x86::CopyYMMtoXSTATE(
1014 uint32_t reg_no = reg - m_reg_info.first_ymm;
1016 m_xstate->fxsave.xmm[reg_no].bytes,
1017 m_xstate->xsave.ymmh[reg_no].bytes);
1024void *NativeRegisterContextLinux_x86::GetFPRBuffer() {
1025 switch (m_xstate_type) {
1026 case XStateType::FXSAVE:
1027 return &m_xstate->fxsave;
1028 case XStateType::XSAVE:
1035size_t NativeRegisterContextLinux_x86::GetFPRSize() {
1036 switch (m_xstate_type) {
1037 case XStateType::FXSAVE:
1038 return sizeof(m_xstate->fxsave);
1039 case XStateType::XSAVE:
1040 return sizeof(m_iovec);
1046Status NativeRegisterContextLinux_x86::ReadFPR() {
1050 if (m_xstate_type != XStateType::FXSAVE) {
1051 error = ReadRegisterSet(&m_iovec,
sizeof(m_xstate->xsave), NT_X86_XSTATE);
1052 if (!
error.Fail()) {
1053 m_xstate_type = XStateType::XSAVE;
1057 error = ReadRegisterSet(
1058 &m_iovec,
sizeof(m_xstate->xsave),
1059 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
1060 if (!
error.Fail()) {
1061 m_xstate_type = XStateType::FXSAVE;
1067bool NativeRegisterContextLinux_x86::IsMPX(uint32_t reg_index)
const {
1068 if (!IsCPUFeatureAvailable(RegSet::mpx))
1070 return (m_reg_info.first_mpxr <= reg_index &&
1071 reg_index <= m_reg_info.last_mpxc);
1074bool NativeRegisterContextLinux_x86::IsThreadPointer(
1076 return GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
1077 llvm::Triple::x86 &&
1082NativeRegisterContextLinux_x86::ReadThreadPointer(
RegisterValue ®_value) {
1097 "cannot read the i386 thread pointer from an LDT selector");
1099 const uintptr_t entry_number = gs >> 3;
1100 user_desc descriptor = {};
1102 PTRACE_GET_THREAD_AREA, m_thread.GetID(),
1103 reinterpret_cast<void *
>(entry_number), &descriptor,
sizeof(descriptor));
1107 reg_value.
SetUInt32(descriptor.base_addr);
1112NativeRegisterContextLinux_x86::GetRegisterInfoIndex(uint32_t lldb_reg)
const {
1114 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
1115 llvm::Triple::x86 &&
1116 lldb_reg >= k_i386_thread_pointer_index)
1117 return lldb_reg + 1;
1121bool NativeRegisterContextLinux_x86::CopyXSTATEtoMPX(uint32_t reg) {
1125 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1126 ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
1127 m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1130 ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
1131 m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1137bool NativeRegisterContextLinux_x86::CopyMPXtoXSTATE(uint32_t reg) {
1141 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1142 ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1143 m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
sizeof(
MPXReg));
1145 ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1146 m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
sizeof(
MPXCsr));
1152NativeRegisterContextLinux_x86::GetPtraceOffset(uint32_t reg_index) {
1154 return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1155 (IsMPX(reg_index) ? 128 : 0);
1158std::optional<NativeRegisterContextLinux::SyscallData>
1159NativeRegisterContextLinux_x86::GetSyscallData() {
1160 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1161 case llvm::Triple::x86: {
1162 static const uint8_t Int80[] = {0xcd, 0x80};
1168 case llvm::Triple::x86_64: {
1169 static const uint8_t Syscall[] = {0x0f, 0x05};
1170 static const uint32_t
Args[] = {
1176 llvm_unreachable(
"Unhandled architecture!");
1180std::optional<NativeRegisterContextLinux::MmapData>
1181NativeRegisterContextLinux_x86::GetMmapData() {
1182 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1183 case llvm::Triple::x86:
1184 return MmapData{192, 91};
1185 case llvm::Triple::x86_64:
1186 return MmapData{9, 11};
1188 llvm_unreachable(
"Unhandled architecture!");
1192const RegisterInfo *NativeRegisterContextLinux_x86::GetDR(
int num)
const {
1193 assert(num >= 0 && num <= 7);
1194 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1195 case llvm::Triple::x86:
1196 return GetRegisterInfoAtIndex(GetRegisterInfoIndex(
lldb_dr0_i386 + num));
1197 case llvm::Triple::x86_64:
1200 llvm_unreachable(
"Unhandled target architecture.");
static llvm::raw_ostream & error(Stream &strm)
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()
A subclass of DataBuffer that stores a data buffer on the heap.
uint32_t GetRegisterCount() const override
const RegisterInfo * GetRegisterInfoAtIndex(uint32_t reg_index) const override
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
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
}
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
#define LLDB_REGNUM_GENERIC_TP
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)
@ k_num_avx_registers_i386
@ k_num_fpr_registers_i386
@ k_num_mpx_registers_i386
@ k_num_gpr_registers_i386
@ eEncodingVector
vector registers
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ 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.