Skip site navigation (1)Skip section navigation (2)
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>