From: Peter Schauer Date: Thu, 13 Apr 2000 18:11:41 +0000 (+0000) Subject: * config/i386/nm-i386sol2.h (CANNOT_STEP_HW_WATCHPOINTS): Define. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=bdcf2d0a1914daecdbf9aa76ded4860a4c7a5e8e;p=pf3gnuchains%2Fpf3gnuchains3x.git * config/i386/nm-i386sol2.h (CANNOT_STEP_HW_WATCHPOINTS): Define. * config/i386/tm-i386sol2.h (HAVE_I387_REGS): Define. * i386v4-nat.c (supply_fpregset, fill_fpregset): Add code to handle floating point registers if NUM_FREGS is not zero. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a5a76855b8..318c1d36f3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2000-04-13 Peter Schauer + + * config/i386/nm-i386sol2.h (CANNOT_STEP_HW_WATCHPOINTS): Define. + * config/i386/tm-i386sol2.h (HAVE_I387_REGS): Define. + * i386v4-nat.c (supply_fpregset, fill_fpregset): Add code + to handle floating point registers if NUM_FREGS is not zero. + 2000-04-13 Nick Duffek * sol-thread.c (init_sol_core_ops): Initialize to_thread_alive diff --git a/gdb/config/i386/nm-i386sol2.h b/gdb/config/i386/nm-i386sol2.h index 2c4b4d4578..8f29711e7f 100644 --- a/gdb/config/i386/nm-i386sol2.h +++ b/gdb/config/i386/nm-i386sol2.h @@ -34,6 +34,16 @@ It will *NOT* be necessary for GDB to step over the watchpoint. */ #define HAVE_CONTINUABLE_WATCHPOINT +/* Solaris x86 2.6 and 2.7 targets have a kernel bug when stepping + over an instruction that causes a page fault without triggering + a hardware watchpoint. The kernel properly notices that it shouldn't + stop, because the hardware watchpoint is not triggered, but it forgets + the step request and continues the program normally. + Work around the problem by removing hardware watchpoints if a step is + requested, GDB will check for a hardware watchpoint trigger after the + step anyway. */ +#define CANNOT_STEP_HW_WATCHPOINTS + extern int procfs_stopped_by_watchpoint PARAMS ((int)); #define STOPPED_BY_WATCHPOINT(W) \ procfs_stopped_by_watchpoint(inferior_pid) diff --git a/gdb/config/i386/tm-i386sol2.h b/gdb/config/i386/tm-i386sol2.h index da231eb830..a15d8125a4 100644 --- a/gdb/config/i386/tm-i386sol2.h +++ b/gdb/config/i386/tm-i386sol2.h @@ -21,6 +21,7 @@ #ifndef TM_I386SOL2_H #define TM_I386SOL2_H 1 +#define HAVE_I387_REGS #include "i386/tm-i386v4.h" /* Signal handler frames under Solaris 2 are recognized by a return address diff --git a/gdb/i386v4-nat.c b/gdb/i386v4-nat.c index 10802cb730..056ea7f3ba 100644 --- a/gdb/i386v4-nat.c +++ b/gdb/i386v4-nat.c @@ -142,17 +142,65 @@ fill_gregset (gregsetp, regno) #endif /* HAVE_GREGSET_T */ -#if defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T) +#if defined (HAVE_FPREGSET_T) /* Given a pointer to a floating point register set in /proc format (fpregset_t *), unpack the register contents and supply them as gdb's idea of the current floating point register values. */ +/* FIXME: Assumes that fpregsetp contains an i387 FSAVE area. */ +static const int freg_offset_map[] = +{ +#if !defined(FPREGSET_FSAVE_OFFSET) +#define FPREGSET_FSAVE_OFFSET 0 +#endif + FPREGSET_FSAVE_OFFSET + 28 + 0 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 1 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 2 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 3 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 4 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 5 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 6 * 10, + FPREGSET_FSAVE_OFFSET + 28 + 7 * 10, + FPREGSET_FSAVE_OFFSET + 0, + FPREGSET_FSAVE_OFFSET + 4, + FPREGSET_FSAVE_OFFSET + 8, + FPREGSET_FSAVE_OFFSET + 16, + FPREGSET_FSAVE_OFFSET + 12, + FPREGSET_FSAVE_OFFSET + 24, + FPREGSET_FSAVE_OFFSET + 20, + FPREGSET_FSAVE_OFFSET + 16 +}; + void supply_fpregset (fpregsetp) fpregset_t *fpregsetp; { - /* FIXME: see m68k-tdep.c for an example, for the m68k. */ + int regi; + + if (NUM_FREGS == 0) + return; + for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++) + { + char tbuf[4]; + ULONGEST tval; + char *from = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM]; + + if (regi == FCS_REGNUM) + { + tval = extract_unsigned_integer (from, 4) & 0xffff; + store_unsigned_integer (tbuf, 4, tval); + supply_register (regi, tbuf); + } + else if (regi == FOP_REGNUM) + { + tval = (extract_unsigned_integer (from, 4) >> 16) & ((1 << 11) - 1); + store_unsigned_integer (tbuf, 4, tval); + supply_register (regi, tbuf); + } + else + supply_register (regi, from); + } } /* Given a pointer to a floating point register set in /proc format @@ -165,9 +213,41 @@ fill_fpregset (fpregsetp, regno) fpregset_t *fpregsetp; int regno; { - /* FIXME: see m68k-tdep.c for an example, for the m68k. */ + int regi; + + if (NUM_FREGS == 0) + return; + for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++) + { + if ((regno == -1) || (regno == regi)) + { + char *to = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM]; + char *from = (char *) ®isters[REGISTER_BYTE (regi)]; + ULONGEST valto; + ULONGEST valfrom; + + if (regi == FCS_REGNUM) + { + valto = extract_unsigned_integer (to, 4); + valfrom = extract_unsigned_integer (from, 4); + valto = (valto & ~0xffff) | (valfrom & 0xffff); + store_unsigned_integer (to, 4, valto); + } + else if (regi == FOP_REGNUM) + { + valto = extract_unsigned_integer (to, 4); + valfrom = extract_unsigned_integer (from, 4); + valto = (valto & 0xffff) | ((valfrom & ((1 << 11) - 1)) << 16); + store_unsigned_integer (to, 4, valto); + } + else + { + memcpy (to, from, REGISTER_RAW_SIZE (regi)); + } + } + } } -#endif /* defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T) */ +#endif /* defined (HAVE_FPREGSET_T) */ #endif /* HAVE_SYS_PROCFS_H */