Subject: Hardware watchpoint support for NetBSD/pc532
To: None <port-pc532@NetBSD.ORG>
From: Phil Budne <budd@cs.bu.edu>
List: port-pc532
Date: 11/26/1997 23:31:27
Here is what I've have working for using the ns32532 hardware
breakpoint regs from gdb on the pc532 under NetBSD.

It's not well tested, but it seems to work for simple tests.  The
kernel interface is primative (read write of h/w registers in pcb;
IRIX appears to support a more abstract interface in their /proc fs).

The debug registers are visible in /procfs as well as from ptrace().

Limitations;
	only one address register on 32532
	does not use PC compare register
	requires changes to machine independant ptrace code 
		(support for  could be added for i386
		 which has 4? address compare regs)
	does not trap access from kernel mode
	gdb support needs work
	some places abbreviate breakpoint as bkpt other as bpt
		could use cleanup!!

The following shar contains 3 files;

	kernel diffs (from kernel sources sup'ed 10/22, less
		changes to allow them to compile that have
		since been fixed)
	a new kernel file /sys/miscfs/procfs/procfs_bptregs.c
	diffs to gdb (sources sup'ed 11/23)
		first change to ns32knbsd-nat.c needed
		to get it to compile (without warnings)

Other good news;
	I was able to cleanly build libc from 11/23 sup'ed sources!

Unrelated strangeness;
	My pc532 locks up if console port left dangling
		attaching to console port shows repeated
		"getty repeating too quickly" messages,
		cannot get login prompt.
	"halt" often hangs after "syncing disks" message

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  sys-971022.diffs procfs_bptregs.c gdb.diffs
# Wrapped by phil@home on Wed Nov 26 23:15:04 1997
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sys-971022.diffs' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sys-971022.diffs'\"
else
echo shar: Extracting \"'sys-971022.diffs'\" \(11952 characters\)
sed "s/^X//" >'sys-971022.diffs' <<'END_OF_FILE'
X===== sys-971022/conf/files
X*** sys-971022/conf/files.0	Sat Oct 18 15:25:09 1997
X***************
X*** 307,312 ****
X--- 307,313 ----
X  file miscfs/nullfs/null_vnops.c		nullfs
X  file miscfs/portal/portal_vfsops.c	portal
X  file miscfs/portal/portal_vnops.c	portal
X+ file miscfs/procfs/procfs_bptregs.c
X  file miscfs/procfs/procfs_ctl.c		procfs
X  file miscfs/procfs/procfs_fpregs.c
X  file miscfs/procfs/procfs_mem.c
X===== sys-971022/kern/sys_process.c
X*** sys-971022/kern/sys_process.c.0	Mon Apr 28 07:21:49 1997
X***************
X*** 163,168 ****
X--- 163,177 ----
X  #ifdef PT_SETFPREGS
X  	case  PT_SETFPREGS:
X  #endif
X+ #ifdef PT_GETBKPTS
X+ 	case  PT_GETBKPTS:
X+ #endif
X+ #ifdef PT_SETBKPTS
X+ 	case  PT_SETBKPTS:
X+ #endif
X+ #ifdef PT_CLRBKPTS
X+ 	case  PT_CLRBKPTS:
X+ #endif
X  		/*
X  		 * You can't do what you want to the process if:
X  		 *	(1) It's not being traced at all,
X***************
X*** 368,373 ****
X--- 377,414 ----
X  			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
X  			uio.uio_procp = p;
X  			return (procfs_dofpregs(p, t, NULL, &uio));
X+ 		}
X+ #endif
X+ #ifdef PT_SETBKPTS
X+ 	case  PT_SETBKPTS:
X+ 		write = 1;
X+ #endif
X+ #ifdef PT_GETBKPTS
X+ 	case  PT_GETBKPTS:
X+ 		/* write = 0 done above. */
X+ #endif
X+ #if defined(PT_SETBKPTS) || defined(PT_GETBKPTS)
X+ 		if (!procfs_validbptregs(t))
X+ 			return (EINVAL);
X+ 		else {
X+ 			iov.iov_base = SCARG(uap, addr);
X+ 			iov.iov_len = sizeof(struct bkptreg);
X+ 			uio.uio_iov = &iov;
X+ 			uio.uio_iovcnt = 1;
X+ 			uio.uio_offset = 0;
X+ 			uio.uio_resid = sizeof(struct bkptreg);
X+ 			uio.uio_segflg = UIO_USERSPACE;
X+ 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
X+ 			uio.uio_procp = p;
X+ 			return (procfs_dobptregs(p, t, NULL, &uio));
X+ 		}
X+ #endif
X+ #ifdef PT_CLRBKPTS
X+ 	    case PT_CLRBKPTS:
X+ 		if (!procfs_validbptregs(t))
X+ 			return (EINVAL);
X+ 		else {
X+ 			return (procfs_clrbptregs(p, t, NULL));
X  		}
X  #endif
X  	}
X===== sys-971022/miscfs/procfs/procfs_subr.c
X*** sys-971022/miscfs/procfs/procfs_subr.c.0	Wed Aug 13 07:21:48 1997
X***************
X*** 153,158 ****
X--- 157,163 ----
X  	case Pmem:	/* /proc/N/mem = -rw------- */
X  	case Pregs:	/* /proc/N/regs = -rw------- */
X  	case Pfpregs:	/* /proc/N/fpregs = -rw------- */
X+ 	case Pbptregs:	/* /proc/N/bptregs = -rw------- */
X  		pfs->pfs_mode = S_IRUSR|S_IWUSR;
X  		vp->v_type = VREG;
X  		break;
X***************
X*** 227,232 ****
X--- 232,238 ----
X  	case Pregs:
X  	case Pfpregs:
X  	case Pmem:
X+ 	case Pbptregs:
X  		/*
X  		 * Do not allow init to be modified while in secure mode; it
X  		 * could be duped into changing the security level.
X***************
X*** 259,264 ****
X--- 265,273 ----
X  
X  	case Pmem:
X  		return (procfs_domem(curp, p, pfs, uio));
X+ 
X+ 	case Pbptregs:
X+ 		return (procfs_dobptregs(curp, p, pfs, uio));
X  
X  	default:
X  		return (EOPNOTSUPP);
X===== sys-971022/miscfs/procfs/procfs_vnops.c
X*** sys-971022/miscfs/procfs/procfs_vnops.c.0	Fri Oct 10 08:26:28 1997
X***************
X*** 93,98 ****
X--- 93,99 ----
X  	{ DT_REG, N("status"),	Pstatus,	NULL },
X  	{ DT_REG, N("note"),	Pnote,		NULL },
X  	{ DT_REG, N("notepg"),	Pnotepg,	NULL },
X+ 	{ DT_REG, N("bptregs"),	Pbptregs,	procfs_validbptregs },
X  #undef N
X  };
X  static int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]);
X***************
X*** 508,513 ****
X--- 509,515 ----
X  	case Pmem:
X  	case Pregs:
X  	case Pfpregs:
X+ 	case Pbptregs:
X  		/*
X  		 * If the process has exercised some setuid or setgid
X  		 * privilege, then rip away read/write permission so
X***************
X*** 596,601 ****
X--- 598,609 ----
X  	case Pnotepg:
X  		vap->va_bytes = vap->va_size = 0;
X  		break;
X+ 
X+ #if defined(PT_GETBKPTS) || defined(PT_SETBKPTS)
X+ 	case Pbptregs:
X+ 		vap->va_bytes = vap->va_size = sizeof(struct bkptreg);
X+ 		break;
X+ #endif
X  
X  	default:
X  		panic("procfs_getattr");
X===== sys-971022/miscfs/procfs/procfs.h
X*** sys-971022/miscfs/procfs/procfs.h.0	Wed Aug 27 07:43:25 1997
X***************
X*** 53,59 ****
X  	Pctl,		/* process control */
X  	Pstatus,	/* process status */
X  	Pnote,		/* process notifier */
X! 	Pnotepg		/* process group notifier */
X  } pfstype;
X  
X  /*
X--- 53,60 ----
X  	Pctl,		/* process control */
X  	Pstatus,	/* process status */
X  	Pnote,		/* process notifier */
X! 	Pnotepg,	/* process group notifier */
X! 	Pbptregs	/* hardware breakpoint registers */
X  } pfstype;
X  
X  /*
X***************
X*** 112,117 ****
X--- 113,120 ----
X  int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
X  int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
X  int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
X+ int procfs_dobptregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
X+ int procfs_clrbptregs __P((struct proc *, struct proc *, struct pfsnode *pfsp));
X  
X  int procfs_checkioperm __P((struct proc *p, struct proc *t));
X  
X***************
X*** 119,124 ****
X--- 122,128 ----
X  int procfs_validfile __P((struct proc *));
X  int procfs_validfpregs __P((struct proc *));
X  int procfs_validregs __P((struct proc *));
X+ int procfs_validbptregs __P((struct proc *));
X  
X  int procfs_rw __P((void *));
X  
X===== sys-971022/sys/ptrace.h
X*** sys-971022/sys/ptrace.h.0	Sat Feb 10 07:34:31 1996
X***************
X*** 82,87 ****
X--- 82,99 ----
X  
X  int	trace_req __P((struct proc *));
X  
X+ #ifdef PT_GETBKPTS
X+ int	process_read_bptregs __P((struct proc *p, struct bkptreg *regs));
X+ #endif
X+ 
X+ #ifdef PT_SETBKPTS
X+ int	process_write_bptregs __P((struct proc *p, struct bkptreg *regs));
X+ #endif
X+ 
X+ #ifdef PT_CLRBKPTS
X+ int	process_clear_bptregs __P((struct proc *p));
X+ #endif
X+ 
X  #else /* !_KERNEL */
X  
X  #include <sys/cdefs.h>
X===== sys-971022/arch/pc532/include/pcb.h
X*** sys-971022/arch/pc532/include/pcb.h.0	Thu Apr  4 07:30:00 1996
X***************
X*** 48,53 ****
X--- 48,55 ----
X   *
X   */
X  
X+ #include <machine/reg.h>		/* for struct bkptreg */
X+ 
X  struct pcb {
X  	/* Put in a pointer to the trap/interrupt frame. */
X  	struct reg *pcb_onstack;
X***************
X*** 61,66 ****
X--- 63,70 ----
X  	long pcb_ksp;		/* Kernel stack -- sp0. */
X  	long pcb_kfp;		/* Kernel fp. */
X  	long pcb_ptb;		/* ptb0, ptb1 */
X+ 
X+ 	struct bkptreg pcb_bkpt; /* breakpoint regs */
X  
X  /*
X   * Software pcb (extension)
X===== sys-971022/arch/pc532/include/reg.h
X*** sys-971022/arch/pc532/include/reg.h.0	Thu Apr  4 07:30:00 1996
X***************
X*** 93,96 ****
X--- 93,141 ----
X  	int    r_fsr;
X  	double r_freg[8];
X  };
X+ 
X+ /* phil budne 9/11/97; */
X+ struct bkptreg {
X+ 	int	r_dcr;			/* debug condition register */
X+ 	int	r_dsr;			/* debug status register (needed?) */
X+ 	int	r_car;			/* compare address register */
X+ 	int	r_bpc;			/* breakpoint program counter */
X+ };
X+ 
X+ /*
X+  * debug condition register
X+  */
X+ 
X+ #define DCR_RSVD 0xff01fe00
X+ 
X+ /* enables; */
X+ #define DCR_DEN  0x00800000		/* enable debug conditions */
X+ #define DCR_SD	 0x00400000		/* enable debug in supervisor mode */
X+ #define DCR_UD	 0x00200000		/* enable debug in user mode */
X+ #define DCR_PCE	 0x00100000		/* PC-match enable */
X+ #define DCR_TR	 0x00080000		/* enable trap (T_DBG) */
X+ 
X+ /* NS32532 implementation specific; */
X+ #define DCR_BCP	 0x00040000		/* [532] branch cond predict disable */
X+ #define DCR_SI	 0x00020000		/* [532] single-instruction mode */
X+ #define DCR_BF	 0x00000100		/* [532] bus-iface FIFO disable */
X+ 
X+ #define DCR_CAE	 0x00000080		/* address-compare enable */
X+ #define DCR_CRD	 0x00000040		/* address-compare enable for read */
X+ #define DCR_CWR	 0x00000020		/* address-compare enable for write */
X+ #define DCR_VNP	 0x00000010		/* compare virtual (vs. physical) */
X+ #define DCR_CBE3 0x00000008		/* compare byte enable 3 */
X+ #define DCR_CBE2 0x00000004		/* compare byte enable 2 */
X+ #define DCR_CBE1 0x00000002		/* compare byte enable 1 */
X+ #define DCR_CBE0 0x00000001		/* compare byte enable 0 */
X+ 
X+ /*
X+  * debug status register
X+  */
X+ 
X+ #define DSR_RD	0x80000000		/* last address-compare cond was rd */
X+ #define DSR_BPC	0x40000000		/* pc-match condition detected */
X+ #define DSR_BEX	0x20000000		/* external condition detected */
X+ #define DSR_BCA	0x10000000		/* address-compare cond detected */
X+ 
X  #endif /* _MACHINE_REG_H_ */
X===== sys-971022/arch/pc532/include/ptrace.h
X*** sys-971022/arch/pc532/include/ptrace.h.0	Fri Oct 13 22:13:35 1995
X***************
X*** 38,40 ****
X--- 38,43 ----
X  #define	PT_SETREGS	(PT_FIRSTMACH + 2)
X  #define	PT_GETFPREGS	(PT_FIRSTMACH + 3)
X  #define	PT_SETFPREGS	(PT_FIRSTMACH + 4)
X+ #define	PT_SETBKPTS	(PT_FIRSTMACH + 5)
X+ #define	PT_GETBKPTS	(PT_FIRSTMACH + 6)
X+ #define	PT_CLRBKPTS	(PT_FIRSTMACH + 7)
X===== sys-971022/arch/pc532/pc532/process_machdep.c
X*** sys-971022/arch/pc532/pc532/process_machdep.c.0	Thu Apr  4 07:30:06 1996
X***************
X*** 174,176 ****
X--- 174,229 ----
X  
X  	return (0);
X  }
X+ 
X+ int
X+ process_read_bptregs(p, regs)
X+ 	struct proc *p;
X+ 	struct bkptreg *regs;
X+ {
X+ 	*regs = p->p_addr->u_pcb.pcb_bkpt;
X+ 
X+ 	return (0);
X+ }
X+ 
X+ int
X+ process_write_bptregs(p, regs)
X+ 	struct proc *p;
X+ 	struct bkptreg *regs;
X+ {
X+ 	struct bkptreg new;
X+ 
X+ 	if ((p->p_flag & P_INMEM) == 0)
X+ 		return (EIO);
X+ 
X+ 	new = *regs;
X+ 
X+ 	if (new.r_dcr & DCR_RSVD)
X+ 		return (EPERM);		/* writing reserved bits? */
X+ 
X+ 	if (new.r_dcr != 0)
X+ 		new.r_dcr |= DCR_VNP;	/* force virtual on if any bits set */
X+ 
X+ 	if (new.r_dcr & (DCR_BF|DCR_SI|DCR_BCP))
X+ 		return (EPERM);		/* disallow '532 sys debug features */
X+ 
X+ 	if (new.r_dcr & DCR_SD)
X+ 		return (EPERM);		/* disallow supervisor mode! */
X+ 
X+ 	if (new.r_car & 0x3)
X+ 		return (EFAULT);	/* bad address */
X+ 
X+ 	p->p_addr->u_pcb.pcb_bkpt = new;
X+ 
X+ 	return (0);
X+ }
X+ 
X+ int
X+ process_clear_bptregs(p)
X+ 	struct proc *p;
X+ {
X+ 	if ((p->p_flag & P_INMEM) == 0)
X+ 		return (EIO);
X+ 
X+ 	bzero(&p->p_addr->u_pcb.pcb_bkpt, sizeof(p->p_addr->u_pcb.pcb_bkpt));
X+ 	return (0);
X+ }
X===== sys-971022/arch/pc532/pc532/genassym.cf
X*** sys-971022/arch/pc532/pc532/genassym.cf.0	Sat Feb  8 07:19:09 1997
X***************
X*** 91,96 ****
X--- 91,100 ----
X  define	PCB_F5			offsetof(struct pcb, pcb_freg[5])
X  define	PCB_F6			offsetof(struct pcb, pcb_freg[6])
X  define	PCB_F7			offsetof(struct pcb, pcb_freg[7])
X+ define	PCB_DCR			offsetof(struct pcb, pcb_bkpt.r_dcr)
X+ define	PCB_DSR			offsetof(struct pcb, pcb_bkpt.r_dsr)
X+ define	PCB_CAR			offsetof(struct pcb, pcb_bkpt.r_car)
X+ define	PCB_BPC			offsetof(struct pcb, pcb_bkpt.r_bpc)
X  
X  define	REGS_USP		offsetof(struct reg, r_sp)
X  define	REGS_FP 		offsetof(struct reg, r_fp)
X===== sys-971022/arch/pc532/pc532/locore.s
X*** sys-971022/arch/pc532/pc532/locore.s.0	Fri May  9 07:21:48 1997
X***************
X*** 727,732 ****
X--- 727,738 ----
X  	sprd	sp,PCB_KSP(r4)
X  	sprd	fp,PCB_KFP(r4)
X  
X+ 	/* save debug registers */
X+ 	sprd	dcr,PCB_DCR(r4)
X+ 	sprd	dsr,PCB_DSR(r4)
X+ 	sprd	car,PCB_CAR(r4)
X+ 	sprd	bpc,PCB_BPC(r4)
X+ 
X  ASLOCAL(switch_exited)
X  	/*
X  	 * Third phase: restore saved context.
X***************
X*** 748,753 ****
X--- 754,767 ----
X  	lprd	sp,PCB_KSP(r1)
X  	lprd	fp,PCB_KFP(r1)
X  
X+ #if 1
X+ 	/* Load debug registers */
X+ 	lprd	dcr,PCB_DCR(r1)
X+ 	lprd	dsr,PCB_DSR(r1)
X+ 	lprd	car,PCB_CAR(r1)
X+ 	lprd	bpc,PCB_BPC(r1)
X+ #endif
X+ 	
X  	/* Record new pcb. */
X  	movd	r1,_C_LABEL(curpcb)(pc)
X  
END_OF_FILE
if test 11952 -ne `wc -c <'sys-971022.diffs'`; then
    echo shar: \"'sys-971022.diffs'\" unpacked with wrong size!
fi
# end of 'sys-971022.diffs'
fi
if test -f 'procfs_bptregs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'procfs_bptregs.c'\"
else
echo shar: Extracting \"'procfs_bptregs.c'\" \(3639 characters\)
sed "s/^X//" >'procfs_bptregs.c' <<'END_OF_FILE'
X/*	$NetBSD: procfs_bptregs.c,v 1.6 1997/08/27 08:52:52 thorpej Exp $	*/
X
X/*
X * September 14, 1997
X * from procfs_fpregs 1.6
X *
X * Copyright (c) 1993 Jan-Simon Pendry
X * Copyright (c) 1993
X *	The Regents of the University of California.  All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Jan-Simon Pendry.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X *    must display the following acknowledgement:
X *	This product includes software developed by the University of
X *	California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X *    may be used to endorse or promote products derived from this software
X *    without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X *	@(#)procfs_fpregs.c	8.2 (Berkeley) 6/15/94
X */
X
X#include <sys/param.h>
X#include <sys/systm.h>
X#include <sys/time.h>
X#include <sys/kernel.h>
X#include <sys/proc.h>
X#include <sys/vnode.h>
X#include <sys/ptrace.h>
X#include <machine/reg.h>
X#include <miscfs/procfs/procfs.h>
X
Xint
Xprocfs_dobptregs(curp, p, pfs, uio)
X	struct proc *curp;		/* tracer */
X	struct proc *p;			/* traced */
X	struct pfsnode *pfs;
X	struct uio *uio;
X{
X#if defined(PT_GETBKPTS) || defined(PT_SETBKPTS)
X	int error;
X	struct bkptreg r;
X	char *kv;
X	int kl;
X
X	if ((error = procfs_checkioperm(curp, p)) != 0)
X		return (error);
X
X	kl = sizeof(r);
X	kv = (char *) &r;
X
X	kv += uio->uio_offset;
X	kl -= uio->uio_offset;
X	if (kl > uio->uio_resid)
X		kl = uio->uio_resid;
X
X	PHOLD(p);
X
X	if (kl < 0)
X		error = EINVAL;
X	else
X		error = process_read_bptregs(p, &r);
X	if (error == 0)
X		error = uiomove(kv, kl, uio);
X	if (error == 0 && uio->uio_rw == UIO_WRITE) {
X		if (p->p_stat != SSTOP)
X			error = EBUSY;
X		else
X			error = process_write_bptregs(p, &r);
X	}
X
X	PRELE(p);
X
X	uio->uio_offset = 0;
X	return (error);
X#else
X	return (EINVAL);
X#endif
X}
X
Xint
Xprocfs_validbptregs(p)
X	struct proc *p;
X{
X#if defined(PT_SETBKPTS) || defined(PT_GETBKPTS)
X	return ((p->p_flag & P_SYSTEM) == 0);
X#else
X	return (0);
X#endif
X}
X
X#ifdef PT_CLRBKPTS
Xint
Xprocfs_clrbptregs(curp, p, pfs)
X	struct proc *curp;		/* tracer */
X	struct proc *p;			/* traced */
X	struct pfsnode *pfs;
X{
X	int error;
X
X	if ((error = procfs_checkioperm(curp, p)) != 0)
X		return (error);
X
X
X	PHOLD(p);
X	error = process_clear_bptregs(p);
X	PRELE(p);
X
X	return (error);
X}
X#endif
END_OF_FILE
if test 3639 -ne `wc -c <'procfs_bptregs.c'`; then
    echo shar: \"'procfs_bptregs.c'\" unpacked with wrong size!
fi
# end of 'procfs_bptregs.c'
fi
if test -f 'gdb.diffs' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gdb.diffs'\"
else
echo shar: Extracting \"'gdb.diffs'\" \(3922 characters\)
sed "s/^X//" >'gdb.diffs' <<'END_OF_FILE'
X===== gdb/config/ns32k/nm-nbsd.h
X*** gdb/config/ns32k/nm-nbsd.h.0	Fri Sep 26 07:10:35 1997
X***************
X*** 27,30 ****
X--- 27,52 ----
X  #define FLOAT_INFO	{ extern ns32k_float_info(); ns32k_float_info(); }
X  #endif
X  
X+ /* NetBSD supports the 32532 hardware debugging registers.  */
X+ 
X+ #define TARGET_HAS_HARDWARE_WATCHPOINTS
X+ 
X+ #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
X+ 
X+ /* After a watchpoint trap, the PC points to the instruction after
X+    the one that caused the trap.  Therefore we don't need to step over it.
X+    But we do need to reset the status register to avoid another trap.  */
X+ #define HAVE_CONTINUABLE_WATCHPOINT	/* ??? */
X+ 
X+ #define STOPPED_BY_WATCHPOINT(W)  \
X+   ns32k_stopped_by_watchpoint (inferior_pid)
X+ 
X+ /* Use these macros for watchpoint insertion/removal.  */
X+ 
X+ #define target_insert_watchpoint(addr, len, type)  \
X+   ns32k_insert_watchpoint (inferior_pid, addr, len, 2)
X+ 
X+ #define target_remove_watchpoint(addr, len, type)  \
X+   ns32k_remove_watchpoint (inferior_pid, addr, len)
X+ 
X  #endif /* NM_NBSD_H */
X===== gdb/ns32knbsd-nat.c
X*** gdb/ns32knbsd-nat.c.0	Fri Sep 26 07:10:21 1997
X***************
X*** 191,201 ****
X    int dummy;
X  
X    /* Integer registers */
X!   if (target_read_memory(pcb->pcb_ksp, &sf, sizeof sf))
X       error("Cannot read integer registers.");
X  
X    /* We use the psr at kernel entry */
X!   if (target_read_memory(pcb->pcb_onstack, &intreg, sizeof intreg))
X       error("Cannot read processor status register.");
X  
X    dummy = 0;
X--- 191,201 ----
X    int dummy;
X  
X    /* Integer registers */
X!   if (target_read_memory(pcb->pcb_ksp, (char *)&sf, sizeof sf))
X       error("Cannot read integer registers.");
X  
X    /* We use the psr at kernel entry */
X!   if (target_read_memory((long)pcb->pcb_onstack, (char *)&intreg, sizeof intreg))
X       error("Cannot read processor status register.");
X  
X    dummy = 0;
X***************
X*** 218,221 ****
X--- 218,294 ----
X    registers_fetched ();
X  }
X  #endif	/* FETCH_KCORE_REGISTERS */
X+ 
X+ /* from i386v-nat.c */
X  
X+ #ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
X+ 
X+ /* Record the value of the debug control register.  */
X+ static struct bkptreg bkpt;
X+ 
X+ /* Insert a watchpoint.  */
X+ 
X+ int
X+ ns32k_insert_watchpoint (pid, addr, len, rw)
X+      int pid;
X+      CORE_ADDR addr;
X+      int len;
X+      int rw;
X+ {
X+   addr &= ~(CORE_ADDR) 3;		/* '532 wants long aligned addr */
X+ 
X+   /* we only have one addr reg, PC compare unused */
X+   if (bkpt.r_dsr && bkpt.r_car != addr)
X+     return -1;				/* we're busy */
X+ 
X+   /* XXX ignore len?? play with compare bits?? */
X+   bkpt.r_car = addr;
X+ 
X+   /* debug enable, user mode, enable trap, virtual addresses */
X+   /*  compare address enable, look at all bytes of address */
X+   bkpt.r_dcr = DCR_DEN | DCR_UD | DCR_TR | DCR_VNP |
X+       DCR_CAE | DCR_CBE0 | DCR_CBE1 | DCR_CBE2 | DCR_CBE3;
X+   if (rw & 1) {
X+     bkpt.r_dcr |= DCR_CRD;		/* compare on reads */
X+   }
X+   if (rw & 2) {
X+     bkpt.r_dcr |= DCR_CWR;		/* compare on writes */
X+   }
X+   if (ptrace(PT_SETBKPTS, pid, (caddr_t)&bkpt, 0) < 0) {
X+     bkpt.r_dcr = 0;			/* nothing set */
X+     return -1;
X+   }
X+   return 0;
X+ }
X+ 
X+ /* Remove a watchpoint.  */
X+ 
X+ int
X+ ns32k_remove_watchpoint (pid, addr, len)
X+      int pid;
X+      CORE_ADDR addr;
X+      int len;
X+ {
X+   /* check addr?? */
X+   bkpt.r_dcr = 0;
X+ 
X+   return ptrace(PT_SETBKPTS, pid, (caddr_t)&bkpt, 0);
X+ }
X+ 
X+ /* Check if stopped by a watchpoint.  */
X+ 
X+ CORE_ADDR
X+ ns32k_stopped_by_watchpoint (pid)
X+     int pid;
X+ {
X+   if (ptrace(PT_GETBKPTS, pid, (caddr_t)&bkpt, 0) < 0 || bkpt.r_dsr == 0)
X+     return 0;
X+ 
X+   /* clear status */
X+   bkpt.r_dsr = 0;
X+   ptrace(PT_SETBKPTS, pid, (caddr_t)&bkpt, 0);
X+ 
X+   return (CORE_ADDR) bkpt.r_car;
X+ }
X+ 
X+ #endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
END_OF_FILE
if test 3922 -ne `wc -c <'gdb.diffs'`; then
    echo shar: \"'gdb.diffs'\" unpacked with wrong size!
fi
# end of 'gdb.diffs'
fi
echo shar: End of shell archive.
exit 0