diff options
author | Peter Schauer <Peter.Schauer@mytum.de> | 2000-04-13 18:11:41 +0000 |
---|---|---|
committer | Peter Schauer <Peter.Schauer@mytum.de> | 2000-04-13 18:11:41 +0000 |
commit | 14164c30b6b5ae623fd1cd75384179d9fef368d6 (patch) | |
tree | 0175426db93d3a1413cf09e375d8799bce41c2e6 /gdb | |
parent | db348f274580cbf2c07ab62ea3ff2a710709e076 (diff) | |
download | gdb-14164c30b6b5ae623fd1cd75384179d9fef368d6.zip gdb-14164c30b6b5ae623fd1cd75384179d9fef368d6.tar.gz gdb-14164c30b6b5ae623fd1cd75384179d9fef368d6.tar.bz2 |
* 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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/config/i386/nm-i386sol2.h | 10 | ||||
-rw-r--r-- | gdb/config/i386/tm-i386sol2.h | 1 | ||||
-rw-r--r-- | gdb/i386v4-nat.c | 88 |
4 files changed, 102 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a5a7685..318c1d3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/config/i386/nm-i386sol2.h b/gdb/config/i386/nm-i386sol2.h index 2c4b4d4..8f29711 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 da231eb..a15d812 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 10802cb..056ea7f 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 */ |