This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v3 5/8] Add MPX support to gdbserver.
- From: Walfred Tedeschi <walfred dot tedeschi at intel dot com>
- To: gdb-patches at sourceware dot org, walfred dot tedeschi at intel dot com, mircea dot gherzan at intel dot com
- Date: Fri, 30 Aug 2013 11:58:00 +0200
- Subject: [PATCH v3 5/8] Add MPX support to gdbserver.
- Authentication-results: sourceware.org; auth=none
- References: <1377856683-11267-1-git-send-email-walfred dot tedeschi at intel dot com>
Added register reading and writing into gdbserver.
MPX registers are based on xsave buffer change was done following same
basically same scheme of MPX native registers reading/writing.
2013-05-22 Walfred Tedeschi <walfred.tedeschi@intel.com>
gdb/gdbserver
* Makefile.in: Add i386-mpx.c, i386-mpx-linux.c, amd64-mpx.c,
amd64-mpx-linux.c, x32-mpx.c and x32-mpx-linux.c generation.
* configure.srv (srv_i386_regobj): Add i386-mpx.o.
(srv_i386_linux_regobj): Add i386-mpx-linux.o.
(srv_amd64_regobj): Add amd64-mpx.o.
(srv_amd64_linux_regobj): Add amd64-mpx-linux.o.
(srv_i386_32bit_xmlfiles): Add i386/32bit-mpx.xml.
(srv_i386_64bit_xmlfiles): Add i386/64bit-mpx.xml.
* i387-fp.c (num_pl_bnd_register) Added constant.
(num_pl_bnd_cfg_registers) Added constant.
(struct i387_xsave) Added reserved area and MPX fields.
(i387_cache_to_xsave, i387_xsave_to_cache) Add MPX.
* linux-x86-low.c (init_registers_i386_mpx_linux): Declare new
function.
(tdesc_i386_mpx_linux): Add MPX amd64 target.
(init_registers_amd64_mpx_linux): Declare new function.
(tdesc_amd64_mpx_linux): Add MPX amd64 target.
(init_registers_x32_mpx_linux): Declare new function.
(tdesc_x32_mpx_linux): Add MPX amd64 target.
(x86_64_regmap): Add MPX registers.
(x86_linux_read_description): Add MPX case.
(initialize_low_arch): Initialize MPX targets.
Signed-off-by: Walfred Tedeschi <walfred.tedeschi@intel.com>
---
gdb/gdbserver/Makefile.in | 15 +++++++
gdb/gdbserver/configure.srv | 20 ++++-----
gdb/gdbserver/i387-fp.c | 90 +++++++++++++++++++++++++++++++++++++++++
gdb/gdbserver/linux-x86-low.c | 87 +++++++++++++++++++++++++++++++--------
4 files changed, 186 insertions(+), 26 deletions(-)
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 45e03a2..1acaf50 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -339,10 +339,13 @@ clean:
rm -f tic6x-c64xp-linux.c tic6x-c64x-linux.c tic6x-c62x-linux.c
rm -f xml-builtin.c stamp-xml
rm -f i386-avx.c i386-avx-linux.c
+ rm -f i386-mpx.c i386-mpx-linux.c
rm -f amd64-avx.c amd64-avx-linux.c
+ rm -f amd64-mpx.c amd64-mpx-linux.c
rm -f i386-mmx.c i386-mmx-linux.c
rm -f x32.c x32-linux.c
rm -f x32-avx.c x32-avx-linux.c
+ rm -f x32-mpx.c x32-mpx-linux.c
@$(MAKE) $(FLAGS_TO_PASS) DO=$@ "DODIRS=$(SUBDIRS)" subdir_do
maintainer-clean realclean distclean: clean
@@ -613,6 +616,10 @@ i386-avx.c : $(srcdir)/../regformats/i386/i386-avx.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx.dat i386-avx.c
i386-avx-linux.c : $(srcdir)/../regformats/i386/i386-avx-linux.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-linux.dat i386-avx-linux.c
+i386-mpx.c : $(srcdir)/../regformats/i386/i386-mpx.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-mpx.dat i386-mpx.c
+i386-mpx-linux.c : $(srcdir)/../regformats/i386/i386-mpx-linux.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-mpx-linux.dat i386-mpx-linux.c
i386-mmx.c : $(srcdir)/../regformats/i386/i386-mmx.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-mmx.dat i386-mmx.c
i386-mmx-linux.c : $(srcdir)/../regformats/i386/i386-mmx-linux.dat $(regdat_sh)
@@ -705,8 +712,12 @@ amd64-linux.c : $(srcdir)/../regformats/i386/amd64-linux.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-linux.dat amd64-linux.c
amd64-avx.c : $(srcdir)/../regformats/i386/amd64-avx.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx.dat amd64-avx.c
+amd64-mpx.c : $(srcdir)/../regformats/i386/amd64-mpx.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-mpx.dat amd64-mpx.c
amd64-avx-linux.c : $(srcdir)/../regformats/i386/amd64-avx-linux.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-linux.dat amd64-avx-linux.c
+amd64-mpx-linux.c : $(srcdir)/../regformats/i386/amd64-mpx-linux.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-mpx-linux.dat amd64-mpx-linux.c
x32.c : $(srcdir)/../regformats/i386/x32.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/x32.dat x32.c
x32-linux.c : $(srcdir)/../regformats/i386/x32-linux.dat $(regdat_sh)
@@ -715,6 +726,10 @@ x32-avx.c : $(srcdir)/../regformats/i386/x32-avx.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/x32-avx.dat x32-avx.c
x32-avx-linux.c : $(srcdir)/../regformats/i386/x32-avx-linux.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/x32-avx-linux.dat x32-avx-linux.c
+x32-mpx.c : $(srcdir)/../regformats/i386/x32-mpx.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/x32-mpx.dat x32-mpx.c
+x32-mpx-linux.c : $(srcdir)/../regformats/i386/x32-mpx-linux.dat $(regdat_sh)
+ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/x32-mpx-linux.dat x32-mpx-linux.c
reg-xtensa.c : $(srcdir)/../regformats/reg-xtensa.dat $(regdat_sh)
$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-xtensa.dat reg-xtensa.c
reg-tilegx.c : $(srcdir)/../regformats/reg-tilegx.dat $(regdat_sh)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index b3c0421..1d463a8 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -24,20 +24,20 @@
# Default hostio_last_error implementation
srv_hostio_err_objs="hostio-errno.o"
-srv_i386_regobj="i386.o i386-avx.o i386-mmx.o"
-srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-mmx-linux.o"
-srv_amd64_regobj="amd64.o amd64-avx.o x32.o x32-avx.o"
-srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o x32-linux.o x32-avx-linux.o"
+srv_i386_regobj="i386.o i386-avx.o i386-mpx.o i386-mmx.o"
+srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-mpx-linux.o i386-mmx-linux.o"
+srv_amd64_regobj="amd64.o amd64-avx.o amd64-mpx.o x32.o x32-avx.o x32-mpx.o"
+srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-mpx-linux.o x32-linux.o x32-avx-linux.o x32-mpx-linux.o"
ipa_i386_linux_regobj=i386-linux-ipa.o
ipa_amd64_linux_regobj=amd64-linux-ipa.o
-srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml"
-srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/x32-core.xml"
-srv_i386_xmlfiles="i386/i386.xml i386/i386-avx.xml i386/i386-mmx.xml $srv_i386_32bit_xmlfiles"
-srv_amd64_xmlfiles="i386/amd64.xml i386/amd64-avx.xml i386/x32.xml i386/x32-avx.xml $srv_i386_64bit_xmlfiles"
-srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/i386-avx-linux.xml i386/i386-mmx-linux.xml i386/32bit-linux.xml $srv_i386_32bit_xmlfiles"
-srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/64bit-linux.xml i386/x32-linux.xml i386/x32-avx-linux.xml $srv_i386_64bit_xmlfiles"
+srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-mpx.xml"
+srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/x32-core.xml i386/64bit-mpx.xml"
+srv_i386_xmlfiles="i386/i386.xml i386/i386-avx.xml i386/i386-mpx.xml i386/i386-mmx.xml $srv_i386_32bit_xmlfiles"
+srv_amd64_xmlfiles="i386/amd64.xml i386/amd64-avx.xml i386/x32.xml i386/x32-avx.xml i386/amd64-mpx.xml $srv_i386_64bit_xmlfiles"
+srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/i386-avx-linux.xml i386/i386-mmx-linux.xml i386/32bit-linux.xml i386/i386-mpx-linux.xml $srv_i386_32bit_xmlfiles"
+srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/64bit-linux.xml i386/amd64-mpx-linux.xml i386/x32-linux.xml i386/x32-avx-linux.xml i386/x32-mpx-linux.xml $srv_i386_64bit_xmlfiles"
# Linux object files. This is so we don't have to repeat
diff --git a/gdb/gdbserver/i387-fp.c b/gdb/gdbserver/i387-fp.c
index 2886519..1240b67 100644
--- a/gdb/gdbserver/i387-fp.c
+++ b/gdb/gdbserver/i387-fp.c
@@ -20,6 +20,9 @@
#include "i387-fp.h"
#include "i386-xstate.h"
+static const int num_mpx_bnd_registers = 4;
+static const int num_mpx_cfg_registers = 2;
+
/* Note: These functions preserve the reserved bits in control registers.
However, gdbserver promptly throws away that information. */
@@ -108,6 +111,15 @@ struct i387_xsave {
/* Space for eight upper 128-bit YMM values, or 16 on x86-64. */
unsigned char ymmh_space[256];
+
+ unsigned char reserved4[128];
+
+ /* Space for 4 bound registers values of 128 bits. */
+ unsigned char mpx_bnd_space[64];
+
+ /* Space for 2 MPX configuration registers of 64 bits
+ plus reserved space. */
+ unsigned char mpx_cfg_space[16];
};
void
@@ -271,6 +283,14 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
if ((clear_bv & I386_XSTATE_AVX))
for (i = 0; i < num_xmm_registers; i++)
memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16);
+
+ if ((clear_bv & I386_XSTATE_BNDREGS))
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16);
+
+ if ((clear_bv & I386_XSTATE_BNDCFG))
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8);
}
/* Check if any x87 registers are changed. */
@@ -324,6 +344,40 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
}
}
+ /* Check if any bound register has changed. */
+ if ((x86_xcr0 & I386_XSTATE_BNDREGS))
+ {
+ int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
+
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ {
+ collect_register (regcache, i + bnd0r_regnum, raw);
+ p = ((char *) &fp->mpx_bnd_space[0]) + i * 16;
+ if (memcmp (raw, p, 16))
+ {
+ xstate_bv |= I386_XSTATE_BNDREGS;
+ memcpy (p, raw, 16);
+ }
+ }
+ }
+
+ /* Check if any status register has changed. */
+ if ((x86_xcr0 & I386_XSTATE_BNDCFG))
+ {
+ int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
+
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ {
+ collect_register (regcache, i + bndcfg_regnum, raw);
+ p = ((char *) &fp->mpx_cfg_space[0]) + i * 8;
+ if (memcmp (raw, p, 8))
+ {
+ xstate_bv |= I386_XSTATE_BNDCFG;
+ memcpy (p, raw, 8);
+ }
+ }
+ }
+
/* Update the corresponding bits in xstate_bv if any SSE/AVX
registers are changed. */
fp->xstate_bv |= xstate_bv;
@@ -531,6 +585,42 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
}
}
+ if ((x86_xcr0 & I386_XSTATE_BNDREGS))
+ {
+ int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw");
+
+
+ if ((clear_bv & I386_XSTATE_BNDREGS) != 0)
+ {
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ supply_register_zeroed (regcache, i + bnd0r_regnum);
+ }
+ else
+ {
+ p = (gdb_byte *) &fp->mpx_bnd_space[0];
+ for (i = 0; i < num_mpx_bnd_registers; i++)
+ supply_register (regcache, i + bnd0r_regnum, p + i * 16);
+ }
+
+ }
+
+ if ((x86_xcr0 & I386_XSTATE_BNDCFG))
+ {
+ int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu");
+
+ if ((clear_bv & I386_XSTATE_BNDCFG) != 0)
+ {
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ supply_register_zeroed (regcache, i + bndcfg_regnum);
+ }
+ else
+ {
+ p = (gdb_byte *) &fp->mpx_cfg_space[0];
+ for (i = 0; i < num_mpx_cfg_registers; i++)
+ supply_register (regcache, i + bndcfg_regnum, p + i * 8);
+ }
+ }
+
supply_register_by_name (regcache, "fioff", &fp->fioff);
supply_register_by_name (regcache, "fooff", &fp->fooff);
supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 3a4f007..8635bf8 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -41,6 +41,10 @@ extern const struct target_desc *tdesc_amd64_linux;
void init_registers_amd64_avx_linux (void);
extern const struct target_desc *tdesc_amd64_avx_linux;
+/* Defined in auto-generated file amd64-mpx-linux.c. */
+void init_registers_amd64_mpx_linux (void);
+extern const struct target_desc *tdesc_amd64_mpx_linux;
+
/* Defined in auto-generated file x32-linux.c. */
void init_registers_x32_linux (void);
extern const struct target_desc *tdesc_x32_linux;
@@ -48,6 +52,11 @@ extern const struct target_desc *tdesc_x32_linux;
/* Defined in auto-generated file x32-avx-linux.c. */
void init_registers_x32_avx_linux (void);
extern const struct target_desc *tdesc_x32_avx_linux;
+
+/* Defined in auto-generated file x32-mpx-linux.c. */
+void init_registers_x32_mpx_linux (void);
+extern const struct target_desc *tdesc_x32_mpx_linux;
+
#endif
/* Defined in auto-generated file i386-linux.c. */
@@ -62,6 +71,10 @@ extern const struct target_desc *tdesc_i386_mmx_linux;
void init_registers_i386_avx_linux (void);
extern const struct target_desc *tdesc_i386_avx_linux;
+/* Defined in auto-generated file i386-mpx-linux.c. */
+void init_registers_i386_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_mpx_linux;
+
#ifdef __x86_64__
static struct target_desc *tdesc_amd64_linux_no_xml;
#endif
@@ -161,8 +174,11 @@ static const int x86_64_regmap[] =
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1,
- ORIG_RAX * 8
+ -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ ORIG_RAX * 8,
+ -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
+ -1, -1 /* MPX registers BNDCFGU, BNDSTATUS. */
};
#define X86_64_NUM_REGS (sizeof (x86_64_regmap) / sizeof (x86_64_regmap[0]))
@@ -1231,7 +1247,7 @@ x86_linux_read_description (void)
{
unsigned int machine;
int is_elf64;
- int avx;
+ int xcr0_features;
int tid;
static uint64_t xcr0;
struct regset_info *regset;
@@ -1310,36 +1326,71 @@ x86_linux_read_description (void)
}
/* Check the native XCR0 only if PTRACE_GETREGSET is available. */
- avx = (have_ptrace_getregset
- && (xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK);
+ xcr0_features = (have_ptrace_getregset
+ && (xcr0 & I386_XSTATE_ALL_MASK) == I386_XSTATE_ALL_MASK);
- /* AVX is the highest feature we support. */
- if (avx)
+ if (xcr0_features)
x86_xcr0 = xcr0;
if (machine == EM_X86_64)
{
#ifdef __x86_64__
- if (avx)
+ if (is_elf64)
{
- if (!is_elf64)
- return tdesc_x32_avx_linux;
+ if (xcr0_features)
+ {
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
+ {
+ case I386_XSTATE_MPX_MASK:
+ return tdesc_amd64_mpx_linux;
+
+ case I386_XSTATE_AVX_MASK:
+ return tdesc_amd64_avx_linux;
+
+ default:
+ return tdesc_amd64_linux;
+ }
+ }
else
- return tdesc_amd64_avx_linux;
+ return tdesc_amd64_linux;
}
else
{
- if (!is_elf64)
- return tdesc_x32_linux;
+ if (xcr0_features)
+ {
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
+ {
+ case I386_XSTATE_MPX_MASK:
+ return tdesc_x32_mpx_linux;
+
+ case I386_XSTATE_AVX_MASK:
+ return tdesc_x32_avx_linux;
+
+ default:
+ return tdesc_x32_linux;
+ }
+ }
else
- return tdesc_amd64_linux;
+ return tdesc_x32_linux;
}
#endif
}
else
{
- if (avx)
- return tdesc_i386_avx_linux;
+ if (xcr0_features)
+ {
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
+ {
+ case (I386_XSTATE_MPX_MASK):
+ return tdesc_i386_mpx_linux;
+
+ case (I386_XSTATE_AVX_MASK):
+ return tdesc_i386_avx_linux;
+
+ default:
+ return tdesc_i386_linux;
+ }
+ }
else
return tdesc_i386_linux;
}
@@ -3336,8 +3387,11 @@ initialize_low_arch (void)
#ifdef __x86_64__
init_registers_amd64_linux ();
init_registers_amd64_avx_linux ();
+ init_registers_amd64_mpx_linux ();
+
init_registers_x32_linux ();
init_registers_x32_avx_linux ();
+ init_registers_x32_mpx_linux ();
tdesc_amd64_linux_no_xml = xmalloc (sizeof (struct target_desc));
copy_target_description (tdesc_amd64_linux_no_xml, tdesc_amd64_linux);
@@ -3346,6 +3400,7 @@ initialize_low_arch (void)
init_registers_i386_linux ();
init_registers_i386_mmx_linux ();
init_registers_i386_avx_linux ();
+ init_registers_i386_mpx_linux ();
tdesc_i386_linux_no_xml = xmalloc (sizeof (struct target_desc));
copy_target_description (tdesc_i386_linux_no_xml, tdesc_i386_linux);
--
1.7.10.4