]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2012-03-06 Pedro Alves <palves@redhat.com>
authorPedro Alves <palves@redhat.com>
Tue, 6 Mar 2012 13:17:12 +0000 (13:17 +0000)
committerPedro Alves <palves@redhat.com>
Tue, 6 Mar 2012 13:17:12 +0000 (13:17 +0000)
PR gdb/13766

* i387-tdep.c (i387_supply_xsave): If we have an xsave buffer, and
the register state is clear, supply explicit zero, instead of
marking the register unavailable.

gdb/ChangeLog
gdb/i387-tdep.c

index 6e9a3ab1c96333c7b60a4af73416a13dd6b5eecd..954e47c3a9c9c6c9817718809e96e30e3fad9f16 100644 (file)
@@ -1,3 +1,11 @@
+2012-03-06  Pedro Alves  <palves@redhat.com>
+
+       PR gdb/13766
+
+       * i387-tdep.c (i387_supply_xsave): If we have an xsave buffer, and
+       the register state is clear, supply explicit zero, instead of
+       marking the register unavailable.
+
 2012-02-23  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        PR backtrace/13716
index 450b8f21a1c2f2f606ae8b8687cef5d571c36cef..d2ff9e54ad5b838ec0ed12ad80340bfe80dffbb4 100644 (file)
@@ -725,6 +725,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   const gdb_byte *regs = xsave;
   int i;
   unsigned int clear_bv;
+  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
   const gdb_byte *p;
   enum
     {
@@ -764,6 +765,19 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   else
     clear_bv = I386_XSTATE_AVX_MASK;
 
+  /* With the delayed xsave mechanism, in between the program
+     starting, and the program accessing the vector registers for the
+     first time, the register's values are invalid.  The kernel
+     initializes register states to zero when they are set the first
+     time in a program.  This means that from the user-space programs'
+     perspective, it's the same as if the registers have always been
+     zero from the start of the program.  Therefore, the debugger
+     should provide the same illusion to the user.
+
+     Note however, the case when REGS is NULL is a different case.
+     That case means we do not have access to the x87 states, so we
+     should mark the registers as unavailable (by supplying NULL).  */
+
   switch (regclass)
     {
     case none:
@@ -771,26 +785,26 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
 
     case avxh:
       if ((clear_bv & I386_XSTATE_AVX))
-       p = NULL;
+       regcache_raw_supply (regcache, regnum, regs == NULL ? NULL : zero);
       else
-       p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
-      regcache_raw_supply (regcache, regnum, p);
+       regcache_raw_supply (regcache, regnum,
+                            XSAVE_AVXH_ADDR (tdep, regs, regnum));
       return;
 
     case sse:
       if ((clear_bv & I386_XSTATE_SSE))
-       p = NULL;
+       regcache_raw_supply (regcache, regnum, regs == NULL ? NULL : zero);
       else
-       p = FXSAVE_ADDR (tdep, regs, regnum);
-      regcache_raw_supply (regcache, regnum, p);
+       regcache_raw_supply (regcache, regnum,
+                            FXSAVE_ADDR (tdep, regs, regnum));
       return;
 
     case x87:
       if ((clear_bv & I386_XSTATE_X87))
-       p = NULL;
+       regcache_raw_supply (regcache, regnum, regs == NULL ? NULL : zero);
       else
-       p = FXSAVE_ADDR (tdep, regs, regnum);
-      regcache_raw_supply (regcache, regnum, p);
+       regcache_raw_supply (regcache, regnum,
+                            FXSAVE_ADDR (tdep, regs, regnum));
       return;
 
     case all:
@@ -798,16 +812,19 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       if ((tdep->xcr0 & I386_XSTATE_AVX))
        {
          if ((clear_bv & I386_XSTATE_AVX))
-           p = NULL;
+           {
+             for (i = I387_YMM0H_REGNUM (tdep);
+                  i < I387_YMMENDH_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, regs == NULL ? NULL : zero);
+           }
          else
-           p = regs;
-
-         for (i = I387_YMM0H_REGNUM (tdep);
-              i < I387_YMMENDH_REGNUM (tdep); i++)
            {
-             if (p != NULL)
-               p = XSAVE_AVXH_ADDR (tdep, regs, i);
-             regcache_raw_supply (regcache, i, p);
+             for (i = I387_YMM0H_REGNUM (tdep);
+                  i < I387_YMMENDH_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i,
+                                    XSAVE_AVXH_ADDR (tdep, regs, i));
            }
        }
 
@@ -815,16 +832,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       if ((tdep->xcr0 & I386_XSTATE_SSE))
        {
          if ((clear_bv & I386_XSTATE_SSE))
-           p = NULL;
+           {
+             for (i = I387_XMM0_REGNUM (tdep);
+                  i < I387_MXCSR_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, regs == NULL ? NULL : zero);
+           }
          else
-           p = regs;
-
-         for (i = I387_XMM0_REGNUM (tdep);
-              i < I387_MXCSR_REGNUM (tdep); i++)
            {
-             if (p != NULL)
-               p = FXSAVE_ADDR (tdep, regs, i);
-             regcache_raw_supply (regcache, i, p);
+             for (i = I387_XMM0_REGNUM (tdep);
+                  i < I387_MXCSR_REGNUM (tdep); i++)
+               regcache_raw_supply (regcache, i,
+                                    FXSAVE_ADDR (tdep, regs, i));
            }
        }
 
@@ -832,16 +851,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       if ((tdep->xcr0 & I386_XSTATE_X87))
        {
          if ((clear_bv & I386_XSTATE_X87))
-           p = NULL;
+           {
+             for (i = I387_ST0_REGNUM (tdep);
+                  i < I387_FCTRL_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, regs == NULL ? NULL : zero);
+           }
          else
-           p = regs;
-
-         for (i = I387_ST0_REGNUM (tdep);
-              i < I387_FCTRL_REGNUM (tdep); i++)
            {
-             if (p != NULL)
-               p = FXSAVE_ADDR (tdep, regs, i);
-             regcache_raw_supply (regcache, i, p);
+             for (i = I387_ST0_REGNUM (tdep);
+                  i < I387_FCTRL_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
            }
        }
       break;