aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2012-03-05 14:21:46 +0000
committerPedro Alves <palves@redhat.com>2012-03-05 14:21:46 +0000
commitb4d36fb80a261e933b7fdf0675fc98cbfb2d9c95 (patch)
tree500db07d45f74e0262808c4e475eae3673558b3e /gdb
parent0945bbeec06f9eb766c1b8158e9d5d9a174c541d (diff)
downloadfsf-binutils-gdb-b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95.zip
fsf-binutils-gdb-b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95.tar.gz
fsf-binutils-gdb-b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95.tar.bz2
2012-03-05 Pedro Alves <palves@redhat.com>
* 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.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/i387-tdep.c87
2 files changed, 60 insertions, 33 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1cc2160..a7fc4dd 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-05 Pedro Alves <palves@redhat.com>
+
+ * 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-03-05 Tristan Gingold <gingold@adacore.com>
* NEWS: Mention OpenVMS ia64 new target.
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index 27f3c5b..3fc344d 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -779,6 +779,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
{
@@ -818,6 +819,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:
@@ -825,26 +839,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:
@@ -852,16 +866,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));
}
}
@@ -869,16 +886,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));
}
}
@@ -886,16 +905,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;