* config/i386/nm-i386sol2.h (CANNOT_STEP_HW_WATCHPOINTS): Define.
authorPeter Schauer <Peter.Schauer@mytum.de>
Thu, 13 Apr 2000 18:11:41 +0000 (18:11 +0000)
committerPeter Schauer <Peter.Schauer@mytum.de>
Thu, 13 Apr 2000 18:11:41 +0000 (18:11 +0000)
* 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.

gdb/ChangeLog
gdb/config/i386/nm-i386sol2.h
gdb/config/i386/tm-i386sol2.h
gdb/i386v4-nat.c

index a5a76855b87ef93725173abd257971cc0cb1ec56..318c1d36f3efa6d644c6fc0ea2b1a938c9003ad4 100644 (file)
@@ -1,3 +1,10 @@
+2000-04-13  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>
+
+       * 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  <nsd@cygnus.com>
 
        * sol-thread.c (init_sol_core_ops): Initialize to_thread_alive
index 2c4b4d4578e63a975d7b20af4b6dc669c5890780..8f29711e7fbf4f7a35719e77072b699406148d14 100644 (file)
    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)
index da231eb830124acd30c02b11228d2b963d52fe2f..a15d8125a421d3f5e09e33e550a9a960cfe320a3 100644 (file)
@@ -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
index 10802cb730b8d88183b33711f799916b5351ab75..056ea7f3ba21c1427f86b739387344803c746f58 100644 (file)
@@ -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 *) &registers[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 */