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