From b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 5 Mar 2012 14:21:46 +0000 Subject: [PATCH] 2012-03-05 Pedro Alves * 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 | 6 ++++ gdb/i387-tdep.c | 87 +++++++++++++++++++++++++++++++++++---------------------- 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 + + * 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 * 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; -- 2.7.4