Return to BSD News archive
Newsgroups: comp.unix.bsd Path: sserve!manuel.anu.edu.au!munnari.oz.au!metro!ipso!runxtsa!bde From: bde@runx.oz.au (Bruce Evans) Subject: [386BSD] implementation of "info float" for gdb-3.5 (source) Message-ID: <1992Nov29.103427.22234@runx.oz.au> Organization: RUNX Un*x Timeshare. Sydney, Australia. References: <1992Nov29.092901.21848@runx.oz.au> Date: Sun, 29 Nov 92 10:34:27 GMT Lines: 155 The enclosed diffs implement printing of the floating point state for the version of gdb-3.5 in 386BSD-0.0. I don't have gdb for 386BSD-0.1 but I've been told that it is also missing this feature. The changes are small. Code to read the FP state from the kernel was #ifdef'ed out, but it essentially works. Code to change the FP regs is still #ifdef'ed out. It is close to working too. Printing of the FP regs was broken because hard reg numbers were confused with stack offsets. Don't expect examination of the FP state to be of much use for debugging (user) FP errors. It won't hurt to look using these changes, but the kernel has a dozen or so bugs in its FP exception handlers. E.g.: 1. FP error handling is changed when you look at it using gdb (ptrace, really). 2. An FP error may be clobber the FP state. 3. All FP errors may cause a panic, and ptracing through an FP error increases the risk. 4. The emulator does not handle FP errors right, and it does not communicate the emulated FP state to the rest of the kernel, so "info float" shows garbage. I may post fixes for the kernel FP bugs (except for emulator bugs and IRQ13 h/w bugs) in a week or two. *** /usr/src/usr.bin/gdb/config/i386bsd-dep.c~ Thu Mar 12 04:31:17 1992 --- /usr/src/usr.bin/gdb/config/i386bsd-dep.c Thu Nov 26 02:49:36 1992 *************** *** 1743,1752 **** top = (ep->status >> 11) & 7; ! printf ("regno tag msb lsb value\n"); for (fpreg = 7; fpreg >= 0; fpreg--) { double val; ! printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); switch ((ep->tag >> (fpreg * 2)) & 3) --- 1743,1758 ---- top = (ep->status >> 11) & 7; ! printf (" regno tag msb lsb value\n"); for (fpreg = 7; fpreg >= 0; fpreg--) { + int st_regno; double val; ! /* The physical regno `fpreg' is only relevant as an index into the ! * tag word. Logical `%st' numbers are required for indexing `p->regs. ! */ ! st_regno = (fpreg + 8 - top) & 0x7; ! ! printf ("%%st(%d) %s ", st_regno, fpreg == top ? "=>" : " "); switch ((ep->tag >> (fpreg * 2)) & 3) *************** *** 1758,1766 **** } for (i = 9; i >= 0; i--) ! printf ("%02x", ep->regs[fpreg][i]); ! i387_to_double (ep->regs[fpreg], (char *)&val); printf (" %g\n", val); } if (ep->r0) printf ("warning: reserved0 is 0x%x\n", ep->r0); --- 1764,1773 ---- } for (i = 9; i >= 0; i--) ! printf ("%02x", ep->regs[st_regno][i]); ! i387_to_double (ep->regs[st_regno], (char *)&val); printf (" %g\n", val); } + #if 0 /* reserved fields are always 0xffff on 486's */ if (ep->r0) printf ("warning: reserved0 is 0x%x\n", ep->r0); *************** *** 1771,1776 **** --- 1778,1789 ---- if (ep->r3) printf ("warning: reserved3 is 0x%x\n", ep->r3); + #endif } + #ifdef __386BSD__ + #define fpstate save87 + #define U_FPSTATE(u) u.u_pcb.pcb_savefpu + #endif + #ifndef U_FPSTATE #define U_FPSTATE(u) u.u_fpstate *************** *** 1781,1785 **** struct user u; /* just for address computations */ int i; - #ifndef i386b /* fpstate defined in <sys/user.h> */ struct fpstate *fpstatep; --- 1794,1797 ---- *************** *** 1792,1795 **** --- 1804,1808 ---- int skip; + #ifndef __386BSD__ /* XXX - look at pcb flags */ uaddr = (char *)&u.u_fpvalid - (char *)&u; if (have_inferior_p()) *************** *** 1799,1803 **** rounded_addr = uaddr & -sizeof (int); ! data = ptrace (3, inferior_pid, rounded_addr, 0); mask = 0xff << ((uaddr - rounded_addr) * 8); --- 1812,1816 ---- rounded_addr = uaddr & -sizeof (int); ! data = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0); mask = 0xff << ((uaddr - rounded_addr) * 8); *************** *** 1818,1821 **** --- 1831,1835 ---- return; } + #endif /* not __386BSD__ */ uaddr = (char *)&U_FPSTATE(u) - (char *)&u; *************** *** 1832,1836 **** for (i = 0; i < rounded_size; i++) { ! *ip++ = ptrace (3, inferior_pid, rounded_addr, 0); rounded_addr += sizeof (int); } --- 1846,1850 ---- for (i = 0; i < rounded_size; i++) { ! *ip++ = ptrace (PT_READ_U, inferior_pid, (caddr_t)rounded_addr, 0); rounded_addr += sizeof (int); } *************** *** 1845,1848 **** --- 1859,1865 ---- } + #ifdef __386BSD__ + print_387_status (0, (struct env387 *)buf); + #else fpstatep = (struct fpstate *)(buf + skip); print_387_status (fpstatep->status, (struct env387 *)fpstatep->state); -- Bruce Evans (bde@runx.oz.au)