diff options
-rw-r--r-- | sys/pc98/i386/machdep.c | 83 | ||||
-rw-r--r-- | sys/pc98/pc98/machdep.c | 83 |
2 files changed, 164 insertions, 2 deletions
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 4b24ce7..690fdcb 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.124 1999/07/05 08:52:54 msmith Exp $ + * $Id: machdep.c,v 1.125 1999/07/08 12:48:53 kato Exp $ */ #include "apm.h" @@ -2163,6 +2163,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) diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 4b24ce7..690fdcb 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.124 1999/07/05 08:52:54 msmith Exp $ + * $Id: machdep.c,v 1.125 1999/07/08 12:48:53 kato Exp $ */ #include "apm.h" @@ -2163,6 +2163,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) |