diff options
author | Pedro Alves <palves@redhat.com> | 2012-03-05 14:21:46 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-03-05 14:21:46 +0000 |
commit | b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95 (patch) | |
tree | 500db07d45f74e0262808c4e475eae3673558b3e | |
parent | 0945bbeec06f9eb766c1b8158e9d5d9a174c541d (diff) | |
download | gdb-b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95.zip gdb-b4d36fb80a261e933b7fdf0675fc98cbfb2d9c95.tar.gz 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.
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | 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 <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; |