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.
This commit is contained in:
Pedro Alves
2012-03-05 14:21:46 +00:00
parent 0945bbeec0
commit b4d36fb80a
2 changed files with 63 additions and 36 deletions

View File

@@ -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;
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, regs == NULL ? NULL : zero);
}
else
{
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;
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, regs == NULL ? NULL : zero);
}
else
{
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;
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, regs == NULL ? NULL : zero);
}
else
{
for (i = I387_ST0_REGNUM (tdep);
i < I387_FCTRL_REGNUM (tdep);
i++)
regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
}
}
break;