diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h --- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h +++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) #ifndef lldb_NativeRegisterContextNetBSD_x86_64_h #define lldb_NativeRegisterContextNetBSD_x86_64_h @@ -81,14 +81,19 @@ enum { GPRegSet, FPRegSet, XStateRegSet, DBRegSet }; // Private member variables. - struct reg m_gpr_x86_64; - struct fpreg m_fpr_x86_64; - struct dbreg m_dbr_x86_64; + struct reg m_gpr; +#if defined(__x86_64__) + struct fpreg m_fpr; +#else + struct xmmregs m_fpr; +#endif + struct dbreg m_dbr; #ifdef HAVE_XSTATE - struct xstate m_xstate_x86_64; + struct xstate m_xstate; #endif int GetSetForNativeRegNum(int reg_num) const; + int GetDR(int num) const; Status ReadRegisterSet(uint32_t set); Status WriteRegisterSet(uint32_t set); diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp --- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) #include "NativeRegisterContextNetBSD_x86_64.h" @@ -16,6 +16,7 @@ #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" +#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" // clang-format off @@ -135,9 +136,84 @@ k_num_dbr_registers_x86_64, "g_dbr_regnums_x86_64 has wrong number of register infos"); +// x86 32-bit general purpose registers. +const uint32_t g_gpr_regnums_i386[] = { + lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, + lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, + lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, + lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, + lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, + lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, + lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, + lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - + 1 == + k_num_gpr_registers_i386, + "g_gpr_regnums_i386 has wrong number of register infos"); + +// x86 32-bit floating point registers. +const uint32_t g_fpu_regnums_i386[] = { + lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, + lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, + lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, + lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, + lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, + lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, + lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, + lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, + lldb_xmm6_i386, lldb_xmm7_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - + 1 == + k_num_fpr_registers_i386, + "g_fpu_regnums_i386 has wrong number of register infos"); + +// x86 64-bit registers available via XState. +static const uint32_t g_xstate_regnums_i386[] = { + lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, + lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, + // Note: we currently do not provide them but this is needed to avoid + // unnamed groups in SBFrame::GetRegisterContext(). + lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, + lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) - + 1 == + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + "g_xstate_regnums_i386 has wrong number of register infos"); + +// x86 debug registers. +static const uint32_t g_dbr_regnums_i386[] = { + lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386, + lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) - + 1 == + k_num_dbr_registers_i386, + "g_dbr_regnums_i386 has wrong number of register infos"); + + // Number of register sets provided by this context. enum { k_num_register_sets = 4 }; +// Register sets for x86 32-bit. +static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, + g_gpr_regnums_i386}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, + g_fpu_regnums_i386}, + {"Extended State Registers", "xstate", + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + g_xstate_regnums_i386}, + {"Debug Registers", "dbr", k_num_dbr_registers_i386, + g_dbr_regnums_i386}, +}; + // Register sets for x86 64-bit. static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, @@ -164,18 +240,23 @@ static RegisterInfoInterface * CreateRegisterInfoInterface(const ArchSpec &target_arch) { - assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && - "Register setting path assumes this is a 64-bit host"); - // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 - // register context. - return new RegisterContextNetBSD_x86_64(target_arch); + if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) { + // 32-bit hosts run with a RegisterContextNetBSD_i386 context. + return new RegisterContextNetBSD_i386(target_arch); + } else { + assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && + "Register setting path assumes this is a 64-bit host"); + // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 + // register context. + return new RegisterContextNetBSD_x86_64(target_arch); + } } NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextNetBSD(native_thread, CreateRegisterInfoInterface(target_arch)), - m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {} + m_gpr(), m_fpr(), m_dbr() {} // CONSIDER after local and llgs debugging are merged, register set support can // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. @@ -192,6 +273,8 @@ const RegisterSet * NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const { switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return &g_reg_sets_i386[set_index]; case llvm::Triple::x86_64: return &g_reg_sets_x86_64[set_index]; default: @@ -202,36 +285,162 @@ return nullptr; } +static constexpr int RegNumX86ToX86_64(int regnum) { + switch (regnum) { + case lldb_eax_i386: + return lldb_rax_x86_64; + case lldb_ebx_i386: + return lldb_rbx_x86_64; + case lldb_ecx_i386: + return lldb_rcx_x86_64; + case lldb_edx_i386: + return lldb_rdx_x86_64; + case lldb_edi_i386: + return lldb_rdi_x86_64; + case lldb_esi_i386: + return lldb_rsi_x86_64; + case lldb_ebp_i386: + return lldb_rbp_x86_64; + case lldb_esp_i386: + return lldb_rsp_x86_64; + case lldb_eip_i386: + return lldb_rip_x86_64; + case lldb_eflags_i386: + return lldb_rflags_x86_64; + case lldb_cs_i386: + return lldb_cs_x86_64; + case lldb_fs_i386: + return lldb_fs_x86_64; + case lldb_gs_i386: + return lldb_gs_x86_64; + case lldb_ss_i386: + return lldb_ss_x86_64; + case lldb_ds_i386: + return lldb_ds_x86_64; + case lldb_es_i386: + return lldb_es_x86_64; + case lldb_fctrl_i386: + return lldb_fctrl_x86_64; + case lldb_fstat_i386: + return lldb_fstat_x86_64; + case lldb_ftag_i386: + return lldb_fstat_x86_64; + case lldb_fop_i386: + return lldb_fop_x86_64; + case lldb_fiseg_i386: + return lldb_fiseg_x86_64; + case lldb_fioff_i386: + return lldb_fioff_x86_64; + case lldb_foseg_i386: + return lldb_foseg_x86_64; + case lldb_fooff_i386: + return lldb_fooff_x86_64; + case lldb_mxcsr_i386: + return lldb_mxcsr_x86_64; + case lldb_mxcsrmask_i386: + return lldb_mxcsrmask_x86_64; + case lldb_st0_i386: + case lldb_st1_i386: + case lldb_st2_i386: + case lldb_st3_i386: + case lldb_st4_i386: + case lldb_st5_i386: + case lldb_st6_i386: + case lldb_st7_i386: + return lldb_st0_x86_64 + regnum - lldb_st0_i386; + case lldb_mm0_i386: + case lldb_mm1_i386: + case lldb_mm2_i386: + case lldb_mm3_i386: + case lldb_mm4_i386: + case lldb_mm5_i386: + case lldb_mm6_i386: + case lldb_mm7_i386: + return lldb_mm0_x86_64 + regnum - lldb_mm0_i386; + case lldb_xmm0_i386: + case lldb_xmm1_i386: + case lldb_xmm2_i386: + case lldb_xmm3_i386: + case lldb_xmm4_i386: + case lldb_xmm5_i386: + case lldb_xmm6_i386: + case lldb_xmm7_i386: + return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386; + case lldb_ymm0_i386: + case lldb_ymm1_i386: + case lldb_ymm2_i386: + case lldb_ymm3_i386: + case lldb_ymm4_i386: + case lldb_ymm5_i386: + case lldb_ymm6_i386: + case lldb_ymm7_i386: + return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386; + case lldb_dr0_i386: + case lldb_dr1_i386: + case lldb_dr2_i386: + case lldb_dr3_i386: + case lldb_dr4_i386: + case lldb_dr5_i386: + case lldb_dr6_i386: + case lldb_dr7_i386: + return lldb_dr0_x86_64 + regnum - lldb_dr0_i386; + default: + assert(false && "Unhandled i386 register."); + return 0; + } +} + int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum( int reg_num) const { - if (reg_num <= k_last_gpr_x86_64) - return GPRegSet; - else if (reg_num <= k_last_fpr_x86_64) - return FPRegSet; - else if (reg_num <= k_last_avx_x86_64) - return XStateRegSet; // AVX - else if (reg_num <= k_last_mpxr_x86_64) - return -1; // MPXR - else if (reg_num <= k_last_mpxc_x86_64) - return -1; // MPXC - else if (reg_num <= lldb_dr7_x86_64) - return DBRegSet; // DBR - else + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + if (reg_num <= k_last_gpr_i386) + return GPRegSet; + else if (reg_num <= k_last_fpr_i386) + return FPRegSet; + else if (reg_num <= k_last_avx_i386) + return XStateRegSet; // AVX + else if (reg_num <= lldb_dr7_i386) + return DBRegSet; // DBR + else + return -1; + case llvm::Triple::x86_64: + if (reg_num <= k_last_gpr_x86_64) + return GPRegSet; + else if (reg_num <= k_last_fpr_x86_64) + return FPRegSet; + else if (reg_num <= k_last_avx_x86_64) + return XStateRegSet; // AVX + else if (reg_num <= k_last_mpxr_x86_64) + return -1; // MPXR + else if (reg_num <= k_last_mpxc_x86_64) + return -1; // MPXC + else if (reg_num <= lldb_dr7_x86_64) + return DBRegSet; // DBR + else + return -1; + default: + assert(false && "Unhandled target architecture."); return -1; + } } Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) { switch (set) { case GPRegSet: - return DoRegisterSet(PT_GETREGS, &m_gpr_x86_64); + return DoRegisterSet(PT_GETREGS, &m_gpr); case FPRegSet: - return DoRegisterSet(PT_GETFPREGS, &m_fpr_x86_64); +#if defined(__x86_64__) + return DoRegisterSet(PT_GETFPREGS, &m_fpr); +#else + return DoRegisterSet(PT_GETXMMREGS, &m_fpr); +#endif case DBRegSet: - return DoRegisterSet(PT_GETDBREGS, &m_dbr_x86_64); + return DoRegisterSet(PT_GETDBREGS, &m_dbr); case XStateRegSet: #ifdef HAVE_XSTATE { - struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)}; + struct iovec iov = {&m_xstate, sizeof(m_xstate)}; return DoRegisterSet(PT_GETXSTATE, &iov); } #else @@ -244,15 +453,19 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) { switch (set) { case GPRegSet: - return DoRegisterSet(PT_SETREGS, &m_gpr_x86_64); + return DoRegisterSet(PT_SETREGS, &m_gpr); case FPRegSet: - return DoRegisterSet(PT_SETFPREGS, &m_fpr_x86_64); +#if defined(__x86_64__) + return DoRegisterSet(PT_SETFPREGS, &m_fpr); +#else + return DoRegisterSet(PT_SETXMMREGS, &m_fpr); +#endif case DBRegSet: - return DoRegisterSet(PT_SETDBREGS, &m_dbr_x86_64); + return DoRegisterSet(PT_SETDBREGS, &m_dbr); case XStateRegSet: #ifdef HAVE_XSTATE { - struct iovec iov = {&m_xstate_x86_64, sizeof(m_xstate_x86_64)}; + struct iovec iov = {&m_xstate, sizeof(m_xstate)}; return DoRegisterSet(PT_SETXSTATE, &iov); } #else @@ -272,7 +485,7 @@ return error; } - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) { // This is likely an internal register for lldb use only and should not be // directly queried. @@ -291,112 +504,175 @@ return error; } + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86_64: + break; + case llvm::Triple::x86: + reg = RegNumX86ToX86_64(reg); + break; + default: + assert(false && "Unhandled target architecture."); + error.SetErrorString("Unhandled target architecture."); + return error; + } + error = ReadRegisterSet(set); if (error.Fail()) return error; switch (reg) { +#if defined(__x86_64__) case lldb_rax_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RAX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RAX]; break; case lldb_rbx_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RBX]; break; case lldb_rcx_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RCX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RCX]; break; case lldb_rdx_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDX]; + reg_value = (uint64_t)m_gpr.regs[_REG_RDX]; break; case lldb_rdi_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RDI]; + reg_value = (uint64_t)m_gpr.regs[_REG_RDI]; break; case lldb_rsi_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSI]; + reg_value = (uint64_t)m_gpr.regs[_REG_RSI]; break; case lldb_rbp_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RBP]; + reg_value = (uint64_t)m_gpr.regs[_REG_RBP]; break; case lldb_rsp_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RSP]; + reg_value = (uint64_t)m_gpr.regs[_REG_RSP]; break; case lldb_r8_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R8]; + reg_value = (uint64_t)m_gpr.regs[_REG_R8]; break; case lldb_r9_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R9]; + reg_value = (uint64_t)m_gpr.regs[_REG_R9]; break; case lldb_r10_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R10]; + reg_value = (uint64_t)m_gpr.regs[_REG_R10]; break; case lldb_r11_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R11]; + reg_value = (uint64_t)m_gpr.regs[_REG_R11]; break; case lldb_r12_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R12]; + reg_value = (uint64_t)m_gpr.regs[_REG_R12]; break; case lldb_r13_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R13]; + reg_value = (uint64_t)m_gpr.regs[_REG_R13]; break; case lldb_r14_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R14]; + reg_value = (uint64_t)m_gpr.regs[_REG_R14]; break; case lldb_r15_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_R15]; + reg_value = (uint64_t)m_gpr.regs[_REG_R15]; break; case lldb_rip_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RIP]; + reg_value = (uint64_t)m_gpr.regs[_REG_RIP]; break; case lldb_rflags_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_RFLAGS]; + reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS]; break; case lldb_cs_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_CS]; + reg_value = (uint64_t)m_gpr.regs[_REG_CS]; break; case lldb_fs_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_FS]; + reg_value = (uint64_t)m_gpr.regs[_REG_FS]; break; case lldb_gs_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_GS]; + reg_value = (uint64_t)m_gpr.regs[_REG_GS]; break; case lldb_ss_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_SS]; + reg_value = (uint64_t)m_gpr.regs[_REG_SS]; break; case lldb_ds_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_DS]; + reg_value = (uint64_t)m_gpr.regs[_REG_DS]; break; case lldb_es_x86_64: - reg_value = (uint64_t)m_gpr_x86_64.regs[_REG_ES]; + reg_value = (uint64_t)m_gpr.regs[_REG_ES]; + break; +#else + case lldb_rax_x86_64: + reg_value = (uint32_t)m_gpr.r_eax; break; + case lldb_rbx_x86_64: + reg_value = (uint32_t)m_gpr.r_ebx; + break; + case lldb_rcx_x86_64: + reg_value = (uint32_t)m_gpr.r_ecx; + break; + case lldb_rdx_x86_64: + reg_value = (uint32_t)m_gpr.r_edx; + break; + case lldb_rdi_x86_64: + reg_value = (uint32_t)m_gpr.r_edi; + break; + case lldb_rsi_x86_64: + reg_value = (uint32_t)m_gpr.r_esi; + break; + case lldb_rsp_x86_64: + reg_value = (uint32_t)m_gpr.r_esp; + break; + case lldb_rbp_x86_64: + reg_value = (uint32_t)m_gpr.r_ebp; + break; + case lldb_rip_x86_64: + reg_value = (uint32_t)m_gpr.r_eip; + break; + case lldb_rflags_x86_64: + reg_value = (uint32_t)m_gpr.r_eflags; + break; + case lldb_cs_x86_64: + reg_value = (uint32_t)m_gpr.r_cs; + break; + case lldb_fs_x86_64: + reg_value = (uint32_t)m_gpr.r_fs; + break; + case lldb_gs_x86_64: + reg_value = (uint32_t)m_gpr.r_gs; + break; + case lldb_ss_x86_64: + reg_value = (uint32_t)m_gpr.r_ss; + break; + case lldb_ds_x86_64: + reg_value = (uint32_t)m_gpr.r_ds; + break; + case lldb_es_x86_64: + reg_value = (uint32_t)m_gpr.r_es; + break; +#endif case lldb_fctrl_x86_64: - reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_cw; + reg_value = (uint16_t)m_fpr.fxstate.fx_cw; break; case lldb_fstat_x86_64: - reg_value = (uint16_t)m_fpr_x86_64.fxstate.fx_sw; + reg_value = (uint16_t)m_fpr.fxstate.fx_sw; break; case lldb_ftag_x86_64: - reg_value = (uint8_t)m_fpr_x86_64.fxstate.fx_tw; + reg_value = (uint8_t)m_fpr.fxstate.fx_tw; break; case lldb_fop_x86_64: - reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_opcode; + reg_value = (uint64_t)m_fpr.fxstate.fx_opcode; break; case lldb_fiseg_x86_64: - reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_ip.fa_64; + reg_value = (uint64_t)m_fpr.fxstate.fx_ip.fa_64; break; case lldb_fioff_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off; + reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off; break; case lldb_foseg_x86_64: - reg_value = (uint64_t)m_fpr_x86_64.fxstate.fx_dp.fa_64; + reg_value = (uint64_t)m_fpr.fxstate.fx_dp.fa_64; break; case lldb_fooff_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off; + reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off; break; case lldb_mxcsr_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr; + reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr; break; case lldb_mxcsrmask_x86_64: - reg_value = (uint32_t)m_fpr_x86_64.fxstate.fx_mxcsr_mask; + reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask; break; case lldb_st0_x86_64: case lldb_st1_x86_64: @@ -406,7 +682,7 @@ case lldb_st5_x86_64: case lldb_st6_x86_64: case lldb_st7_x86_64: - reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64], + reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; case lldb_mm0_x86_64: @@ -417,7 +693,7 @@ case lldb_mm5_x86_64: case lldb_mm6_x86_64: case lldb_mm7_x86_64: - reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], + reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; case lldb_xmm0_x86_64: @@ -436,7 +712,7 @@ case lldb_xmm13_x86_64: case lldb_xmm14_x86_64: case lldb_xmm15_x86_64: - reg_value.SetBytes(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], + reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], reg_info->byte_size, endian::InlHostByteOrder()); break; case lldb_ymm0_x86_64: @@ -456,15 +732,15 @@ case lldb_ymm14_x86_64: case lldb_ymm15_x86_64: #ifdef HAVE_XSTATE - if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) || - !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) { + if (!(m_xstate.xs_rfbm & XCR0_SSE) || + !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", reg_info->name); } else { uint32_t reg_index = reg - lldb_ymm0_x86_64; YMMReg ymm = XStateToYMM( - m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes, - m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); + m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, + m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); reg_value.SetBytes(ymm.bytes, reg_info->byte_size, endian::InlHostByteOrder()); } @@ -480,7 +756,7 @@ case lldb_dr5_x86_64: case lldb_dr6_x86_64: case lldb_dr7_x86_64: - reg_value = (uint64_t)m_dbr_x86_64.dr[reg - lldb_dr0_x86_64]; + reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64]; break; } @@ -497,7 +773,7 @@ return error; } - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) { // This is likely an internal register for lldb use only and should not be // directly queried. @@ -516,112 +792,175 @@ return error; } + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86_64: + break; + case llvm::Triple::x86: + reg = RegNumX86ToX86_64(reg); + break; + default: + assert(false && "Unhandled target architecture."); + error.SetErrorString("Unhandled target architecture."); + return error; + } + error = ReadRegisterSet(set); if (error.Fail()) return error; switch (reg) { +#if defined(__x86_64__) case lldb_rax_x86_64: - m_gpr_x86_64.regs[_REG_RAX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64(); break; case lldb_rbx_x86_64: - m_gpr_x86_64.regs[_REG_RBX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64(); break; case lldb_rcx_x86_64: - m_gpr_x86_64.regs[_REG_RCX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64(); break; case lldb_rdx_x86_64: - m_gpr_x86_64.regs[_REG_RDX] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64(); break; case lldb_rdi_x86_64: - m_gpr_x86_64.regs[_REG_RDI] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64(); break; case lldb_rsi_x86_64: - m_gpr_x86_64.regs[_REG_RSI] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64(); break; case lldb_rbp_x86_64: - m_gpr_x86_64.regs[_REG_RBP] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64(); break; case lldb_rsp_x86_64: - m_gpr_x86_64.regs[_REG_RSP] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64(); break; case lldb_r8_x86_64: - m_gpr_x86_64.regs[_REG_R8] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64(); break; case lldb_r9_x86_64: - m_gpr_x86_64.regs[_REG_R9] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64(); break; case lldb_r10_x86_64: - m_gpr_x86_64.regs[_REG_R10] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64(); break; case lldb_r11_x86_64: - m_gpr_x86_64.regs[_REG_R11] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64(); break; case lldb_r12_x86_64: - m_gpr_x86_64.regs[_REG_R12] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64(); break; case lldb_r13_x86_64: - m_gpr_x86_64.regs[_REG_R13] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64(); break; case lldb_r14_x86_64: - m_gpr_x86_64.regs[_REG_R14] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64(); break; case lldb_r15_x86_64: - m_gpr_x86_64.regs[_REG_R15] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64(); break; case lldb_rip_x86_64: - m_gpr_x86_64.regs[_REG_RIP] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64(); break; case lldb_rflags_x86_64: - m_gpr_x86_64.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64(); break; case lldb_cs_x86_64: - m_gpr_x86_64.regs[_REG_CS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64(); break; case lldb_fs_x86_64: - m_gpr_x86_64.regs[_REG_FS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64(); break; case lldb_gs_x86_64: - m_gpr_x86_64.regs[_REG_GS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64(); break; case lldb_ss_x86_64: - m_gpr_x86_64.regs[_REG_SS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64(); break; case lldb_ds_x86_64: - m_gpr_x86_64.regs[_REG_DS] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64(); break; case lldb_es_x86_64: - m_gpr_x86_64.regs[_REG_ES] = reg_value.GetAsUInt64(); + m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64(); break; +#else + case lldb_rax_x86_64: + m_gpr.r_eax = reg_value.GetAsUInt32(); + break; + case lldb_rbx_x86_64: + m_gpr.r_ebx = reg_value.GetAsUInt32(); + break; + case lldb_rcx_x86_64: + m_gpr.r_ecx = reg_value.GetAsUInt32(); + break; + case lldb_rdx_x86_64: + m_gpr.r_edx = reg_value.GetAsUInt32(); + break; + case lldb_rdi_x86_64: + m_gpr.r_edi = reg_value.GetAsUInt32(); + break; + case lldb_rsi_x86_64: + m_gpr.r_esi = reg_value.GetAsUInt32(); + break; + case lldb_rsp_x86_64: + m_gpr.r_esp = reg_value.GetAsUInt32(); + break; + case lldb_rbp_x86_64: + m_gpr.r_ebp = reg_value.GetAsUInt32(); + break; + case lldb_rip_x86_64: + m_gpr.r_eip = reg_value.GetAsUInt32(); + break; + case lldb_rflags_x86_64: + m_gpr.r_eflags = reg_value.GetAsUInt32(); + break; + case lldb_cs_x86_64: + m_gpr.r_cs = reg_value.GetAsUInt32(); + break; + case lldb_fs_x86_64: + m_gpr.r_fs = reg_value.GetAsUInt32(); + break; + case lldb_gs_x86_64: + m_gpr.r_gs = reg_value.GetAsUInt32(); + break; + case lldb_ss_x86_64: + m_gpr.r_ss = reg_value.GetAsUInt32(); + break; + case lldb_ds_x86_64: + m_gpr.r_ds = reg_value.GetAsUInt32(); + break; + case lldb_es_x86_64: + m_gpr.r_es = reg_value.GetAsUInt32(); + break; +#endif case lldb_fctrl_x86_64: - m_fpr_x86_64.fxstate.fx_cw = reg_value.GetAsUInt16(); + m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16(); break; case lldb_fstat_x86_64: - m_fpr_x86_64.fxstate.fx_sw = reg_value.GetAsUInt16(); + m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16(); break; case lldb_ftag_x86_64: - m_fpr_x86_64.fxstate.fx_tw = reg_value.GetAsUInt8(); + m_fpr.fxstate.fx_tw = reg_value.GetAsUInt8(); break; case lldb_fop_x86_64: - m_fpr_x86_64.fxstate.fx_opcode = reg_value.GetAsUInt16(); + m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16(); break; case lldb_fiseg_x86_64: - m_fpr_x86_64.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64(); + m_fpr.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64(); break; case lldb_fioff_x86_64: - m_fpr_x86_64.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); break; case lldb_foseg_x86_64: - m_fpr_x86_64.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64(); + m_fpr.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64(); break; case lldb_fooff_x86_64: - m_fpr_x86_64.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); break; case lldb_mxcsr_x86_64: - m_fpr_x86_64.fxstate.fx_mxcsr = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32(); break; case lldb_mxcsrmask_x86_64: - m_fpr_x86_64.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32(); + m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32(); break; case lldb_st0_x86_64: case lldb_st1_x86_64: @@ -631,7 +970,7 @@ case lldb_st5_x86_64: case lldb_st6_x86_64: case lldb_st7_x86_64: - ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_st0_x86_64], + ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; case lldb_mm0_x86_64: @@ -642,7 +981,7 @@ case lldb_mm5_x86_64: case lldb_mm6_x86_64: case lldb_mm7_x86_64: - ::memcpy(&m_fpr_x86_64.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], + ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; case lldb_xmm0_x86_64: @@ -661,7 +1000,7 @@ case lldb_xmm13_x86_64: case lldb_xmm14_x86_64: case lldb_xmm15_x86_64: - ::memcpy(&m_fpr_x86_64.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], + ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64], reg_value.GetBytes(), reg_value.GetByteSize()); break; case lldb_ymm0_x86_64: @@ -681,8 +1020,8 @@ case lldb_ymm14_x86_64: case lldb_ymm15_x86_64: #ifdef HAVE_XSTATE - if (!(m_xstate_x86_64.xs_rfbm & XCR0_SSE) || - !(m_xstate_x86_64.xs_rfbm & XCR0_YMM_Hi128)) { + if (!(m_xstate.xs_rfbm & XCR0_SSE) || + !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) { error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel", reg_info->name); } else { @@ -690,8 +1029,8 @@ YMMReg ymm; ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize()); YMMToXState(ymm, - m_xstate_x86_64.xs_fxsave.fx_xmm[reg_index].xmm_bytes, - m_xstate_x86_64.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); + m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes, + m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes); } #else error.SetErrorString("XState not supported by the kernel"); @@ -705,7 +1044,7 @@ case lldb_dr5_x86_64: case lldb_dr6_x86_64: case lldb_dr7_x86_64: - m_dbr_x86_64.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64(); + m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64(); break; } @@ -722,7 +1061,7 @@ return error; uint8_t *dst = data_sp->GetBytes(); - ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); + ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize()); dst += GetRegisterInfoInterface().GetGPRSize(); return error; @@ -742,7 +1081,7 @@ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { error.SetErrorStringWithFormat( "NativeRegisterContextNetBSD_x86_64::%s data_sp contained mismatched " - "data size, expected %" PRIu64 ", actual %" PRIu64, + "data size, expected %zu, actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); return error; } @@ -755,7 +1094,7 @@ __FUNCTION__); return error; } - ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize()); + ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize()); error = WriteRegisterSet(GPRegSet); if (error.Fail()) @@ -765,13 +1104,25 @@ return error; } +int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const { + assert(num >= 0 && num <= 7); + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return lldb_dr0_i386 + num; + case llvm::Triple::x86_64: + return lldb_dr0_x86_64 + num; + default: + return -1; + } +} + Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit) { if (wp_index >= NumSupportedHardwareWatchpoints()) return Status("Watchpoint index out of range"); RegisterValue reg_value; - const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr6_x86_64); + const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6)); Status error = ReadRegister(reg_info, reg_value); if (error.Fail()) { is_hit = false; @@ -808,7 +1159,7 @@ return Status("Watchpoint index out of range"); RegisterValue reg_value; - const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7)); Status error = ReadRegister(reg_info, reg_value); if (error.Fail()) { is_vacant = false; @@ -848,8 +1199,7 @@ if (!is_vacant) return Status("Watchpoint index not vacant"); - const RegisterInfo *const reg_info_dr7 = - GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); RegisterValue dr7_value; error = ReadRegister(reg_info_dr7, dr7_value); if (error.Fail()) @@ -874,7 +1224,7 @@ control_bits |= enable_bit | rw_bits | size_bits; const RegisterInfo *const reg_info_drN = - GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index); + GetRegisterInfoAtIndex(GetDR(wp_index)); RegisterValue drN_value; error = ReadRegister(reg_info_drN, drN_value); if (error.Fail()) @@ -906,8 +1256,7 @@ // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5 // or 6-7 of the debug control register (DR7) - const RegisterInfo *const reg_info_dr7 = - GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); RegisterValue reg_value; Status error = ReadRegister(reg_info_dr7, reg_value); if (error.Fail()) @@ -924,8 +1273,7 @@ // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of // the debug status register (DR6) - const RegisterInfo *const reg_info_dr6 = - GetRegisterInfoAtIndex(lldb_dr6_x86_64); + const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); RegisterValue reg_value; Status error = ReadRegister(reg_info_dr6, reg_value); if (error.Fail()) @@ -940,8 +1288,7 @@ RegisterValue reg_value; // clear bits {0-4} of the debug status register (DR6) - const RegisterInfo *const reg_info_dr6 = - GetRegisterInfoAtIndex(lldb_dr6_x86_64); + const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6)); Status error = ReadRegister(reg_info_dr6, reg_value); if (error.Fail()) return error; @@ -952,8 +1299,7 @@ return error; // clear bits {0-7,16-31} of the debug control register (DR7) - const RegisterInfo *const reg_info_dr7 = - GetRegisterInfoAtIndex(lldb_dr7_x86_64); + const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7)); error = ReadRegister(reg_info_dr7, reg_value); if (error.Fail()) return error; @@ -988,7 +1334,7 @@ return LLDB_INVALID_ADDRESS; RegisterValue reg_value; const RegisterInfo *const reg_info_drN = - GetRegisterInfoAtIndex(lldb_dr0_x86_64 + wp_index); + GetRegisterInfoAtIndex(GetDR(wp_index)); if (ReadRegister(reg_info_drN, reg_value).Fail()) return LLDB_INVALID_ADDRESS; return reg_value.GetAsUInt64(); @@ -1005,10 +1351,10 @@ Status res = r_source.ReadRegisterSet(DBRegSet); if (!res.Fail()) { // copy dbregs only if any watchpoints were set - if ((r_source.m_dbr_x86_64.dr[7] & 0xFF) == 0) + if ((r_source.m_dbr.dr[7] & 0xFF) == 0) return res; - m_dbr_x86_64 = r_source.m_dbr_x86_64; + m_dbr = r_source.m_dbr; res = WriteRegisterSet(DBRegSet); } return res; diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt --- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -32,6 +32,7 @@ RegisterContextMach_i386.cpp RegisterContextMach_x86_64.cpp RegisterContextMemory.cpp + RegisterContextNetBSD_i386.cpp RegisterContextNetBSD_x86_64.cpp RegisterContextOpenBSD_i386.cpp RegisterContextOpenBSD_x86_64.cpp diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.h @@ -0,0 +1,25 @@ +//===-- RegisterContextNetBSD_i386.h ----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextNetBSD_i386_H_ +#define liblldb_RegisterContextNetBSD_i386_H_ + +#include "RegisterInfoInterface.h" + +class RegisterContextNetBSD_i386 : public lldb_private::RegisterInfoInterface { +public: + RegisterContextNetBSD_i386(const lldb_private::ArchSpec &target_arch); + + size_t GetGPRSize() const override; + + const lldb_private::RegisterInfo *GetRegisterInfo() const override; + + uint32_t GetRegisterCount() const override; +}; + +#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_i386.cpp @@ -0,0 +1,96 @@ +//===-- RegisterContextNetBSD_i386.cpp -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "RegisterContextNetBSD_i386.h" +#include "RegisterContextPOSIX_x86.h" + +using namespace lldb_private; +using namespace lldb; + +// this needs to match 'struct reg' +struct GPR { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t gs; +}; + +struct FPR_i386 { + uint16_t fctrl; // FPU Control Word (fcw) + uint16_t fstat; // FPU Status Word (fsw) + uint16_t ftag; // FPU Tag Word (ftw) + uint16_t fop; // Last Instruction Opcode (fop) + union { + struct { + uint64_t fip; // Instruction Pointer + uint64_t fdp; // Data Pointer + } x86_64; + struct { + uint32_t fioff; // FPU IP Offset (fip) + uint32_t fiseg; // FPU IP Selector (fcs) + uint32_t fooff; // FPU Operand Pointer Offset (foo) + uint32_t foseg; // FPU Operand Pointer Selector (fos) + } i386_; // Added _ in the end to avoid error with gcc defining i386 in some + // cases + } ptr; + uint32_t mxcsr; // MXCSR Register State + uint32_t mxcsrmask; // MXCSR Mask + MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes + XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes + uint32_t padding[56]; +}; + +struct UserArea { + GPR gpr; + FPR_i386 i387; + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). + uint32_t tlsbase; +}; + +#define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0]) +#define DR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index])) + +// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. +#define DECLARE_REGISTER_INFOS_I386_STRUCT +#include "RegisterInfos_i386.h" +#undef DECLARE_REGISTER_INFOS_I386_STRUCT + +RegisterContextNetBSD_i386::RegisterContextNetBSD_i386( + const ArchSpec &target_arch) + : RegisterInfoInterface(target_arch) {} + +size_t RegisterContextNetBSD_i386::GetGPRSize() const { return sizeof(GPR); } + +const RegisterInfo *RegisterContextNetBSD_i386::GetRegisterInfo() const { + switch (m_target_arch.GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return g_register_infos_i386; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } +} + +uint32_t RegisterContextNetBSD_i386::GetRegisterCount() const { + return static_cast(sizeof(g_register_infos_i386) / + sizeof(g_register_infos_i386[0])); +} diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -145,7 +145,7 @@ DR_OFFSET(i), eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ - LLDB_INVALID_REGNUM }, \ + lldb_##reg##i##_i386 }, \ nullptr, nullptr, nullptr, 0 \ } diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h --- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -113,7 +113,8 @@ lldb_bndstatus_i386, k_last_mpxc_i386 = lldb_bndstatus_i386, - lldb_dr0_i386, + k_first_dbr_i386, + lldb_dr0_i386 = k_first_dbr_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386, @@ -121,6 +122,7 @@ lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386, + k_last_dbr_i386 = lldb_dr7_i386, k_num_registers_i386, k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, @@ -131,6 +133,7 @@ k_num_fpr_registers_i386 + k_num_avx_registers_i386 + k_num_mpx_registers_i386, + k_num_dbr_registers_i386 = k_last_dbr_i386 - k_first_dbr_i386 + 1, }; // Internal codes for all x86_64 registers.