Date: Fri, 23 Sep 2011 02:48:30 GMT From: Ben Morrow <ben@morrow.me.uk> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/160930: [PATCH] devel/gdb: HW watchpoint support for amd64 Message-ID: <201109230248.p8N2mUwS084986@red.freebsd.org> Resent-Message-ID: <201109230250.p8N2o3B3031492@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 160930 >Category: ports >Synopsis: [PATCH] devel/gdb: HW watchpoint support for amd64 >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Sep 23 02:50:03 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Ben Morrow >Release: 8.2-RELEASE-p2 >Organization: >Environment: FreeBSD anubis.morrow.me.uk 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #7: Thu Jun 9 14:58:42 BST 2011 mauzo@anubis:/usr/obj/usr/src/sys/ANUBIS amd64 >Description: Currently gdb on amd64 has no support for hardware watchpoints. Since the hardware does actually support them, this is a little irritating. >How-To-Repeat: Set a watchpoint in gdb72 on amd64. It will be a software watchpoint, and the program being debugged will run extremely slowly. >Fix: The attached patch adds support. Patch attached with submission follows: diff -Naur devel/gdb.orig/Makefile devel/gdb/Makefile --- devel/gdb.orig/Makefile 2011-02-25 07:50:35.000000000 +0000 +++ devel/gdb/Makefile 2011-09-23 01:43:15.375784434 +0100 @@ -84,6 +84,7 @@ @${REINPLACE_CMD} -e 's/$$/ [GDB v${PORTVERSION} for FreeBSD]/' \ ${WRKSRC}/gdb/version.in @${CP} ${FILESDIR}/fbsd-threads.c ${WRKSRC}/gdb + @${CP} ${FILESDIR}/amd64bsd-nat.h ${WRKSRC}/gdb do-install: ${INSTALL_PROGRAM} ${WRKSRC}/gdb/gdb ${PREFIX}/bin/gdb${VER} diff -Naur devel/gdb.orig/files/amd64bsd-nat.h devel/gdb/files/amd64bsd-nat.h --- devel/gdb.orig/files/amd64bsd-nat.h 1970-01-01 01:00:00.000000000 +0100 +++ devel/gdb/files/amd64bsd-nat.h 2011-09-23 01:39:50.852195530 +0100 @@ -0,0 +1,38 @@ +/* Native-dependent code for amd64 BSD's. + + Copyright (C) 2011 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef AMD64BSD_NAT_H +#define AMD64BSD_NAT_H + +/* Create a prototype *BSD/amd64 target. The client can override it + with local methods. */ + +extern struct target_ops *amd64bsd_target (void); + +/* low level amd64 debug register functions used in amd64fbsd-nat.c. */ + +extern void amd64bsd_dr_set_control (unsigned long control); + +extern void amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr); + +extern void amd64bsd_dr_reset_addr (int regnum); + +extern unsigned long amd64bsd_dr_get_status (void); + +#endif /* amd64bsd-nat.h */ diff -Naur devel/gdb.orig/files/patch-gdb-Makefile.in devel/gdb/files/patch-gdb-Makefile.in --- devel/gdb.orig/files/patch-gdb-Makefile.in 2010-11-16 20:39:48.000000000 +0000 +++ devel/gdb/files/patch-gdb-Makefile.in 2011-09-23 01:41:43.239509675 +0100 @@ -1,6 +1,6 @@ ---- gdb/Makefile.in.orig 2010-02-02 18:16:53.000000000 -0500 -+++ gdb/Makefile.in 2010-10-13 16:09:43.312803000 -0400 -@@ -524,7 +524,7 @@ +--- gdb/Makefile.in.orig 2010-08-19 19:40:34.000000000 +0100 ++++ gdb/Makefile.in 2011-09-23 01:31:58.825043698 +0100 +@@ -546,7 +546,7 @@ xstormy16-tdep.o \ xtensa-config.o xtensa-tdep.o xtensa-linux-tdep.o \ glibc-tdep.o \ @@ -9,7 +9,16 @@ nbsd-tdep.o obsd-tdep.o \ sol2-tdep.o \ solib-frv.o solib-irix.o solib-svr4.o solib-target.o \ -@@ -720,7 +720,7 @@ +@@ -731,7 +731,7 @@ + osf-share/cma_deb_core.h osf-share/AT386/cma_thread_io.h \ + osf-share/cma_sched.h proc-utils.h arm-tdep.h ax-gdb.h ppcnbsd-tdep.h \ + cli-out.h gdb_expat.h breakpoint.h infcall.h obsd-tdep.h \ +-exec.h m32r-tdep.h osabi.h gdbcore.h solib-som.h \ ++exec.h m32r-tdep.h osabi.h gdbcore.h solib-som.h amd64bsd-nat.h \ + i386bsd-nat.h xml-support.h xml-tdesc.h alphabsd-tdep.h gdb_obstack.h \ + ia64-tdep.h ada-lang.h varobj.h frv-tdep.h nto-tdep.h serial.h \ + c-lang.h d-lang.h frame.h event-loop.h block.h cli/cli-setshow.h \ +@@ -744,7 +744,7 @@ gdbserver/linux-low.h gdbserver/gdb_proc_service.h \ gdbserver/regcache.h gdbthread.h dwarf2-frame.h nbsd-nat.h dcache.h \ amd64-nat.h s390-tdep.h arm-linux-tdep.h exceptions.h macroscope.h \ @@ -18,7 +27,7 @@ mdebugread.h m88k-tdep.h stabsread.h hppa-linux-offsets.h linux-fork.h \ ser-unix.h scm-lang.h inf-ptrace.h terminal.h ui-out.h frame-base.h \ f-lang.h dwarf2loc.h value.h sparc-tdep.h defs.h target-descriptions.h \ -@@ -1130,7 +1130,7 @@ +@@ -1161,7 +1161,7 @@ # Removing the old gdb first works better if it is running, at least on SunOS. gdb$(EXEEXT): gdb.o libgdb.a $(ADD_DEPS) $(CDEPS) $(TDEPLIBS) rm -f gdb$(EXEEXT) @@ -27,8 +36,8 @@ -o gdb$(EXEEXT) gdb.o libgdb.a \ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) -@@ -1402,7 +1402,7 @@ - arm-linux-nat.c arm-linux-tdep.c arm-tdep.c \ +@@ -1433,7 +1433,7 @@ + arm-linux-nat.c arm-linux-tdep.c arm-symbian-tdep.c arm-tdep.c \ armnbsd-nat.c armbsd-tdep.c armnbsd-tdep.c armobsd-tdep.c \ avr-tdep.c \ - bsd-uthread.c bsd-kvm.c \ diff -Naur devel/gdb.orig/files/patch-gdb-amd64-nat.h devel/gdb/files/patch-gdb-amd64-nat.h --- devel/gdb.orig/files/patch-gdb-amd64-nat.h 1970-01-01 01:00:00.000000000 +0100 +++ devel/gdb/files/patch-gdb-amd64-nat.h 2011-09-23 01:41:07.842903111 +0100 @@ -0,0 +1,12 @@ +--- gdb/amd64-nat.h.orig 2011-09-23 01:36:54.874780473 +0100 ++++ gdb/amd64-nat.h 2011-09-23 01:28:46.964218514 +0100 +@@ -50,9 +50,4 @@ + extern void amd64_collect_native_gregset (const struct regcache *regcache, + void *gregs, int regnum); + +-/* Create a prototype *BSD/amd64 target. The client can override it +- with local methods. */ +- +-extern struct target_ops *amd64bsd_target (void); +- + #endif /* amd64-nat.h */ diff -Naur devel/gdb.orig/files/patch-gdb-amd64bsd-nat.c devel/gdb/files/patch-gdb-amd64bsd-nat.c --- devel/gdb.orig/files/patch-gdb-amd64bsd-nat.c 1970-01-01 01:00:00.000000000 +0100 +++ devel/gdb/files/patch-gdb-amd64bsd-nat.c 2011-09-23 01:40:24.590895157 +0100 @@ -0,0 +1,91 @@ +--- gdb/amd64bsd-nat.c.orig 2011-09-23 01:35:24.211306143 +0100 ++++ gdb/amd64bsd-nat.c 2011-09-23 01:28:28.444487431 +0100 +@@ -33,6 +33,7 @@ + + #include "amd64-tdep.h" + #include "amd64-nat.h" ++#include "amd64bsd-nat.h" + #include "inf-ptrace.h" + + +@@ -126,3 +127,80 @@ + t->to_store_registers = amd64bsd_store_inferior_registers; + return t; + } ++ ++ ++/* 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 ++amd64bsd_dr_set (int regnum, unsigned long value) ++{ ++ struct dbreg dbregs; ++ ++ if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid), ++ (PTRACE_TYPE_ARG3) &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. */ ++ DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00); ++ ++ DBREG_DRX ((&dbregs), regnum) = value; ++ ++ if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid), ++ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) ++ perror_with_name (_("Couldn't write debug registers")); ++} ++ ++void ++amd64bsd_dr_set_control (unsigned long control) ++{ ++ amd64bsd_dr_set (7, control); ++} ++ ++void ++amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr) ++{ ++ gdb_assert (regnum >= 0 && regnum <= 4); ++ ++ amd64bsd_dr_set (regnum, addr); ++} ++ ++void ++amd64bsd_dr_reset_addr (int regnum) ++{ ++ gdb_assert (regnum >= 0 && regnum <= 4); ++ ++ amd64bsd_dr_set (regnum, 0); ++} ++ ++unsigned long ++amd64bsd_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 vector. For now, just return zero if the ++ ptrace call fails. */ ++ if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid), ++ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) ++#if 0 ++ perror_with_name (_("Couldn't read debug registers")); ++#else ++ return 0; ++#endif ++ ++ return DBREG_DRX ((&dbregs), 6); ++} ++ ++#endif /* PT_GETDBREGS */ diff -Naur devel/gdb.orig/files/patch-gdb-amd64fbsd-nat.c devel/gdb/files/patch-gdb-amd64fbsd-nat.c --- devel/gdb.orig/files/patch-gdb-amd64fbsd-nat.c 2010-11-16 20:39:48.000000000 +0000 +++ devel/gdb/files/patch-gdb-amd64fbsd-nat.c 2011-09-23 03:09:20.209594449 +0100 @@ -1,5 +1,5 @@ ---- gdb/amd64fbsd-nat.c.orig 2010-10-13 14:53:14.425152000 -0400 -+++ gdb/amd64fbsd-nat.c 2010-10-13 15:15:01.080198000 -0400 +--- gdb/amd64fbsd-nat.c.orig 2010-02-03 15:30:25.000000000 +0000 ++++ gdb/amd64fbsd-nat.c 2011-09-23 03:08:51.942111416 +0100 @@ -27,6 +27,7 @@ #include <signal.h> #include <stddef.h> @@ -8,7 +8,16 @@ #include <sys/ptrace.h> #include <sys/sysctl.h> #include <machine/reg.h> -@@ -92,6 +93,47 @@ +@@ -34,6 +35,8 @@ + #include "fbsd-nat.h" + #include "amd64-tdep.h" + #include "amd64-nat.h" ++#include "amd64bsd-nat.h" ++#include "i386-nat.h" + + + /* Offset in `struct reg' where MEMBER is stored. */ +@@ -92,6 +95,47 @@ }; @@ -56,3 +65,23 @@ /* Support for debugging kernel virtual memory images. */ #include <sys/types.h> +@@ -155,6 +199,19 @@ + + /* Add some extra features to the common *BSD/i386 target. */ + t = amd64bsd_target (); ++ ++#ifdef HAVE_PT_GETDBREGS ++ ++ i386_use_watchpoints (t); ++ ++ i386_dr_low.set_control = amd64bsd_dr_set_control; ++ i386_dr_low.set_addr = amd64bsd_dr_set_addr; ++ i386_dr_low.reset_addr = amd64bsd_dr_reset_addr; ++ i386_dr_low.get_status = amd64bsd_dr_get_status; ++ i386_set_debug_register_length (8); ++ ++#endif /* HAVE_PT_GETDBREGS */ ++ + t->to_pid_to_exec_file = fbsd_pid_to_exec_file; + t->to_find_memory_regions = fbsd_find_memory_regions; + t->to_make_corefile_notes = fbsd_make_corefile_notes; diff -Naur devel/gdb.orig/files/patch-gdb-config-i386-fbsd64.mh devel/gdb/files/patch-gdb-config-i386-fbsd64.mh --- devel/gdb.orig/files/patch-gdb-config-i386-fbsd64.mh 1970-01-01 01:00:00.000000000 +0100 +++ devel/gdb/files/patch-gdb-config-i386-fbsd64.mh 2011-09-23 03:16:21.204024239 +0100 @@ -0,0 +1,10 @@ +--- gdb/config/i386/fbsd64.mh.orig 2011-09-23 03:15:43.254648862 +0100 ++++ gdb/config/i386/fbsd64.mh 2011-09-23 03:14:06.843804785 +0100 +@@ -1,6 +1,6 @@ + # Host: FreeBSD/amd64 + NATDEPFILES= fork-child.o inf-ptrace.o \ +- fbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o \ ++ fbsd-nat.o i386-nat.o amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o \ + bsd-kvm.o + + LOADLIBES= -lkvm >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201109230248.p8N2mUwS084986>