This is the mail archive of the
gdb@sourceware.cygnus.com
mailing list for the GDB project.
Linux i387 fix
- To: jimb at cygnus dot com
- Subject: Linux i387 fix
- From: Mark Kettenis <kettenis at wins dot uva dot nl>
- Date: Mon, 13 Dec 1999 23:57:04 +0100 (CET)
- CC: gdb at sourceware dot cygnus dot com, gdb-patches at sourceware dot cygnus dot com
Hi Jim,
The current i386-linux.c:supply_fpregset() passes whatever is in the
reserved bits on to the GDB register file. Since the coporocessor
seems to be initialized in a state where these reserved bits are
turned on (at least in non-fpu using threads, see
linux/arch/i386/kernel/ptrace.c) this means that `info float' and
`info all-registers' will print some funny numbers. At the end of
this message you'll find a patch that fixes this.
I don't know if supply_xfpregs needs to be fixed too. Depends on the
Cygnus-specific Linux kernel patch I guess.
Maybe we should make some changes to convert_to_fpregset() too, such
that it doesn't change the reserved bits in *FPREGSETP. Right now it
overwrites those with the padding that's present in the GDB register
file.
Mark
1999-12-13 Mark Kettenis <kettenis@gnu.org>
* i386-linux-nat.c (supply_fpregset): Mask off the reserved bits
in *FPREGSETP before storing the values in the GDB register file.
Index: gdb/i386-linux-nat.c
===================================================================
RCS file: /var/cvsroot/gdb/gdb/i386-linux-nat.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 i386-linux-nat.c
--- gdb/i386-linux-nat.c 1999/12/13 21:10:21 1.1.1.4
+++ gdb/i386-linux-nat.c 1999/12/13 22:44:20
@@ -195,29 +195,36 @@
void
supply_fpregset (fpregset_t *fpregsetp)
{
+ long l;
int i;
/* Supply the floating-point registers. */
for (i = 0; i < 8; i++)
supply_register (FP0_REGNUM + i, FPREGSET_T_FPREG_ADDR (fpregsetp, i));
- supply_register (FCTRL_REGNUM, (char *) &fpregsetp->cwd);
- supply_register (FSTAT_REGNUM, (char *) &fpregsetp->swd);
- supply_register (FTAG_REGNUM, (char *) &fpregsetp->twd);
+ /* We have to mask off the reserved bits in *FPREGSETP before
+ storing the values in the GDB register file, since the reserved
+ parts of the structure typically are initialized with all bits
+ turned on. */
+#define supply(REGNO, MEMBER) \
+ l = fpregsetp->MEMBER & 0xffff; \
+ supply_register (REGNO, (char *) &l)
+
+ supply (FCTRL_REGNUM, cwd);
+ supply (FSTAT_REGNUM, swd);
+ supply (FTAG_REGNUM, twd);
supply_register (FCOFF_REGNUM, (char *) &fpregsetp->fip);
- supply_register (FDS_REGNUM, (char *) &fpregsetp->fos);
+ supply (FDS_REGNUM, fos);
supply_register (FDOFF_REGNUM, (char *) &fpregsetp->foo);
-
- /* Extract the code segment and opcode from the "fcs" member. */
- {
- long l;
- l = fpregsetp->fcs & 0xffff;
- supply_register (FCS_REGNUM, (char *) &l);
+#undef supply
+
+ /* Extract the code segment and opcode from the "fcs" member. */
+ l = fpregsetp->fcs & 0xffff;
+ supply_register (FCS_REGNUM, (char *) &l);
- l = (fpregsetp->fcs >> 16) & ((1 << 11) - 1);
- supply_register (FOP_REGNUM, (char *) &l);
- }
+ l = (fpregsetp->fcs >> 16) & ((1 << 11) - 1);
+ supply_register (FOP_REGNUM, (char *) &l);
}