From: Pedro Alves Date: Tue, 6 Mar 2012 13:17:12 +0000 (+0000) Subject: 2012-03-06 Pedro Alves X-Git-Tag: gdb_7_4_1-2012-04-26-release~58 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1efc25ca4a22625b10fd13286ed68eb42b761bb8;p=thirdparty%2Fbinutils-gdb.git 2012-03-06 Pedro Alves 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6e9a3ab1c96..954e47c3a9c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2012-03-06 Pedro Alves + + 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 PR backtrace/13716 diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index 450b8f21a1c..d2ff9e54ad5 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -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;