179 changes: 169 additions & 10 deletions lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ namespace
static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == 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[] =
Expand Down Expand Up @@ -291,29 +306,47 @@ namespace
static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == 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
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 },
{ "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
{ "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 },
{ "Advanced Vector Extensions", "avx", k_num_avx_registers_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] =
{
{ "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
{ "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 }
{ "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
{ "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 },
{ "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64, g_mpx_regnums_x86_64 }

};
}

Expand Down Expand Up @@ -368,6 +401,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const Arch
m_fpr (),
m_iovec (),
m_ymm_set (),
m_mpx_set (),
m_reg_info (),
m_gpr_x86_64 ()
{
Expand All @@ -379,6 +413,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const Arch
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;
Expand All @@ -390,6 +425,10 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const Arch
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;
Expand All @@ -398,6 +437,7 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const Arch
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;
Expand All @@ -409,6 +449,10 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64 (const Arch
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;
Expand Down Expand Up @@ -554,7 +598,28 @@ NativeRegisterContextLinux_x86_64::ReadRegister (const RegisterInfo *reg_info, R
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 ("write failed - type was expected to be RegisterValue::eTypeBytes");

Expand Down Expand Up @@ -634,6 +699,26 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
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
{
Expand Down Expand Up @@ -677,6 +762,12 @@ NativeRegisterContextLinux_x86_64::WriteRegister (const RegisterInfo *reg_info,
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, write strategy unknown");
Expand Down Expand Up @@ -727,6 +818,17 @@ NativeRegisterContextLinux_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &da
}
}

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));
}
Expand Down Expand Up @@ -806,6 +908,17 @@ NativeRegisterContextLinux_x86_64::WriteAllRegisterValues (const lldb::DataBuffe
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;
Expand All @@ -820,7 +933,7 @@ NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable (uint32_t set_index) c
if (GetFPRType () == eFPRTypeXSAVE)
{
// AVX is the first extended register set.
++num_sets;
num_sets += 2;
}
return (set_index < num_sets);
}
Expand Down Expand Up @@ -870,7 +983,8 @@ NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index, FPRType fpr_type) c
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;
}

Expand Down Expand Up @@ -1005,6 +1119,7 @@ NativeRegisterContextLinux_x86_64::ReadFPR ()
{
const FPRType fpr_type = GetFPRType ();
const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();

switch (fpr_type)
{
case FPRType::eFPRTypeFXSAVE:
Expand All @@ -1029,6 +1144,50 @@ 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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ namespace process_linux {
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;
Expand All @@ -124,6 +125,10 @@ namespace process_linux {
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;
Expand All @@ -134,6 +139,7 @@ namespace process_linux {
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;
Expand All @@ -160,7 +166,16 @@ namespace process_linux {
CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);

bool
IsAVX (uint32_t reg_index) const;
CopyXSTATEtoMPX(uint32_t reg);

bool
CopyMPXtoXSTATE(uint32_t reg);

bool
IsAVX(uint32_t reg_index) const;

bool
IsMPX(uint32_t reg_index) const;
};

} // namespace process_linux
Expand Down
38 changes: 33 additions & 5 deletions lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,13 @@ 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,
};

//---------------------------------------------------------------------------
Expand Down Expand Up @@ -216,6 +219,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,
Expand Down Expand Up @@ -291,19 +299,39 @@ 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];
};

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];
} __attribute__((packed));

// x86 extensions to FXSAVE (i.e. for AVX processors)
struct XSAVE
// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
struct XSAVE
{
FXSAVE i387; // floating point registers typical in i387_fxsave_struct
XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the 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)
uint64_t reserved3[16];
MPXReg mpxr[4]; // MPX BNDREG state, containing 128-bit bound registers BND0-BND3
MPXCsr mpxc[2]; // MPX BNDCSR state, containing 64-bit BNDCFGU and BNDSTATUS registers
// Slot any extensions to the register file here
} __attribute__((packed, aligned (64)));

Expand Down
35 changes: 35 additions & 0 deletions lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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)
Expand All @@ -49,6 +59,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) \
{ #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \
Expand Down Expand Up @@ -85,6 +99,18 @@
{ LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \
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##_x86_64 }, \
NULL, NULL }

#define DEFINE_DR(reg, i) \
{ #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
{ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
Expand Down Expand Up @@ -188,6 +214,15 @@ g_register_infos_i386[] =
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),
Expand Down
35 changes: 35 additions & 0 deletions lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@
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.
Expand All @@ -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)

#define DR_SIZE sizeof(((DBG*)NULL)->dr[0])

// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
Expand Down Expand Up @@ -85,6 +99,18 @@
{ dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_x86_64 }, \
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, DR_OFFSET(i), eEncodingUint, eFormatHex, \
{ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
Expand Down Expand Up @@ -251,6 +277,15 @@ g_register_infos_x86_64[] =
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),
Expand Down
30 changes: 28 additions & 2 deletions lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ namespace lldb_private
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,
Expand All @@ -119,7 +131,8 @@ namespace lldb_private
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_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + k_num_avx_registers_i386,
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_mpx_registers_i386,
};

//---------------------------------------------------------------------------
Expand Down Expand Up @@ -274,6 +287,18 @@ namespace lldb_private
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,
Expand All @@ -287,7 +312,8 @@ namespace lldb_private
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_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64,
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_mpx_registers_x86_64,
};

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1566,6 +1566,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo (StringExtractorGDBRemote
case eFormatVectorOfSInt32: response.PutCString ("format:vector-sint32;"); break;
case eFormatVectorOfUInt32: response.PutCString ("format:vector-uint32;"); break;
case eFormatVectorOfFloat32: response.PutCString ("format:vector-float32;"); break;
case eFormatVectorOfUInt64: response.PutCString ("format:vector-uint64;"); break;
case eFormatVectorOfUInt128: response.PutCString ("format:vector-uint128;"); break;
default: break;
};
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ 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);
}
Expand Down Expand Up @@ -4545,6 +4546,8 @@ ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemot
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;
}
Expand Down