summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorValentina Giusti <valentina.giusti@intel.com>2016-09-08 14:16:45 +0000
committerValentina Giusti <valentina.giusti@intel.com>2016-09-08 14:16:45 +0000
commitcda0ae46ac9b368ee7cbb0da5aa447563dec0aae (patch)
tree6c509d4f4177d7f0e36df592219884b079561915 /lldb/source
parent4d1e4d76ee4636b6605e6d119322b767efc93b70 (diff)
downloadbcm5719-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')
-rwxr-xr-xlldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp79
-rw-r--r--lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp78
-rwxr-xr-xlldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp149
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h15
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContext_x86.h36
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h44
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h45
-rw-r--r--lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h32
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp3
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") {
OpenPOWER on IntegriCloud