Implement support for hardware debug registers on the i386.
Submitted by: Brian Dean <brdean@unx.sas.com>
This commit is contained in:
parent
bd17e46e55
commit
ab001a72be
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: swtch.s,v 1.82 1999/06/01 18:19:45 jlemon Exp $
|
||||
* $Id: swtch.s,v 1.83 1999/07/03 06:33:24 alc Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -480,6 +480,26 @@ ENTRY(cpu_switch)
|
||||
movl %edi,PCB_EDI(%edx)
|
||||
movl %gs,PCB_GS(%edx)
|
||||
|
||||
/* test if debug regisers should be saved */
|
||||
movb PCB_FLAGS(%edx),%al
|
||||
andb $PCB_DBREGS,%al
|
||||
jz 1f /* no, skip over */
|
||||
movl %dr7,%eax /* yes, do the save */
|
||||
movl %eax,PCB_DR7(%edx)
|
||||
andl $0x0000ff00, %eax /* disable all watchpoints */
|
||||
movl %eax,%dr7
|
||||
movl %dr6,%eax
|
||||
movl %eax,PCB_DR6(%edx)
|
||||
movl %dr3,%eax
|
||||
movl %eax,PCB_DR3(%edx)
|
||||
movl %dr2,%eax
|
||||
movl %eax,PCB_DR2(%edx)
|
||||
movl %dr1,%eax
|
||||
movl %eax,PCB_DR1(%edx)
|
||||
movl %dr0,%eax
|
||||
movl %eax,PCB_DR0(%edx)
|
||||
1:
|
||||
|
||||
#ifdef SMP
|
||||
movl _mp_lock, %eax
|
||||
/* XXX FIXME: we should be saving the local APIC TPR */
|
||||
@ -718,6 +738,24 @@ swtch_com:
|
||||
cpu_switch_load_gs:
|
||||
movl PCB_GS(%edx),%gs
|
||||
|
||||
/* test if debug regisers should be restored */
|
||||
movb PCB_FLAGS(%edx),%al
|
||||
andb $PCB_DBREGS,%al
|
||||
jz 1f /* no, skip over */
|
||||
movl PCB_DR6(%edx),%eax /* yes, do the restore */
|
||||
movl %eax,%dr6
|
||||
movl PCB_DR3(%edx),%eax
|
||||
movl %eax,%dr3
|
||||
movl PCB_DR2(%edx),%eax
|
||||
movl %eax,%dr2
|
||||
movl PCB_DR1(%edx),%eax
|
||||
movl %eax,%dr1
|
||||
movl PCB_DR0(%edx),%eax
|
||||
movl %eax,%dr0
|
||||
movl PCB_DR7(%edx),%eax
|
||||
movl %eax,%dr7
|
||||
1:
|
||||
|
||||
sti
|
||||
ret
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
|
||||
* $Id: genassym.c,v 1.71 1999/06/28 09:21:41 peter Exp $
|
||||
* $Id: genassym.c,v 1.72 1999/07/06 07:13:32 cracauer Exp $
|
||||
*/
|
||||
|
||||
#include "opt_user_ldt.h"
|
||||
@ -128,6 +128,13 @@ main()
|
||||
printf("#define\tTSS_ESP0 %#x\n", OS(i386tss, tss_esp0));
|
||||
printf("#define\tPCB_USERLDT %#x\n", OS(pcb, pcb_ldt));
|
||||
printf("#define\tPCB_GS %#x\n", OS(pcb, pcb_gs));
|
||||
printf("#define\tPCB_DR0 %#x\n", OS(pcb, pcb_dr0));
|
||||
printf("#define\tPCB_DR1 %#x\n", OS(pcb, pcb_dr1));
|
||||
printf("#define\tPCB_DR2 %#x\n", OS(pcb, pcb_dr2));
|
||||
printf("#define\tPCB_DR3 %#x\n", OS(pcb, pcb_dr3));
|
||||
printf("#define\tPCB_DR6 %#x\n", OS(pcb, pcb_dr6));
|
||||
printf("#define\tPCB_DR7 %#x\n", OS(pcb, pcb_dr7));
|
||||
printf("#define\tPCB_DBREGS %#x\n", PCB_DBREGS );
|
||||
printf("#define\tPCB_EXT %#x\n", OS(pcb, pcb_ext));
|
||||
#ifdef SMP
|
||||
printf("#define\tPCB_MPNEST %#x\n", OS(pcb, pcb_mpnest));
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.353 1999/07/06 07:13:33 cracauer Exp $
|
||||
* $Id: machdep.c,v 1.354 1999/07/08 06:05:48 mckusick Exp $
|
||||
*/
|
||||
|
||||
#include "apm.h"
|
||||
@ -1927,6 +1927,87 @@ set_fpregs(p, fpregs)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fill_dbregs(p, dbregs)
|
||||
struct proc *p;
|
||||
struct dbreg *dbregs;
|
||||
{
|
||||
struct pcb *pcb;
|
||||
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
dbregs->dr0 = pcb->pcb_dr0;
|
||||
dbregs->dr1 = pcb->pcb_dr1;
|
||||
dbregs->dr2 = pcb->pcb_dr2;
|
||||
dbregs->dr3 = pcb->pcb_dr3;
|
||||
dbregs->dr4 = 0;
|
||||
dbregs->dr5 = 0;
|
||||
dbregs->dr6 = pcb->pcb_dr6;
|
||||
dbregs->dr7 = pcb->pcb_dr7;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
set_dbregs(p, dbregs)
|
||||
struct proc *p;
|
||||
struct dbreg *dbregs;
|
||||
{
|
||||
struct pcb *pcb;
|
||||
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
|
||||
/*
|
||||
* Don't let a process set a breakpoint that is not within the
|
||||
* process's address space. If a process could do this, it
|
||||
* could halt the system by setting a breakpoint in the kernel
|
||||
* (if ddb was enabled). Thus, we need to check to make sure
|
||||
* that no breakpoints are being enabled for addresses outside
|
||||
* process's address space, unless, perhaps, we were called by
|
||||
* uid 0.
|
||||
*
|
||||
* XXX - what about when the watched area of the user's
|
||||
* address space is written into from within the kernel
|
||||
* ... wouldn't that still cause a breakpoint to be generated
|
||||
* from within kernel mode?
|
||||
*/
|
||||
|
||||
if (p->p_cred->pc_ucred->cr_uid != 0) {
|
||||
if (dbregs->dr7 & 0x3) {
|
||||
/* dr0 is enabled */
|
||||
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dbregs->dr7 & (0x3<<2)) {
|
||||
/* dr1 is enabled */
|
||||
if (dbregs->dr1 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dbregs->dr7 & (0x3<<4)) {
|
||||
/* dr2 is enabled */
|
||||
if (dbregs->dr2 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dbregs->dr7 & (0x3<<6)) {
|
||||
/* dr3 is enabled */
|
||||
if (dbregs->dr3 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
pcb->pcb_dr0 = dbregs->dr0;
|
||||
pcb->pcb_dr1 = dbregs->dr1;
|
||||
pcb->pcb_dr2 = dbregs->dr2;
|
||||
pcb->pcb_dr3 = dbregs->dr3;
|
||||
pcb->pcb_dr6 = dbregs->dr6;
|
||||
pcb->pcb_dr7 = dbregs->dr7;
|
||||
|
||||
pcb->pcb_flags |= PCB_DBREGS;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef DDB
|
||||
void
|
||||
Debugger(const char *msg)
|
||||
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: swtch.s,v 1.82 1999/06/01 18:19:45 jlemon Exp $
|
||||
* $Id: swtch.s,v 1.83 1999/07/03 06:33:24 alc Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -480,6 +480,26 @@ ENTRY(cpu_switch)
|
||||
movl %edi,PCB_EDI(%edx)
|
||||
movl %gs,PCB_GS(%edx)
|
||||
|
||||
/* test if debug regisers should be saved */
|
||||
movb PCB_FLAGS(%edx),%al
|
||||
andb $PCB_DBREGS,%al
|
||||
jz 1f /* no, skip over */
|
||||
movl %dr7,%eax /* yes, do the save */
|
||||
movl %eax,PCB_DR7(%edx)
|
||||
andl $0x0000ff00, %eax /* disable all watchpoints */
|
||||
movl %eax,%dr7
|
||||
movl %dr6,%eax
|
||||
movl %eax,PCB_DR6(%edx)
|
||||
movl %dr3,%eax
|
||||
movl %eax,PCB_DR3(%edx)
|
||||
movl %dr2,%eax
|
||||
movl %eax,PCB_DR2(%edx)
|
||||
movl %dr1,%eax
|
||||
movl %eax,PCB_DR1(%edx)
|
||||
movl %dr0,%eax
|
||||
movl %eax,PCB_DR0(%edx)
|
||||
1:
|
||||
|
||||
#ifdef SMP
|
||||
movl _mp_lock, %eax
|
||||
/* XXX FIXME: we should be saving the local APIC TPR */
|
||||
@ -718,6 +738,24 @@ swtch_com:
|
||||
cpu_switch_load_gs:
|
||||
movl PCB_GS(%edx),%gs
|
||||
|
||||
/* test if debug regisers should be restored */
|
||||
movb PCB_FLAGS(%edx),%al
|
||||
andb $PCB_DBREGS,%al
|
||||
jz 1f /* no, skip over */
|
||||
movl PCB_DR6(%edx),%eax /* yes, do the restore */
|
||||
movl %eax,%dr6
|
||||
movl PCB_DR3(%edx),%eax
|
||||
movl %eax,%dr3
|
||||
movl PCB_DR2(%edx),%eax
|
||||
movl %eax,%dr2
|
||||
movl PCB_DR1(%edx),%eax
|
||||
movl %eax,%dr1
|
||||
movl PCB_DR0(%edx),%eax
|
||||
movl %eax,%dr0
|
||||
movl PCB_DR7(%edx),%eax
|
||||
movl %eax,%dr7
|
||||
1:
|
||||
|
||||
sti
|
||||
ret
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: md_var.h,v 1.28 1999/01/08 16:29:58 bde Exp $
|
||||
* $Id: md_var.h,v 1.29 1999/04/28 01:04:02 luoqi Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_MD_VAR_H_
|
||||
@ -64,6 +64,7 @@ typedef void alias_for_inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
|
||||
struct proc;
|
||||
struct reg;
|
||||
struct fpreg;
|
||||
struct dbreg;
|
||||
|
||||
void bcopyb __P((const void *from, void *to, size_t len));
|
||||
void busdma_swi __P((void));
|
||||
@ -80,6 +81,7 @@ void doreti_popl_fs __P((void)) __asm(__STRING(doreti_popl_fs));
|
||||
void doreti_popl_fs_fault __P((void)) __asm(__STRING(doreti_popl_fs_fault));
|
||||
int fill_fpregs __P((struct proc *, struct fpreg *));
|
||||
int fill_regs __P((struct proc *p, struct reg *regs));
|
||||
int fill_dbregs __P((struct proc *p, struct dbreg *dbregs));
|
||||
void fillw __P((int /*u_short*/ pat, void *base, size_t cnt));
|
||||
void i486_bzero __P((void *buf, size_t len));
|
||||
void i586_bcopy __P((const void *from, void *to, size_t len));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pcb.h 5.10 (Berkeley) 5/12/91
|
||||
* $Id: pcb.h,v 1.27 1999/04/28 01:04:05 luoqi Exp $
|
||||
* $Id: pcb.h,v 1.28 1999/06/01 18:20:06 jlemon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _I386_PCB_H_
|
||||
@ -54,11 +54,20 @@ struct pcb {
|
||||
int pcb_esp;
|
||||
int pcb_ebx;
|
||||
int pcb_eip;
|
||||
|
||||
int pcb_dr0;
|
||||
int pcb_dr1;
|
||||
int pcb_dr2;
|
||||
int pcb_dr3;
|
||||
int pcb_dr6;
|
||||
int pcb_dr7;
|
||||
|
||||
caddr_t pcb_ldt; /* per process (user) LDT */
|
||||
int pcb_ldt_len; /* number of LDT entries */
|
||||
struct save87 pcb_savefpu; /* floating point state for 287/387 */
|
||||
u_char pcb_flags;
|
||||
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
|
||||
#define PCB_DBREGS 0x02 /* process using debug registers */
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
#ifdef SMP
|
||||
u_long pcb_mpnest;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ptrace.h 8.1 (Berkeley) 6/11/93
|
||||
* $Id: ptrace.h,v 1.5 1997/02/22 09:35:03 peter Exp $
|
||||
* $Id: ptrace.h,v 1.6 1998/05/19 00:00:12 tegge Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_PTRACE_H_
|
||||
@ -44,6 +44,8 @@
|
||||
#define PT_SETREGS (PT_FIRSTMACH + 2)
|
||||
#define PT_GETFPREGS (PT_FIRSTMACH + 3)
|
||||
#define PT_SETFPREGS (PT_FIRSTMACH + 4)
|
||||
#define PT_GETDBREGS (PT_FIRSTMACH + 5)
|
||||
#define PT_SETDBREGS (PT_FIRSTMACH + 6)
|
||||
|
||||
#ifdef KERNEL
|
||||
int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)reg.h 5.5 (Berkeley) 1/18/91
|
||||
* $Id: reg.h,v 1.17 1999/04/03 22:19:59 jdp Exp $
|
||||
* $Id: reg.h,v 1.18 1999/04/28 01:04:06 luoqi Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_REG_H_
|
||||
@ -118,6 +118,18 @@ struct fpreg {
|
||||
unsigned char fpr_pad[64];
|
||||
};
|
||||
|
||||
struct dbreg {
|
||||
unsigned int dr0; /* debug address register 0 */
|
||||
unsigned int dr1; /* debug address register 1 */
|
||||
unsigned int dr2; /* debug address register 2 */
|
||||
unsigned int dr3; /* debug address register 3 */
|
||||
unsigned int dr4; /* reserved */
|
||||
unsigned int dr5; /* reserved */
|
||||
unsigned int dr6; /* debug status register */
|
||||
unsigned int dr7; /* debug control register */
|
||||
};
|
||||
|
||||
|
||||
#ifdef KERNEL
|
||||
/*
|
||||
* XXX these interfaces are MI, so they should be declared in a MI place.
|
||||
@ -125,6 +137,7 @@ struct fpreg {
|
||||
int set_fpregs __P((struct proc *, struct fpreg *));
|
||||
int set_regs __P((struct proc *p, struct reg *regs));
|
||||
void setregs __P((struct proc *, u_long, u_long, u_long));
|
||||
int set_dbregs __P((struct proc *p, struct dbreg *dbregs));
|
||||
#endif
|
||||
|
||||
#endif /* !_MACHINE_REG_H_ */
|
||||
|
@ -362,6 +362,7 @@ miscfs/nullfs/null_vnops.c optional nullfs
|
||||
miscfs/portal/portal_vfsops.c optional portal
|
||||
miscfs/portal/portal_vnops.c optional portal
|
||||
miscfs/procfs/procfs_ctl.c optional procfs
|
||||
miscfs/procfs/procfs_dbregs.c standard
|
||||
miscfs/procfs/procfs_fpregs.c standard
|
||||
miscfs/procfs/procfs_map.c optional procfs
|
||||
miscfs/procfs/procfs_mem.c standard
|
||||
|
@ -37,7 +37,7 @@
|
||||
* @(#)procfs.h 8.9 (Berkeley) 5/14/95
|
||||
*
|
||||
* From:
|
||||
* $Id: procfs.h,v 1.25 1999/05/04 08:00:10 phk Exp $
|
||||
* $Id: procfs.h,v 1.26 1999/06/13 20:53:13 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -51,6 +51,7 @@ typedef enum {
|
||||
Pmem, /* the process's memory image */
|
||||
Pregs, /* the process's register set */
|
||||
Pfpregs, /* the process's FP register set */
|
||||
Pdbregs, /* the process's debug register set */
|
||||
Pctl, /* process control */
|
||||
Pstatus, /* process status */
|
||||
Pnote, /* process notifier */
|
||||
@ -124,6 +125,7 @@ vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int));
|
||||
/* <machine/reg.h> */
|
||||
struct reg;
|
||||
struct fpreg;
|
||||
struct dbreg;
|
||||
|
||||
#define PFIND(pid) ((pid) ? pfind(pid) : &proc0)
|
||||
|
||||
@ -137,9 +139,12 @@ int procfs_read_regs __P((struct proc *, struct reg *));
|
||||
int procfs_write_regs __P((struct proc *, struct reg *));
|
||||
int procfs_read_fpregs __P((struct proc *, struct fpreg *));
|
||||
int procfs_write_fpregs __P((struct proc *, struct fpreg *));
|
||||
int procfs_read_dbregs __P((struct proc *, struct dbreg *));
|
||||
int procfs_write_dbregs __P((struct proc *, struct dbreg *));
|
||||
int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dodbregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
@ -155,6 +160,7 @@ int procfs_kmemaccess __P((struct proc *));
|
||||
int procfs_validfile __P((struct proc *));
|
||||
int procfs_validfpregs __P((struct proc *));
|
||||
int procfs_validregs __P((struct proc *));
|
||||
int procfs_validdbregs __P((struct proc *));
|
||||
int procfs_validmap __P((struct proc *));
|
||||
int procfs_validtype __P((struct proc *));
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
|
||||
*
|
||||
* $Id: procfs_subr.c,v 1.23 1999/01/27 22:42:07 dillon Exp $
|
||||
* $Id: procfs_subr.c,v 1.24 1999/04/30 13:04:21 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -167,6 +167,7 @@ loop:
|
||||
|
||||
case Pregs:
|
||||
case Pfpregs:
|
||||
case Pdbregs:
|
||||
pfs->pfs_mode = (VREAD|VWRITE);
|
||||
vp->v_type = VREG;
|
||||
break;
|
||||
@ -264,6 +265,10 @@ procfs_rw(ap)
|
||||
rtval = procfs_dofpregs(curp, p, pfs, uio);
|
||||
break;
|
||||
|
||||
case Pdbregs:
|
||||
rtval = procfs_dodbregs(curp, p, pfs, uio);
|
||||
break;
|
||||
|
||||
case Pctl:
|
||||
rtval = procfs_doctl(curp, p, pfs, uio);
|
||||
break;
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.68 1999/05/04 08:01:55 phk Exp $
|
||||
* $Id: procfs_vnops.c,v 1.69 1999/06/13 20:53:16 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -95,6 +95,7 @@ static struct proc_target {
|
||||
{ DT_REG, N("mem"), Pmem, NULL },
|
||||
{ DT_REG, N("regs"), Pregs, procfs_validregs },
|
||||
{ DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs },
|
||||
{ DT_REG, N("dbregs"), Pdbregs, procfs_validdbregs },
|
||||
{ DT_REG, N("ctl"), Pctl, NULL },
|
||||
{ DT_REG, N("status"), Pstatus, NULL },
|
||||
{ DT_REG, N("note"), Pnote, NULL },
|
||||
@ -491,6 +492,7 @@ procfs_getattr(ap)
|
||||
case Pctl:
|
||||
case Pregs:
|
||||
case Pfpregs:
|
||||
case Pdbregs:
|
||||
if (procp->p_flag & P_SUGID)
|
||||
vap->va_mode &= ~((VREAD|VWRITE)|
|
||||
((VREAD|VWRITE)>>3)|
|
||||
@ -571,6 +573,10 @@ procfs_getattr(ap)
|
||||
vap->va_bytes = vap->va_size = sizeof(struct fpreg);
|
||||
break;
|
||||
|
||||
case Pdbregs:
|
||||
vap->va_bytes = vap->va_size = sizeof(struct dbreg);
|
||||
break;
|
||||
|
||||
case Ptype:
|
||||
case Pmap:
|
||||
case Pctl:
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
|
||||
* $Id: genassym.c,v 1.71 1999/06/28 09:21:41 peter Exp $
|
||||
* $Id: genassym.c,v 1.72 1999/07/06 07:13:32 cracauer Exp $
|
||||
*/
|
||||
|
||||
#include "opt_user_ldt.h"
|
||||
@ -128,6 +128,13 @@ main()
|
||||
printf("#define\tTSS_ESP0 %#x\n", OS(i386tss, tss_esp0));
|
||||
printf("#define\tPCB_USERLDT %#x\n", OS(pcb, pcb_ldt));
|
||||
printf("#define\tPCB_GS %#x\n", OS(pcb, pcb_gs));
|
||||
printf("#define\tPCB_DR0 %#x\n", OS(pcb, pcb_dr0));
|
||||
printf("#define\tPCB_DR1 %#x\n", OS(pcb, pcb_dr1));
|
||||
printf("#define\tPCB_DR2 %#x\n", OS(pcb, pcb_dr2));
|
||||
printf("#define\tPCB_DR3 %#x\n", OS(pcb, pcb_dr3));
|
||||
printf("#define\tPCB_DR6 %#x\n", OS(pcb, pcb_dr6));
|
||||
printf("#define\tPCB_DR7 %#x\n", OS(pcb, pcb_dr7));
|
||||
printf("#define\tPCB_DBREGS %#x\n", PCB_DBREGS );
|
||||
printf("#define\tPCB_EXT %#x\n", OS(pcb, pcb_ext));
|
||||
#ifdef SMP
|
||||
printf("#define\tPCB_MPNEST %#x\n", OS(pcb, pcb_mpnest));
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
|
||||
* $Id: machdep.c,v 1.353 1999/07/06 07:13:33 cracauer Exp $
|
||||
* $Id: machdep.c,v 1.354 1999/07/08 06:05:48 mckusick Exp $
|
||||
*/
|
||||
|
||||
#include "apm.h"
|
||||
@ -1927,6 +1927,87 @@ set_fpregs(p, fpregs)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fill_dbregs(p, dbregs)
|
||||
struct proc *p;
|
||||
struct dbreg *dbregs;
|
||||
{
|
||||
struct pcb *pcb;
|
||||
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
dbregs->dr0 = pcb->pcb_dr0;
|
||||
dbregs->dr1 = pcb->pcb_dr1;
|
||||
dbregs->dr2 = pcb->pcb_dr2;
|
||||
dbregs->dr3 = pcb->pcb_dr3;
|
||||
dbregs->dr4 = 0;
|
||||
dbregs->dr5 = 0;
|
||||
dbregs->dr6 = pcb->pcb_dr6;
|
||||
dbregs->dr7 = pcb->pcb_dr7;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
set_dbregs(p, dbregs)
|
||||
struct proc *p;
|
||||
struct dbreg *dbregs;
|
||||
{
|
||||
struct pcb *pcb;
|
||||
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
|
||||
/*
|
||||
* Don't let a process set a breakpoint that is not within the
|
||||
* process's address space. If a process could do this, it
|
||||
* could halt the system by setting a breakpoint in the kernel
|
||||
* (if ddb was enabled). Thus, we need to check to make sure
|
||||
* that no breakpoints are being enabled for addresses outside
|
||||
* process's address space, unless, perhaps, we were called by
|
||||
* uid 0.
|
||||
*
|
||||
* XXX - what about when the watched area of the user's
|
||||
* address space is written into from within the kernel
|
||||
* ... wouldn't that still cause a breakpoint to be generated
|
||||
* from within kernel mode?
|
||||
*/
|
||||
|
||||
if (p->p_cred->pc_ucred->cr_uid != 0) {
|
||||
if (dbregs->dr7 & 0x3) {
|
||||
/* dr0 is enabled */
|
||||
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dbregs->dr7 & (0x3<<2)) {
|
||||
/* dr1 is enabled */
|
||||
if (dbregs->dr1 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dbregs->dr7 & (0x3<<4)) {
|
||||
/* dr2 is enabled */
|
||||
if (dbregs->dr2 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (dbregs->dr7 & (0x3<<6)) {
|
||||
/* dr3 is enabled */
|
||||
if (dbregs->dr3 >= VM_MAXUSER_ADDRESS)
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
pcb->pcb_dr0 = dbregs->dr0;
|
||||
pcb->pcb_dr1 = dbregs->dr1;
|
||||
pcb->pcb_dr2 = dbregs->dr2;
|
||||
pcb->pcb_dr3 = dbregs->dr3;
|
||||
pcb->pcb_dr6 = dbregs->dr6;
|
||||
pcb->pcb_dr7 = dbregs->dr7;
|
||||
|
||||
pcb->pcb_flags |= PCB_DBREGS;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef DDB
|
||||
void
|
||||
Debugger(const char *msg)
|
||||
|
@ -37,7 +37,7 @@
|
||||
* @(#)procfs_machdep.c 8.3 (Berkeley) 1/27/94
|
||||
*
|
||||
* From:
|
||||
* $Id: procfs_machdep.c,v 1.10 1997/07/20 08:37:22 bde Exp $
|
||||
* $Id: procfs_machdep.c,v 1.11 1998/09/14 22:43:33 jdp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -59,6 +59,9 @@
|
||||
* procfs_read_fpregs, procfs_write_fpregs
|
||||
* deal with the floating point register set, otherwise as above.
|
||||
*
|
||||
* procfs_read_dbregs, procfs_write_dbregs
|
||||
* deal with the processor debug register set, otherwise as above.
|
||||
*
|
||||
* procfs_sstep(proc)
|
||||
* Arrange for the process to trap after executing a single instruction.
|
||||
*
|
||||
@ -100,6 +103,26 @@ procfs_write_regs(p, regs)
|
||||
return (set_regs(p, regs));
|
||||
}
|
||||
|
||||
int
|
||||
procfs_read_dbregs(p, dbregs)
|
||||
struct proc *p;
|
||||
struct dbreg *dbregs;
|
||||
{
|
||||
if ((p->p_flag & P_INMEM) == 0)
|
||||
return (EIO);
|
||||
return (fill_dbregs(p, dbregs));
|
||||
}
|
||||
|
||||
int
|
||||
procfs_write_dbregs(p, dbregs)
|
||||
struct proc *p;
|
||||
struct dbreg *dbregs;
|
||||
{
|
||||
if ((p->p_flag & P_INMEM) == 0)
|
||||
return (EIO);
|
||||
return (set_dbregs(p, dbregs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Ptrace doesn't support fpregs at all, and there are no security holes
|
||||
* or translations for fpregs, so we can just copy them.
|
||||
|
@ -33,7 +33,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: swtch.s,v 1.82 1999/06/01 18:19:45 jlemon Exp $
|
||||
* $Id: swtch.s,v 1.83 1999/07/03 06:33:24 alc Exp $
|
||||
*/
|
||||
|
||||
#include "npx.h"
|
||||
@ -480,6 +480,26 @@ ENTRY(cpu_switch)
|
||||
movl %edi,PCB_EDI(%edx)
|
||||
movl %gs,PCB_GS(%edx)
|
||||
|
||||
/* test if debug regisers should be saved */
|
||||
movb PCB_FLAGS(%edx),%al
|
||||
andb $PCB_DBREGS,%al
|
||||
jz 1f /* no, skip over */
|
||||
movl %dr7,%eax /* yes, do the save */
|
||||
movl %eax,PCB_DR7(%edx)
|
||||
andl $0x0000ff00, %eax /* disable all watchpoints */
|
||||
movl %eax,%dr7
|
||||
movl %dr6,%eax
|
||||
movl %eax,PCB_DR6(%edx)
|
||||
movl %dr3,%eax
|
||||
movl %eax,PCB_DR3(%edx)
|
||||
movl %dr2,%eax
|
||||
movl %eax,PCB_DR2(%edx)
|
||||
movl %dr1,%eax
|
||||
movl %eax,PCB_DR1(%edx)
|
||||
movl %dr0,%eax
|
||||
movl %eax,PCB_DR0(%edx)
|
||||
1:
|
||||
|
||||
#ifdef SMP
|
||||
movl _mp_lock, %eax
|
||||
/* XXX FIXME: we should be saving the local APIC TPR */
|
||||
@ -718,6 +738,24 @@ swtch_com:
|
||||
cpu_switch_load_gs:
|
||||
movl PCB_GS(%edx),%gs
|
||||
|
||||
/* test if debug regisers should be restored */
|
||||
movb PCB_FLAGS(%edx),%al
|
||||
andb $PCB_DBREGS,%al
|
||||
jz 1f /* no, skip over */
|
||||
movl PCB_DR6(%edx),%eax /* yes, do the restore */
|
||||
movl %eax,%dr6
|
||||
movl PCB_DR3(%edx),%eax
|
||||
movl %eax,%dr3
|
||||
movl PCB_DR2(%edx),%eax
|
||||
movl %eax,%dr2
|
||||
movl PCB_DR1(%edx),%eax
|
||||
movl %eax,%dr1
|
||||
movl PCB_DR0(%edx),%eax
|
||||
movl %eax,%dr0
|
||||
movl PCB_DR7(%edx),%eax
|
||||
movl %eax,%dr7
|
||||
1:
|
||||
|
||||
sti
|
||||
ret
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: md_var.h,v 1.28 1999/01/08 16:29:58 bde Exp $
|
||||
* $Id: md_var.h,v 1.29 1999/04/28 01:04:02 luoqi Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_MD_VAR_H_
|
||||
@ -64,6 +64,7 @@ typedef void alias_for_inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
|
||||
struct proc;
|
||||
struct reg;
|
||||
struct fpreg;
|
||||
struct dbreg;
|
||||
|
||||
void bcopyb __P((const void *from, void *to, size_t len));
|
||||
void busdma_swi __P((void));
|
||||
@ -80,6 +81,7 @@ void doreti_popl_fs __P((void)) __asm(__STRING(doreti_popl_fs));
|
||||
void doreti_popl_fs_fault __P((void)) __asm(__STRING(doreti_popl_fs_fault));
|
||||
int fill_fpregs __P((struct proc *, struct fpreg *));
|
||||
int fill_regs __P((struct proc *p, struct reg *regs));
|
||||
int fill_dbregs __P((struct proc *p, struct dbreg *dbregs));
|
||||
void fillw __P((int /*u_short*/ pat, void *base, size_t cnt));
|
||||
void i486_bzero __P((void *buf, size_t len));
|
||||
void i586_bcopy __P((const void *from, void *to, size_t len));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pcb.h 5.10 (Berkeley) 5/12/91
|
||||
* $Id: pcb.h,v 1.27 1999/04/28 01:04:05 luoqi Exp $
|
||||
* $Id: pcb.h,v 1.28 1999/06/01 18:20:06 jlemon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _I386_PCB_H_
|
||||
@ -54,11 +54,20 @@ struct pcb {
|
||||
int pcb_esp;
|
||||
int pcb_ebx;
|
||||
int pcb_eip;
|
||||
|
||||
int pcb_dr0;
|
||||
int pcb_dr1;
|
||||
int pcb_dr2;
|
||||
int pcb_dr3;
|
||||
int pcb_dr6;
|
||||
int pcb_dr7;
|
||||
|
||||
caddr_t pcb_ldt; /* per process (user) LDT */
|
||||
int pcb_ldt_len; /* number of LDT entries */
|
||||
struct save87 pcb_savefpu; /* floating point state for 287/387 */
|
||||
u_char pcb_flags;
|
||||
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
|
||||
#define PCB_DBREGS 0x02 /* process using debug registers */
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
#ifdef SMP
|
||||
u_long pcb_mpnest;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ptrace.h 8.1 (Berkeley) 6/11/93
|
||||
* $Id: ptrace.h,v 1.5 1997/02/22 09:35:03 peter Exp $
|
||||
* $Id: ptrace.h,v 1.6 1998/05/19 00:00:12 tegge Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_PTRACE_H_
|
||||
@ -44,6 +44,8 @@
|
||||
#define PT_SETREGS (PT_FIRSTMACH + 2)
|
||||
#define PT_GETFPREGS (PT_FIRSTMACH + 3)
|
||||
#define PT_SETFPREGS (PT_FIRSTMACH + 4)
|
||||
#define PT_GETDBREGS (PT_FIRSTMACH + 5)
|
||||
#define PT_SETDBREGS (PT_FIRSTMACH + 6)
|
||||
|
||||
#ifdef KERNEL
|
||||
int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len));
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)reg.h 5.5 (Berkeley) 1/18/91
|
||||
* $Id: reg.h,v 1.17 1999/04/03 22:19:59 jdp Exp $
|
||||
* $Id: reg.h,v 1.18 1999/04/28 01:04:06 luoqi Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_REG_H_
|
||||
@ -118,6 +118,18 @@ struct fpreg {
|
||||
unsigned char fpr_pad[64];
|
||||
};
|
||||
|
||||
struct dbreg {
|
||||
unsigned int dr0; /* debug address register 0 */
|
||||
unsigned int dr1; /* debug address register 1 */
|
||||
unsigned int dr2; /* debug address register 2 */
|
||||
unsigned int dr3; /* debug address register 3 */
|
||||
unsigned int dr4; /* reserved */
|
||||
unsigned int dr5; /* reserved */
|
||||
unsigned int dr6; /* debug status register */
|
||||
unsigned int dr7; /* debug control register */
|
||||
};
|
||||
|
||||
|
||||
#ifdef KERNEL
|
||||
/*
|
||||
* XXX these interfaces are MI, so they should be declared in a MI place.
|
||||
@ -125,6 +137,7 @@ struct fpreg {
|
||||
int set_fpregs __P((struct proc *, struct fpreg *));
|
||||
int set_regs __P((struct proc *p, struct reg *regs));
|
||||
void setregs __P((struct proc *, u_long, u_long, u_long));
|
||||
int set_dbregs __P((struct proc *p, struct dbreg *dbregs));
|
||||
#endif
|
||||
|
||||
#endif /* !_MACHINE_REG_H_ */
|
||||
|
@ -28,7 +28,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: sys_process.c,v 1.45 1999/04/28 11:37:04 phk Exp $
|
||||
* $Id: sys_process.c,v 1.46 1999/07/01 22:52:40 peter Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -274,6 +274,12 @@ ptrace(curp, uap)
|
||||
#endif
|
||||
#ifdef PT_SETFPREGS
|
||||
case PT_SETFPREGS:
|
||||
#endif
|
||||
#ifdef PT_GETDBREGS
|
||||
case PT_GETDBREGS:
|
||||
#endif
|
||||
#ifdef PT_SETDBREGS
|
||||
case PT_SETDBREGS:
|
||||
#endif
|
||||
/* not being traced... */
|
||||
if ((p->p_flag & P_TRACED) == 0)
|
||||
@ -502,6 +508,32 @@ ptrace(curp, uap)
|
||||
}
|
||||
#endif /* defined(PT_SETFPREGS) || defined(PT_GETFPREGS) */
|
||||
|
||||
#ifdef PT_SETDBREGS
|
||||
case PT_SETDBREGS:
|
||||
write = 1;
|
||||
/* fallthrough */
|
||||
#endif /* PT_SETDBREGS */
|
||||
#ifdef PT_GETDBREGS
|
||||
case PT_GETDBREGS:
|
||||
/* write = 0 above */
|
||||
#endif /* PT_SETDBREGS */
|
||||
#if defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
|
||||
if (!procfs_validdbregs(p)) /* no P_SYSTEM procs please */
|
||||
return EINVAL;
|
||||
else {
|
||||
iov.iov_base = uap->addr;
|
||||
iov.iov_len = sizeof(struct dbreg);
|
||||
uio.uio_iov = &iov;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = 0;
|
||||
uio.uio_resid = sizeof(struct dbreg);
|
||||
uio.uio_segflg = UIO_USERSPACE;
|
||||
uio.uio_rw = write ? UIO_WRITE : UIO_READ;
|
||||
uio.uio_procp = curp;
|
||||
return (procfs_dodbregs(curp, p, NULL, &uio));
|
||||
}
|
||||
#endif /* defined(PT_SETDBREGS) || defined(PT_GETDBREGS) */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
* @(#)procfs.h 8.9 (Berkeley) 5/14/95
|
||||
*
|
||||
* From:
|
||||
* $Id: procfs.h,v 1.25 1999/05/04 08:00:10 phk Exp $
|
||||
* $Id: procfs.h,v 1.26 1999/06/13 20:53:13 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -51,6 +51,7 @@ typedef enum {
|
||||
Pmem, /* the process's memory image */
|
||||
Pregs, /* the process's register set */
|
||||
Pfpregs, /* the process's FP register set */
|
||||
Pdbregs, /* the process's debug register set */
|
||||
Pctl, /* process control */
|
||||
Pstatus, /* process status */
|
||||
Pnote, /* process notifier */
|
||||
@ -124,6 +125,7 @@ vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int));
|
||||
/* <machine/reg.h> */
|
||||
struct reg;
|
||||
struct fpreg;
|
||||
struct dbreg;
|
||||
|
||||
#define PFIND(pid) ((pid) ? pfind(pid) : &proc0)
|
||||
|
||||
@ -137,9 +139,12 @@ int procfs_read_regs __P((struct proc *, struct reg *));
|
||||
int procfs_write_regs __P((struct proc *, struct reg *));
|
||||
int procfs_read_fpregs __P((struct proc *, struct fpreg *));
|
||||
int procfs_write_fpregs __P((struct proc *, struct fpreg *));
|
||||
int procfs_read_dbregs __P((struct proc *, struct dbreg *));
|
||||
int procfs_write_dbregs __P((struct proc *, struct dbreg *));
|
||||
int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dodbregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
|
||||
@ -155,6 +160,7 @@ int procfs_kmemaccess __P((struct proc *));
|
||||
int procfs_validfile __P((struct proc *));
|
||||
int procfs_validfpregs __P((struct proc *));
|
||||
int procfs_validregs __P((struct proc *));
|
||||
int procfs_validdbregs __P((struct proc *));
|
||||
int procfs_validmap __P((struct proc *));
|
||||
int procfs_validtype __P((struct proc *));
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
|
||||
*
|
||||
* $Id: procfs_subr.c,v 1.23 1999/01/27 22:42:07 dillon Exp $
|
||||
* $Id: procfs_subr.c,v 1.24 1999/04/30 13:04:21 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -167,6 +167,7 @@ loop:
|
||||
|
||||
case Pregs:
|
||||
case Pfpregs:
|
||||
case Pdbregs:
|
||||
pfs->pfs_mode = (VREAD|VWRITE);
|
||||
vp->v_type = VREG;
|
||||
break;
|
||||
@ -264,6 +265,10 @@ procfs_rw(ap)
|
||||
rtval = procfs_dofpregs(curp, p, pfs, uio);
|
||||
break;
|
||||
|
||||
case Pdbregs:
|
||||
rtval = procfs_dodbregs(curp, p, pfs, uio);
|
||||
break;
|
||||
|
||||
case Pctl:
|
||||
rtval = procfs_doctl(curp, p, pfs, uio);
|
||||
break;
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.68 1999/05/04 08:01:55 phk Exp $
|
||||
* $Id: procfs_vnops.c,v 1.69 1999/06/13 20:53:16 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -95,6 +95,7 @@ static struct proc_target {
|
||||
{ DT_REG, N("mem"), Pmem, NULL },
|
||||
{ DT_REG, N("regs"), Pregs, procfs_validregs },
|
||||
{ DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs },
|
||||
{ DT_REG, N("dbregs"), Pdbregs, procfs_validdbregs },
|
||||
{ DT_REG, N("ctl"), Pctl, NULL },
|
||||
{ DT_REG, N("status"), Pstatus, NULL },
|
||||
{ DT_REG, N("note"), Pnote, NULL },
|
||||
@ -491,6 +492,7 @@ procfs_getattr(ap)
|
||||
case Pctl:
|
||||
case Pregs:
|
||||
case Pfpregs:
|
||||
case Pdbregs:
|
||||
if (procp->p_flag & P_SUGID)
|
||||
vap->va_mode &= ~((VREAD|VWRITE)|
|
||||
((VREAD|VWRITE)>>3)|
|
||||
@ -571,6 +573,10 @@ procfs_getattr(ap)
|
||||
vap->va_bytes = vap->va_size = sizeof(struct fpreg);
|
||||
break;
|
||||
|
||||
case Pdbregs:
|
||||
vap->va_bytes = vap->va_size = sizeof(struct dbreg);
|
||||
break;
|
||||
|
||||
case Ptype:
|
||||
case Pmap:
|
||||
case Pctl:
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ptrace.h 8.1 (Berkeley) 6/11/93
|
||||
* $Id: ptrace.h,v 1.5 1997/02/22 09:35:03 peter Exp $
|
||||
* $Id: ptrace.h,v 1.6 1998/05/19 00:00:12 tegge Exp $
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_PTRACE_H_
|
||||
@ -44,6 +44,8 @@
|
||||
#define PT_SETREGS (PT_FIRSTMACH + 2)
|
||||
#define PT_GETFPREGS (PT_FIRSTMACH + 3)
|
||||
#define PT_SETFPREGS (PT_FIRSTMACH + 4)
|
||||
#define PT_GETDBREGS (PT_FIRSTMACH + 5)
|
||||
#define PT_SETDBREGS (PT_FIRSTMACH + 6)
|
||||
|
||||
#ifdef KERNEL
|
||||
int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len));
|
||||
|
Loading…
x
Reference in New Issue
Block a user