From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark Kettenis To: gdb-patches@sources.redhat.com Subject: [PATCH]: Add hardware watchpoint/breakpoint support for FreeBSD/i386 Date: Sat, 31 Mar 2001 10:18:00 -0000 Message-id: <200103311809.f2VI9KG00338@delius.kettenis.local> X-SW-Source: 2001-03/msg00578.html Checked in. Mark Index: ChangeLog from Mark Kettenis * i386bsd-nat.c: Include "gdb_assert.h". [HAVE_PT_GETDBREGS] (DBREG_DRX): Define if not already defined. [HAVE_PT_GETDBREGS] (i386bsd_dr_set, i386bsd_dr_set_control, i386bsd_dr_set_addr, i386bsd_dr_reset_addr, i386bsd_dr_get_status): New functions. * config/i386/nm-fbsd.h [HAVE_PT_GETDBREGS] (I386_USE_GENERIC_WATCHPOINTS): Define. Include "i386/nm-i386.h". (I386_DR_LOW_SET_CONTROL, I386_DR_LOW_SET_ADDR, I386_DR_LOW_RESET_ADDR, I386_DR_LOW_GET_STATUS): New macros. (i386bsd_dr_set_control, i386bsd_dr_set_addr, i386bsd_dr_reset_addr, i386bsd_dr_get_status): New prototypes. * acconfig.h (HAVE_PT_GETDBREGS): New configure macro. * configure.in: Cleanup a few comments. Check for PT_GETDBREGS ptrace request. * config.in, configure: Regenerate. Index: acconfig.h =================================================================== RCS file: /cvs/src/src/gdb/acconfig.h,v retrieving revision 1.15 diff -u -p -r1.15 acconfig.h --- acconfig.h 2001/03/19 05:46:26 1.15 +++ acconfig.h 2001/03/31 18:03:40 @@ -147,6 +147,9 @@ /* Define if defines the PTRACE_GETFPXREGS request. */ #undef HAVE_PTRACE_GETFPXREGS +/* Define if defines the PT_GETDBREGS request. */ +#undef HAVE_PT_GETDBREGS + /* Define if gnu-regex.c included with GDB should be used. */ #undef USE_INCLUDED_REGEX Index: configure.in =================================================================== RCS file: /cvs/src/src/gdb/configure.in,v retrieving revision 1.62 diff -u -p -r1.62 configure.in --- configure.in 2001/03/28 21:42:31 1.62 +++ configure.in 2001/03/31 18:03:40 @@ -135,7 +135,7 @@ AC_CHECK_FUNCS(setpgid sbrk sigaction is AC_FUNC_VFORK AC_FUNC_ALLOCA -# See if machine/reg.h supports the %fs and %gs i386 segment registers. +# See if supports the %fs and %gs i386 segment registers. # Older i386 BSD's don't have the r_fs and r_gs members of `struct reg'. AC_CACHE_CHECK([for r_fs in struct reg], gdb_cv_struct_reg_r_fs, [AC_TRY_COMPILE([#include ], [struct reg r; r.r_fs;], @@ -150,7 +150,7 @@ if test $gdb_cv_struct_reg_r_gs = yes; t AC_DEFINE(HAVE_STRUCT_REG_R_GS) fi -dnl See if ptrace.h provides the PTRACE_GETREGS request. +# See if provides the PTRACE_GETREGS request. AC_MSG_CHECKING(for PTRACE_GETREGS) AC_CACHE_VAL(gdb_cv_have_ptrace_getregs, [AC_TRY_COMPILE([#include ], @@ -162,7 +162,7 @@ if test $gdb_cv_have_ptrace_getregs = ye AC_DEFINE(HAVE_PTRACE_GETREGS) fi -dnl See if ptrace.h provides the PTRACE_GETFPXREGS request. +# See if provides the PTRACE_GETFPXREGS request. AC_MSG_CHECKING(for PTRACE_GETFPXREGS) AC_CACHE_VAL(gdb_cv_have_ptrace_getfpxregs, [AC_TRY_COMPILE([#include ], @@ -173,6 +173,20 @@ AC_MSG_RESULT($gdb_cv_have_ptrace_getfpx if test $gdb_cv_have_ptrace_getfpxregs = yes; then AC_DEFINE(HAVE_PTRACE_GETFPXREGS) fi + +# See if provides the PT_GETDBREGS request. +AC_MSG_CHECKING(for PT_GETDBREGS) +AC_CACHE_VAL(gdb_cv_have_pt_getdbregs, +[AC_TRY_COMPILE([#include +#include ], + [PT_GETDBREGS;], + [gdb_cv_have_pt_getdbregs=yes], + [gdb_cv_have_pt_getdbregs=no])]) +AC_MSG_RESULT($gdb_cv_have_pt_getdbregs) +if test $gdb_cv_have_pt_getdbregs = yes; then + AC_DEFINE(HAVE_PT_GETDBREGS) +fi + AC_CHECK_LIB(socket, socketpair) AC_CHECK_FUNCS(socketpair) Index: i386bsd-nat.c =================================================================== RCS file: /cvs/src/src/gdb/i386bsd-nat.c,v retrieving revision 1.5 diff -u -p -r1.5 i386bsd-nat.c --- i386bsd-nat.c 2001/03/01 01:39:20 1.5 +++ i386bsd-nat.c 2001/03/31 18:03:40 @@ -22,6 +22,7 @@ #include "inferior.h" #include "regcache.h" +#include "gdb_assert.h" #include #include #include @@ -213,6 +214,80 @@ store_inferior_registers (int regno) perror_with_name ("Couldn't write floating point status"); } } + + +/* Support for debug registers. */ + +#ifdef HAVE_PT_GETDBREGS + +/* Not all versions of FreeBSD/i386 that support the debug registers + have this macro. */ +#ifndef DBREG_DRX +#define DBREG_DRX(d, x) ((&d->dr0)[x]) +#endif + +static void +i386bsd_dr_set (int regnum, unsigned int value) +{ + struct dbreg dbregs; + + if (ptrace (PT_GETDBREGS, inferior_pid, (PTRACE_ARG3_TYPE) &dbregs, 0) == -1) + perror_with_name ("Couldn't get debug registers"); + + /* For some mysterious reason, some of the reserved bits in the + debug control register get set. Mask these off, otherwise the + ptrace call below will fail. */ + dbregs.dr7 &= ~(0x0000fc00); + + DBREG_DRX ((&dbregs), regnum) = value; + + if (ptrace (PT_SETDBREGS, inferior_pid, (PTRACE_ARG3_TYPE) &dbregs, 0) == -1) + perror_with_name ("Couldn't write debug registers"); +} + +void +i386bsd_dr_set_control (unsigned long control) +{ + i386bsd_dr_set (7, control); +} + +void +i386bsd_dr_set_addr (int regnum, CORE_ADDR addr) +{ + gdb_assert (regnum >= 0 && regnum <= 4); + + i386bsd_dr_set (regnum, addr); +} + +void +i386bsd_dr_reset_addr (int regnum) +{ + gdb_assert (regnum >= 0 && regnum <= 4); + + i386bsd_dr_set (regnum, 0); +} + +unsigned long +i386bsd_dr_get_status (void) +{ + struct dbreg dbregs; + + /* FIXME: kettenis/2001-03-31: Calling perror_with_name if the + ptrace call fails breaks debugging remote targets. The correct + way to fix this is to add the hardware breakpoint and watchpoint + stuff to the target vectore. For now, just return zero if the + ptrace call fails. */ + if (ptrace (PT_GETDBREGS, inferior_pid, (PTRACE_ARG3_TYPE) &dbregs, 0) == -1) +#if 0 + perror_with_name ("Couldn't read debug registers"); +#else + return 0; +#endif + + return dbregs.dr6; +} + +#endif /* PT_GETDBREGS */ /* Support for the user struct. */ Index: config/i386/nm-fbsd.h =================================================================== RCS file: /cvs/src/src/gdb/config/i386/nm-fbsd.h,v retrieving revision 1.3 diff -u -p -r1.3 nm-fbsd.h --- config/i386/nm-fbsd.h 2001/03/06 08:21:28 1.3 +++ config/i386/nm-fbsd.h 2001/03/31 18:03:40 @@ -1,5 +1,5 @@ /* Native-dependent definitions for FreeBSD/i386. - Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000 + Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. @@ -21,6 +21,31 @@ #ifndef NM_FBSD_H #define NM_FBSD_H + +#ifdef HAVE_PT_GETDBREGS +#define I386_USE_GENERIC_WATCHPOINTS +#endif + +#include "i386/nm-i386.h" + +/* Provide access to the i386 hardware debugging registers. */ + +#define I386_DR_LOW_SET_CONTROL(control) \ + i386bsd_dr_set_control (control) +extern void i386bsd_dr_set_control (unsigned long control); + +#define I386_DR_LOW_SET_ADDR(regnum, addr) \ + i386bsd_dr_set_addr (regnum, addr) +extern void i386bsd_dr_set_addr (int regnum, CORE_ADDR addr); + +#define I386_DR_LOW_RESET_ADDR(regnum) \ + i386bsd_dr_reset_addr (regnum) +extern void i386bsd_dr_reset_addr (int regnum); + +#define I386_DR_LOW_GET_STATUS() \ + i386bsd_dr_get_status () +extern unsigned long i386bsd_dr_get_status (void); + /* Type of the third argument to the `ptrace' system call. */ #define PTRACE_ARG3_TYPE caddr_t