This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/4] Change xstate_bv handling to use 8 bytes of data.


The size of the state-component bitmap as specified in
Intel(R) 64 and IA-32 Architectures Software Developer's Manual,
Chapter 13.4.2 is 8 bytes.
So far, the data types used for xstate_bv_p (gdb_byte*),
clear_bv (unsigned int) and tdep->xcr0 (uint64_t) were
inconsistent. But, since the xstate components were still
fitting into a single byte, the code still worked
as expected.
However, with the addition of the PKU feature (bit 9),
using one byte for the bitmap will no longer be sufficient.

This patch changes related code to use 64 bit data types
consistently and changes read/write acces of the XSAVE
header in the regcache to use memcpy, like already done
for register access.

gdb/Changelog:
2016-04-18  Michael Sturm  <michael.sturm@intel.com>

     * i387-tdep.c (i387_supply_xsave): Change type
     of clear_bv to ULONGEST. Replace gdb_byte *xstate_bv_p
     with ULONGEST xstate_bv and use memcpy to read its
     value. Change assigment to clear_bv accordingly.
     (i387_collect_xsave): Replace gdb_byte *xstate_bv_p
     with ULONGEST initial_xstate_bv and use memcpy to read/write
     its value. Change type of clear_bv to ULONGEST.

gdbserver/Changelog:
2016-04-18  Michael Sturm  <michael.sturm@intel.com>

     * i387-fp.c (i387_cache_to_xsave): Change type of clear_bv to
     unsigned long long.
     (i387_fxsave_to_cache): Likewise.

Change-Id: I0de254158960b4f7bcbc9fe2fb857034fa1f7ca5
Signed-off-by: Michael Sturm <michael.sturm@intel.com>
---
 gdb/gdbserver/i387-fp.c |  4 ++--
 gdb/i387-tdep.c         | 25 ++++++++++++++-----------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/gdb/gdbserver/i387-fp.c b/gdb/gdbserver/i387-fp.c
index a90729a..3775fc1 100644
--- a/gdb/gdbserver/i387-fp.c
+++ b/gdb/gdbserver/i387-fp.c
@@ -273,8 +273,8 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf)
   struct i387_xsave *fp = (struct i387_xsave *) buf;
   int i;
   unsigned long val, val2;
-  unsigned int clear_bv;
   unsigned long long xstate_bv = 0;
+  unsigned long long clear_bv = 0;
   char raw[64];
   char *p;
   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
@@ -643,7 +643,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf)
   struct i387_fxsave *fxp = (struct i387_fxsave *) buf;
   int i, top;
   unsigned long val;
-  unsigned int clear_bv;
+  unsigned long long clear_bv;
   gdb_byte *p;
   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
   int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index f7a3b55..cf9cc01 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -898,7 +898,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   const gdb_byte *regs = (const gdb_byte *) xsave;
   int i;
-  unsigned int clear_bv;
+  ULONGEST clear_bv;
   static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
   enum
     {
@@ -950,12 +950,13 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
 
   if (regclass != none)
     {
-      /* Get `xstat_bv'.  */
-      const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
+      /* Get `xstat_bv'. The supported bits in `xstat_bv' are 8 bytes.  */
+      ULONGEST xstate_bv = 0;
 
-      /* The supported bits in `xstat_bv' are 1 byte.  Clear part in
-	 vector registers if its bit in xstat_bv is zero.  */
-      clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
+      memcpy (&xstate_bv, XSAVE_XSTATE_BV_ADDR (regs), 8);
+
+      /* Clear part in vector registers if its bit in xstat_bv is zero.  */
+      clear_bv = (~(xstate_bv)) & tdep->xcr0;
     }
   else
     clear_bv = X86_XSTATE_ALL_MASK;
@@ -1333,12 +1334,13 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
   if ((regclass & check))
     {
       gdb_byte raw[I386_MAX_REGISTER_SIZE];
-      gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
-      unsigned int xstate_bv = 0;
-      /* The supported bits in `xstat_bv' are 1 byte.  */
-      unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
+      ULONGEST initial_xstate_bv, clear_bv, xstate_bv = 0;
       gdb_byte *p;
 
+      /* The supported bits in `xstat_bv' are 8 bytes.  */
+      memcpy (&initial_xstate_bv, XSAVE_XSTATE_BV_ADDR (regs), 8);
+      clear_bv = (~(initial_xstate_bv)) & tdep->xcr0;
+
       /* Clear register set if its bit in xstat_bv is zero.  */
       if (clear_bv)
 	{
@@ -1620,7 +1622,8 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
       if (xstate_bv)
 	{
 	  /* The supported bits in `xstat_bv' are 1 byte.  */
-	  *xstate_bv_p |= (gdb_byte) xstate_bv;
+	  initial_xstate_bv |= xstate_bv;
+	  memcpy (XSAVE_XSTATE_BV_ADDR (regs), &initial_xstate_bv, 8);
 
 	  switch (regclass)
 	    {
-- 
1.8.4.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]