diff options
| author | Valentina Giusti <valentina.giusti@intel.com> | 2016-09-08 14:16:45 +0000 |
|---|---|---|
| committer | Valentina Giusti <valentina.giusti@intel.com> | 2016-09-08 14:16:45 +0000 |
| commit | cda0ae46ac9b368ee7cbb0da5aa447563dec0aae (patch) | |
| tree | 6c509d4f4177d7f0e36df592219884b079561915 /lldb/source | |
| parent | 4d1e4d76ee4636b6605e6d119322b767efc93b70 (diff) | |
| download | bcm5719-llvm-cda0ae46ac9b368ee7cbb0da5aa447563dec0aae.tar.gz bcm5719-llvm-cda0ae46ac9b368ee7cbb0da5aa447563dec0aae.zip | |
Fix for rL280668, Intel(R) Memory Protection Extensions (Intel(R) MPX) support.
Summary: Signed-off-by: Valentina Giusti <valentina.giusti@intel.com>
Reviewers: dvlahovski, granata.enrico, clayborg, labath
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D24255
llvm-svn: 280942
Diffstat (limited to 'lldb/source')
10 files changed, 467 insertions, 17 deletions
diff --git a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp index 30a9289437c..64376908e05 100755 --- a/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp +++ b/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp @@ -104,7 +104,12 @@ enum dwarf_regnums { dwarf_mm4, dwarf_mm5, dwarf_mm6, - dwarf_mm7 + dwarf_mm7, + + dwarf_bnd0 = 101, + dwarf_bnd1, + dwarf_bnd2, + dwarf_bnd3 }; static RegisterInfo g_register_infos[] = { @@ -703,6 +708,78 @@ static RegisterInfo g_register_infos[] = { nullptr, nullptr, nullptr, + 0}, + {"bnd0", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM }, + nullptr, + nullptr, + nullptr, + 0}, + {"bnd1", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM }, + nullptr, + nullptr, + nullptr, + 0}, + {"bnd2", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM }, + nullptr, + nullptr, + nullptr, + 0}, + {"bnd3", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM }, + nullptr, + nullptr, + nullptr, + 0}, + {"bndcfgu", + nullptr, + 8, + 0, + eEncodingVector, + eFormatVectorOfUInt8, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bndstatus", + nullptr, + 8, + 0, + eEncodingVector, + eFormatVectorOfUInt8, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, 0}}; static const uint32_t k_num_register_infos = diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index caa4aec1b43..01681a54ebc 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -94,7 +94,11 @@ enum dwarf_regnums { dwarf_ymm12, dwarf_ymm13, dwarf_ymm14, - dwarf_ymm15 + dwarf_ymm15, + dwarf_bnd0 = 126, + dwarf_bnd1, + dwarf_bnd2, + dwarf_bnd3 }; static RegisterInfo g_register_infos[] = { @@ -979,6 +983,78 @@ static RegisterInfo g_register_infos[] = { nullptr, nullptr, nullptr, + 0}, + {"bnd0", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bnd1", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bnd2", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bnd3", + nullptr, + 16, + 0, + eEncodingVector, + eFormatVectorOfUInt64, + {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bndcfgu", + nullptr, + 8, + 0, + eEncodingVector, + eFormatVectorOfUInt8, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + 0}, + {"bndstatus", + nullptr, + 8, + 0, + eEncodingVector, + eFormatVectorOfUInt8, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, 0}}; static const uint32_t k_num_register_infos = diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp index 369a8033a62..e7ae1f721ef 100755 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -74,6 +74,17 @@ static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - k_num_avx_registers_i386, " g_avx_regnums_i386 has wrong number of register infos"); +// x64 32-bit MPX registers. +static const uint32_t g_mpx_regnums_i386[] = { + 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_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) - + 1 == + k_num_mpx_registers_i386, + "g_mpx_regnums_x86_64 has wrong number of register infos"); + // x86 64-bit general purpose registers. static const uint32_t g_gpr_regnums_x86_64[] = { lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64, @@ -156,8 +167,19 @@ static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - k_num_avx_registers_x86_64, "g_avx_regnums_x86_64 has wrong number of register infos"); +// x86 64-bit MPX registers. +static const uint32_t g_mpx_regnums_x86_64[] = { + lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64, + lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) - + 1 == + k_num_mpx_registers_x86_64, + "g_mpx_regnums_x86_64 has wrong number of register infos"); + // Number of register sets provided by this context. -enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 }; +enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 }; // Register sets for x86 32-bit. static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { @@ -166,7 +188,9 @@ static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386}, {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, - g_avx_regnums_i386}}; + g_avx_regnums_i386}, + { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386, + g_mpx_regnums_i386}}; // Register sets for x86 64-bit. static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { @@ -175,7 +199,9 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64}, {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, - g_avx_regnums_x86_64}}; + g_avx_regnums_x86_64}, + { "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64, + g_mpx_regnums_x86_64}}; } #define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR)) @@ -224,7 +250,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( : NativeRegisterContextLinux(native_thread, concrete_frame_idx, CreateRegisterInfoInterface(target_arch)), m_fpr_type(eFPRTypeNotValid), m_fpr(), m_iovec(), m_ymm_set(), - m_reg_info(), m_gpr_x86_64() { + m_mpx_set(), m_reg_info(), m_gpr_x86_64() { // Set up data about ranges of valid registers. switch (target_arch.GetMachine()) { case llvm::Triple::x86: @@ -232,6 +258,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( m_reg_info.num_gpr_registers = k_num_gpr_registers_i386; m_reg_info.num_fpr_registers = k_num_fpr_registers_i386; m_reg_info.num_avx_registers = k_num_avx_registers_i386; + m_reg_info.num_mpx_registers = k_num_mpx_registers_i386; m_reg_info.last_gpr = k_last_gpr_i386; m_reg_info.first_fpr = k_first_fpr_i386; m_reg_info.last_fpr = k_last_fpr_i386; @@ -243,6 +270,10 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( m_reg_info.last_xmm = lldb_xmm7_i386; m_reg_info.first_ymm = lldb_ymm0_i386; m_reg_info.last_ymm = lldb_ymm7_i386; + m_reg_info.first_mpxr = lldb_bnd0_i386; + m_reg_info.last_mpxr = lldb_bnd3_i386; + m_reg_info.first_mpxc = lldb_bndcfgu_i386; + m_reg_info.last_mpxc = lldb_bndstatus_i386; m_reg_info.first_dr = lldb_dr0_i386; m_reg_info.gpr_flags = lldb_eflags_i386; break; @@ -251,6 +282,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64; m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64; m_reg_info.num_avx_registers = k_num_avx_registers_x86_64; + m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64; m_reg_info.last_gpr = k_last_gpr_x86_64; m_reg_info.first_fpr = k_first_fpr_x86_64; m_reg_info.last_fpr = k_last_fpr_x86_64; @@ -262,6 +294,10 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( m_reg_info.last_xmm = lldb_xmm15_x86_64; m_reg_info.first_ymm = lldb_ymm0_x86_64; m_reg_info.last_ymm = lldb_ymm15_x86_64; + m_reg_info.first_mpxr = lldb_bnd0_x86_64; + m_reg_info.last_mpxr = lldb_bnd3_x86_64; + m_reg_info.first_mpxc = lldb_bndcfgu_x86_64; + m_reg_info.last_mpxc = lldb_bndstatus_x86_64; m_reg_info.first_dr = lldb_dr0_x86_64; m_reg_info.gpr_flags = lldb_rflags_x86_64; break; @@ -400,6 +436,24 @@ Error NativeRegisterContextLinux_x86_64::ReadRegister( return error; } } + if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { + if (GetFPRType() == eFPRTypeXSAVE && CopyXSTATEtoMPX(reg)) + reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, + reg_info->byte_size, byte_order); + else { + error.SetErrorString("failed to copy mpx register value"); + return error; + } + } + if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) { + if (GetFPRType() == eFPRTypeXSAVE && CopyXSTATEtoMPX(reg)) + reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, + reg_info->byte_size, byte_order); + else { + error.SetErrorString("failed to copy mpx register value"); + return error; + } + } if (reg_value.GetType() != RegisterValue::eTypeBytes) error.SetErrorString( @@ -492,6 +546,28 @@ Error NativeRegisterContextLinux_x86_64::WriteRegister( if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) return Error("CopyYMMtoXSTATE() failed"); } + + if (reg_index >= m_reg_info.first_mpxr && + reg_index <= m_reg_info.last_mpxr) { + if (GetFPRType() != eFPRTypeXSAVE) + return Error("target processor does not support MPX"); + + ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes, + reg_value.GetBytes(), reg_value.GetByteSize()); + if (!CopyMPXtoXSTATE(reg_index)) + return Error("CopyMPXtoXSTATE() failed"); + } + + if (reg_index >= m_reg_info.first_mpxc && + reg_index <= m_reg_info.last_mpxc) { + if (GetFPRType() != eFPRTypeXSAVE) + return Error("target processor does not support MPX"); + + ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes, + reg_value.GetBytes(), reg_value.GetByteSize()); + if (!CopyMPXtoXSTATE(reg_index)) + return Error("CopyMPXtoXSTATE() failed"); + } } else { // Get pointer to m_fpr.xstate.fxsave variable and set the data to it. @@ -537,6 +613,11 @@ Error NativeRegisterContextLinux_x86_64::WriteRegister( if (!CopyYMMtoXSTATE(reg_index, GetByteOrder())) return Error("CopyYMMtoXSTATE() failed"); } + + if (IsMPX(reg_index)) { + if (!CopyMPXtoXSTATE(reg_index)) + return Error("CopyMPXtoXSTATE() failed"); + } return Error(); } return Error("failed - register wasn't recognized to be a GPR or an FPR, " @@ -590,6 +671,16 @@ Error NativeRegisterContextLinux_x86_64::ReadAllRegisterValues( } } + for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc; + ++reg) { + if (!CopyXSTATEtoMPX(reg)) { + error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s " + "CopyXSTATEtoMPX() failed for reg num " + "%" PRIu32, + __FUNCTION__, reg); + return error; + } + } // Copy the extended register state including the assembled ymm registers. ::memcpy(dst, &m_fpr, sizeof(m_fpr)); } else { @@ -672,6 +763,17 @@ Error NativeRegisterContextLinux_x86_64::WriteAllRegisterValues( return error; } } + + for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc; + ++reg) { + if (!CopyMPXtoXSTATE(reg)) { + error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s " + "CopyMPXtoXSTATE() failed for reg num " + "%" PRIu32, + __FUNCTION__, reg); + return error; + } + } } return error; @@ -684,7 +786,7 @@ bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable( if (GetFPRType() == eFPRTypeXSAVE) { // AVX is the first extended register set. - ++num_sets; + num_sets += 2; } return (set_index < num_sets); } @@ -732,7 +834,7 @@ bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, bool generic_fpr = IsFPR(reg_index); if (fpr_type == eFPRTypeXSAVE) - return generic_fpr || IsAVX(reg_index); + return generic_fpr || IsAVX(reg_index) || IsMPX(reg_index); return generic_fpr; } @@ -873,6 +975,41 @@ Error NativeRegisterContextLinux_x86_64::ReadFPR() { } } +bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const { + return (m_reg_info.first_mpxr <= reg_index && + reg_index <= m_reg_info.last_mpxc); +} + +bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) { + if (!IsMPX(reg)) + return false; + + if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { + ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, + m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, + sizeof(MPXReg)); + } else { + ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, + m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, + sizeof(MPXCsr)); + } + return true; +} + +bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) { + if (!IsMPX(reg)) + return false; + + if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { + ::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, + m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg)); + } else { + ::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, + m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr)); + } + return true; +} + Error NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index, bool &is_hit) { if (wp_index >= NumSupportedHardwareWatchpoints()) diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h index 2378c771c62..21f548a95de 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h @@ -85,11 +85,10 @@ private: uint32_t num_gpr_registers; uint32_t num_fpr_registers; uint32_t num_avx_registers; - + uint32_t num_mpx_registers; uint32_t last_gpr; uint32_t first_fpr; uint32_t last_fpr; - uint32_t first_st; uint32_t last_st; uint32_t first_mm; @@ -98,7 +97,10 @@ private: uint32_t last_xmm; uint32_t first_ymm; uint32_t last_ymm; - + uint32_t first_mpxr; + uint32_t last_mpxr; + uint32_t first_mpxc; + uint32_t last_mpxc; uint32_t first_dr; uint32_t gpr_flags; }; @@ -108,6 +110,7 @@ private: FPR m_fpr; IOVEC m_iovec; YMM m_ymm_set; + MPX m_mpx_set; RegInfo m_reg_info; uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64]; uint32_t m_fctrl_offset_in_userarea; @@ -128,6 +131,12 @@ private: bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order); bool IsAVX(uint32_t reg_index) const; + + bool CopyXSTATEtoMPX(uint32_t reg); + + bool CopyMPXtoXSTATE(uint32_t reg); + + bool IsMPX(uint32_t reg_index) const; }; } // namespace process_linux diff --git a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h index 87212e1c099..2dcc43ed4fc 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -120,10 +120,14 @@ enum { dwarf_ss_i386 = 42, dwarf_ds_i386 = 43, dwarf_fs_i386 = 44, - dwarf_gs_i386 = 45 + dwarf_gs_i386 = 45, // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and // then differentiate based on size of the register. + dwarf_bnd0_i386 = 101, + dwarf_bnd1_i386, + dwarf_bnd2_i386, + dwarf_bnd3_i386, }; //--------------------------------------------------------------------------- @@ -220,6 +224,11 @@ enum { dwarf_ymm13h_x86_64, dwarf_ymm14h_x86_64, dwarf_ymm15h_x86_64, + // MPX registers + dwarf_bnd0_x86_64 = 126, + dwarf_bnd1_x86_64, + dwarf_bnd2_x86_64, + dwarf_bnd3_x86_64, // AVX2 Vector Mask Registers // dwarf_k0_x86_64 = 118, // dwarf_k1_x86_64, @@ -287,16 +296,32 @@ struct YMM { YMMReg ymm[16]; // assembled from ymmh and xmm registers }; +struct MPXReg { + uint8_t bytes[16]; // MPX 128 bit bound registers +}; + +struct MPXCsr { + uint8_t bytes[8]; // MPX 64 bit bndcfgu and bndstatus registers (collectively + // BNDCSR state) +}; + +struct MPX { + MPXReg mpxr[4]; + MPXCsr mpxc[2]; +}; + LLVM_PACKED_START struct XSAVE_HDR { uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states // supported by the processor - uint64_t reserved1[2]; + uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of + // the XRSTOR instruction + uint64_t reserved1[1]; uint64_t reserved2[5]; }; LLVM_PACKED_END -// x86 extensions to FXSAVE (i.e. for AVX processors) +// x86 extensions to FXSAVE (i.e. for AVX and MPX processors) LLVM_PACKED_START struct LLVM_ALIGNAS(64) XSAVE { FXSAVE i387; // floating point registers typical in i387_fxsave_struct @@ -304,7 +329,10 @@ struct LLVM_ALIGNAS(64) XSAVE { // following extensions are usable YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes // are in FXSAVE.xmm for compatibility with SSE) - // Slot any extensions to the register file here + uint64_t reserved3[16]; + MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers + MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and + // BNDSTATUS registers }; LLVM_PACKED_END diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index 1b3dad8a22a..e7cca48b767 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -34,6 +34,16 @@ LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \ (32 * reg_index)) +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, i387) + \ + LLVM_EXTENSION offsetof(FPR, xstate) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index])) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, i387) + \ + LLVM_EXTENSION offsetof(FPR, xstate) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index])) + // Number of bytes needed to represent a FPR. #if !defined(FPR_SIZE) #define FPR_SIZE(reg) sizeof(((FXSAVE *)NULL)->reg) @@ -48,6 +58,10 @@ // Number of bytes needed to represent a YMM register. #define YMM_SIZE sizeof(YMMReg) +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + // Note that the size and offset will be updated by platform-specific classes. #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { \ @@ -111,6 +125,25 @@ NULL, NULL, NULL, 0 \ } +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, NULL, BNDR_SIZE, \ + LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ + NULL, NULL \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, NULL, BNDC_SIZE, \ + LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \ + NULL, NULL \ + } + #define DEFINE_DR(reg, i) \ { \ #reg #i, NULL, DR_SIZE, \ @@ -236,6 +269,15 @@ static RegisterInfo g_register_infos_i386[] = { DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + // Debug registers for lldb internal use DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; @@ -256,6 +298,8 @@ static_assert((sizeof(g_register_infos_i386) / #undef DEFINE_FP #undef DEFINE_XMM #undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC #undef DEFINE_DR #undef DEFINE_GPR_PSEUDO_16 #undef DEFINE_GPR_PSEUDO_8H diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h index 5dcbc6772ed..06d79dcc5e0 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h @@ -32,6 +32,16 @@ LLVM_EXTENSION offsetof(FPR, xstate) + \ LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xstate) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index])) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xstate) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index])) + #ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT // Number of bytes needed to represent a FPR. @@ -46,6 +56,10 @@ // Number of bytes needed to represent a YMM register. #define YMM_SIZE sizeof(YMMReg) +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + #define DR_SIZE sizeof(((DBG *)NULL)->dr[0]) // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB @@ -111,6 +125,26 @@ NULL, NULL, NULL, 0 \ } +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, NULL, BNDR_SIZE, \ + LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_x86_64, \ + dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + lldb_##reg##i##_x86_64 }, \ + NULL, NULL \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, NULL, BNDC_SIZE, \ + LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, lldb_##name##_x86_64 }, \ + NULL, NULL \ + } + #define DEFINE_DR(reg, i) \ { \ #reg #i, NULL, DR_SIZE, \ @@ -288,6 +322,15 @@ static RegisterInfo g_register_infos_x86_64[] = { DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14), DEFINE_YMM(ymm, 15), + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + // Debug registers for lldb internal use DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; @@ -305,6 +348,8 @@ static_assert((sizeof(g_register_infos_x86_64) / #undef DEFINE_FP #undef DEFINE_XMM #undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC #undef DEFINE_DR #undef DEFINE_GPR_PSEUDO_32 #undef DEFINE_GPR_PSEUDO_16 diff --git a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h index 5f71495c302..770ec5a5f3e 100644 --- a/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -104,6 +104,18 @@ enum { lldb_ymm7_i386, k_last_avx_i386 = lldb_ymm7_i386, + k_first_mpxr_i386, + lldb_bnd0_i386 = k_first_mpxr_i386, + lldb_bnd1_i386, + lldb_bnd2_i386, + lldb_bnd3_i386, + k_last_mpxr = lldb_bnd3_i386, + + k_first_mpxc_i386, + lldb_bndcfgu_i386 = k_first_mpxc_i386, + lldb_bndstatus_i386, + k_last_mpxc_i386 = lldb_bndstatus_i386, + lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, @@ -117,9 +129,11 @@ enum { k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1, k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1, + k_num_mpx_registers_i386 = k_last_mpxc_i386 - k_first_mpxr_i386 + 1, k_num_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + - k_num_avx_registers_i386, + k_num_avx_registers_i386 + + k_num_mpx_registers_i386, }; //--------------------------------------------------------------------------- @@ -273,6 +287,18 @@ enum { lldb_ymm15_x86_64, k_last_avx_x86_64 = lldb_ymm15_x86_64, + k_first_mpxr_x86_64, + lldb_bnd0_x86_64 = k_first_mpxr_x86_64, + lldb_bnd1_x86_64, + lldb_bnd2_x86_64, + lldb_bnd3_x86_64, + k_last_mpxr_x86_64 = lldb_bnd3_x86_64, + + k_first_mpxc_x86_64, + lldb_bndcfgu_x86_64 = k_first_mpxc_x86_64, + lldb_bndstatus_x86_64, + k_last_mpxc_x86_64 = lldb_bndstatus_x86_64, + lldb_dr0_x86_64, lldb_dr1_x86_64, lldb_dr2_x86_64, @@ -286,9 +312,11 @@ enum { k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1, k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1, k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1, + k_num_mpx_registers_x86_64 = k_last_mpxc_x86_64 - k_first_mpxr_x86_64 + 1, k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + - k_num_avx_registers_x86_64, + k_num_avx_registers_x86_64 + + k_num_mpx_registers_x86_64, }; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index bc018368461..8f0a8873bfc 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -1592,6 +1592,9 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( case eFormatVectorOfFloat32: response.PutCString("format:vector-float32;"); break; + case eFormatVectorOfUInt64: + response.PutCString("format:vector-uint64;"); + break; case eFormatVectorOfUInt128: response.PutCString("format:vector-uint128;"); break; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index cf220f3150b..2050a7d7610 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -547,6 +547,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { .Case("vector-sint32", eFormatVectorOfSInt32) .Case("vector-uint32", eFormatVectorOfUInt32) .Case("vector-float32", eFormatVectorOfFloat32) + .Case("vector-uint64", eFormatVectorOfUInt64) .Case("vector-uint128", eFormatVectorOfUInt128) .Default(eFormatInvalid); } @@ -4178,6 +4179,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, reg_info.format = eFormatVectorOfUInt32; else if (value == "vector-float32") reg_info.format = eFormatVectorOfFloat32; + else if (value == "vector-uint64") + reg_info.format = eFormatVectorOfUInt64; else if (value == "vector-uint128") reg_info.format = eFormatVectorOfUInt128; } else if (name == "group_id") { |

