version 1.41, 2002/05/10 15:25:13 |
version 1.41.6.7, 2002/08/02 19:51:36 |
|
|
#include <sys/mount.h> |
#include <sys/mount.h> |
#include <sys/proc.h> |
#include <sys/proc.h> |
#include <sys/signalvar.h> |
#include <sys/signalvar.h> |
|
#include <sys/sa.h> |
|
#include <sys/savar.h> |
#include <sys/syscallargs.h> |
#include <sys/syscallargs.h> |
|
#include <sys/ucontext.h> |
#include <sys/user.h> |
#include <sys/user.h> |
|
|
#ifdef KGDB |
#ifdef KGDB |
|
|
|
|
/* Setup proc0 */ |
/* Setup proc0 */ |
proc0paddr = (struct user *)u; |
proc0paddr = (struct user *)u; |
proc0.p_addr = proc0paddr; |
lwp0.l_addr = proc0paddr; |
/* |
/* |
* u-area map: |
* u-area map: |
* |user| .... | ............... | |
* |user| .... | ............... | |
|
|
* stack top ... r7_bank |
* stack top ... r7_bank |
* current stack ... r15 |
* current stack ... r15 |
*/ |
*/ |
curpcb = proc0.p_md.md_pcb = &proc0.p_addr->u_pcb; |
curpcb = lwp0.l_md.md_pcb = &lwp0.l_addr->u_pcb; |
curupte = proc0.p_md.md_upte; |
curupte = lwp0.l_md.md_upte; |
|
|
sf = &curpcb->pcb_sf; |
sf = &curpcb->pcb_sf; |
sf->sf_r6_bank = u + NBPG; |
sf->sf_r6_bank = u + NBPG; |
|
|
__asm__ __volatile__("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank)); |
__asm__ __volatile__("ldc %0, r6_bank" :: "r"(sf->sf_r6_bank)); |
__asm__ __volatile__("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank)); |
__asm__ __volatile__("ldc %0, r7_bank" :: "r"(sf->sf_r7_bank)); |
|
|
proc0.p_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1; |
lwp0.l_md.md_regs = (struct trapframe *)sf->sf_r6_bank - 1; |
#ifdef KSTACK_DEBUG |
#ifdef KSTACK_DEBUG |
memset((char *)(u + sizeof(struct user)), 0x5a, |
memset((char *)(u + sizeof(struct user)), 0x5a, |
NBPG - sizeof(struct user)); |
NBPG - sizeof(struct user)); |
|
|
} |
} |
|
|
/* |
/* |
|
* void cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, |
|
* void *sas, void *ap, void *sp, sa_upcall_t upcall): |
|
* |
|
* Send an upcall to userland. |
|
*/ |
|
void |
|
cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas, |
|
void *ap, void *sp, sa_upcall_t upcall) |
|
{ |
|
struct proc *p = l->l_proc; |
|
struct trapframe *tf; |
|
struct saframe *sf, frame; |
|
extern char sigcode[], upcallcode[]; |
|
|
|
tf = l->l_md.md_regs; |
|
|
|
/* Build the stack frame. */ |
|
#if 0 /* First 4 args in regs (see below). */ |
|
frame.sa_type = type; |
|
frame.sa_sas = sas; |
|
frame.sa_events = nevents; |
|
frame.sa_interrupted = ninterrupted; |
|
#endif |
|
frame.sa_arg = ap; |
|
|
|
sf = (struct saframe *)sp - 1; |
|
if (copyout(&frame, sf, sizeof(frame)) != 0) { |
|
/* Copying onto the stack didn't work. Die. */ |
|
sigexit(l, SIGILL); |
|
/* NOTREACHED */ |
|
} |
|
|
|
tf->tf_r4 = type; |
|
tf->tf_r5 = (int) sas; |
|
tf->tf_r6 = nevents; |
|
tf->tf_r7 = ninterrupted; |
|
|
|
tf->tf_spc = (int) upcall; |
|
tf->tf_pr = (int) ((caddr_t)p->p_sigctx.ps_sigcode + |
|
((caddr_t)upcallcode - (caddr_t)sigcode)); |
|
tf->tf_r15 = (int) sf; |
|
} |
|
|
|
/* |
* Send an interrupt to process. |
* Send an interrupt to process. |
* |
* |
* Stack is set up to allow sigcode stored |
* Stack is set up to allow sigcode stored |
|
|
* specified pc, psl. |
* specified pc, psl. |
*/ |
*/ |
void |
void |
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) |
sendsig(int sig, sigset_t *mask, u_long code) |
{ |
{ |
struct proc *p = curproc; |
struct lwp *l = curlwp; |
|
struct proc *p = l->l_proc; |
|
struct sigacts *ps = p->p_sigacts; |
struct trapframe *tf; |
struct trapframe *tf; |
struct sigframe *fp, frame; |
struct sigframe *fp, frame; |
int onstack; |
int onstack; |
|
sig_t catcher = SIGACTION(p, sig).sa_handler; |
|
|
tf = p->p_md.md_regs; |
tf = l->l_md.md_regs; |
|
|
/* Do we need to jump onto the signal stack? */ |
/* Do we need to jump onto the signal stack? */ |
onstack = |
onstack = |
Line 394 sendsig(sig_t catcher, int sig, sigset_t |
|
Line 444 sendsig(sig_t catcher, int sig, sigset_t |
|
fp = (struct sigframe *)tf->tf_r15; |
fp = (struct sigframe *)tf->tf_r15; |
fp--; |
fp--; |
|
|
/* Build stack frame for signal trampoline. */ |
|
frame.sf_signum = sig; |
|
frame.sf_code = code; |
|
frame.sf_scp = &fp->sf_sc; |
|
frame.sf_handler = catcher; |
|
|
|
/* Save register context. */ |
/* Save register context. */ |
frame.sf_sc.sc_ssr = tf->tf_ssr; |
frame.sf_sc.sc_ssr = tf->tf_ssr; |
frame.sf_sc.sc_spc = tf->tf_spc; |
frame.sf_sc.sc_spc = tf->tf_spc; |
Line 433 sendsig(sig_t catcher, int sig, sigset_t |
|
Line 477 sendsig(sig_t catcher, int sig, sigset_t |
|
* Process has trashed its stack; give it an illegal |
* Process has trashed its stack; give it an illegal |
* instruction to halt it in its tracks. |
* instruction to halt it in its tracks. |
*/ |
*/ |
sigexit(p, SIGILL); |
sigexit(l, SIGILL); |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
/* |
/* |
* Build context to run handler in. |
* Build context to run handler in. We invoke the handler |
|
* directly, only returning via the trampoline. |
*/ |
*/ |
tf->tf_spc = (int)p->p_sigctx.ps_sigcode; |
switch (ps->sa_sigdesc[sig].sd_vers) { |
|
#if 1 /* COMPAT_16 */ |
|
case 0: /* legacy on-stack sigtramp */ |
|
tf->tf_pr = (int)p->p_sigctx.ps_sigcode; |
|
break; |
|
#endif /* COMPAT_16 */ |
|
|
|
case 1: |
|
tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp; |
|
break; |
|
|
|
default: |
|
/* Don't know what trampoline version; kill it. */ |
|
sigexit(l, SIGILL); |
|
} |
|
|
|
tf->tf_r4 = sig; |
|
tf->tf_r5 = code; |
|
tf->tf_r6 = (int)&fp->sf_sc; |
|
tf->tf_spc = (int)catcher; |
tf->tf_r15 = (int)fp; |
tf->tf_r15 = (int)fp; |
|
|
/* Remember that we're now on the signal stack. */ |
/* Remember that we're now on the signal stack. */ |
Line 459 sendsig(sig_t catcher, int sig, sigset_t |
|
Line 523 sendsig(sig_t catcher, int sig, sigset_t |
|
* a machine fault. |
* a machine fault. |
*/ |
*/ |
int |
int |
sys___sigreturn14(struct proc *p, void *v, register_t *retval) |
sys___sigreturn14(struct lwp *l, void *v, register_t *retval) |
{ |
{ |
struct sys___sigreturn14_args /* { |
struct sys___sigreturn14_args /* { |
syscallarg(struct sigcontext *) sigcntxp; |
syscallarg(struct sigcontext *) sigcntxp; |
} */ *uap = v; |
} */ *uap = v; |
struct sigcontext *scp, context; |
struct sigcontext *scp, context; |
struct trapframe *tf; |
struct trapframe *tf; |
|
struct proc *p = l->l_proc; |
|
|
/* |
/* |
* The trampoline code hands us the context. |
* The trampoline code hands us the context. |
Line 477 sys___sigreturn14(struct proc *p, void * |
|
Line 542 sys___sigreturn14(struct proc *p, void * |
|
return (EFAULT); |
return (EFAULT); |
|
|
/* Restore signal context. */ |
/* Restore signal context. */ |
tf = p->p_md.md_regs; |
tf = l->l_md.md_regs; |
|
|
/* Check for security violations. */ |
/* Check for security violations. */ |
if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) |
if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) |
Line 515 sys___sigreturn14(struct proc *p, void * |
|
Line 580 sys___sigreturn14(struct proc *p, void * |
|
return (EJUSTRETURN); |
return (EJUSTRETURN); |
} |
} |
|
|
|
void |
|
cpu_getmcontext(l, mcp, flags) |
|
struct lwp *l; |
|
mcontext_t *mcp; |
|
unsigned int *flags; |
|
{ |
|
const struct trapframe *tf = l->l_md.md_regs; |
|
__greg_t *gr = mcp->__gregs; |
|
|
|
/* Save register context. */ |
|
gr[_REG_EXPEVT] = tf->tf_expevt; |
|
gr[_REG_PC] = tf->tf_spc; |
|
gr[_REG_SR] = tf->tf_ssr; |
|
gr[_REG_MACL] = tf->tf_macl; |
|
gr[_REG_MACH] = tf->tf_mach; |
|
gr[_REG_PR] = tf->tf_pr; |
|
gr[_REG_R14] = tf->tf_r14; |
|
gr[_REG_R13] = tf->tf_r13; |
|
gr[_REG_R12] = tf->tf_r12; |
|
gr[_REG_R11] = tf->tf_r11; |
|
gr[_REG_R10] = tf->tf_r10; |
|
gr[_REG_R9] = tf->tf_r9; |
|
gr[_REG_R8] = tf->tf_r8; |
|
gr[_REG_R7] = tf->tf_r7; |
|
gr[_REG_R6] = tf->tf_r6; |
|
gr[_REG_R5] = tf->tf_r5; |
|
gr[_REG_R4] = tf->tf_r4; |
|
gr[_REG_R3] = tf->tf_r3; |
|
gr[_REG_R2] = tf->tf_r2; |
|
gr[_REG_R1] = tf->tf_r1; |
|
gr[_REG_R0] = tf->tf_r0; |
|
gr[_REG_R15] = tf->tf_r15; |
|
*flags |= _UC_CPU; |
|
|
|
/* FPU context is currently not handled by the kernel. */ |
|
memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs)); |
|
} |
|
|
|
int |
|
cpu_setmcontext(l, mcp, flags) |
|
struct lwp *l; |
|
const mcontext_t *mcp; |
|
unsigned int flags; |
|
{ |
|
struct trapframe *tf = l->l_md.md_regs; |
|
const __greg_t *gr = mcp->__gregs; |
|
|
|
/* Restore register context, if any. */ |
|
if ((flags & _UC_CPU) != 0) { |
|
/* Check for security violations. */ |
|
if (((tf->tf_ssr ^ gr[_REG_SR]) & PSL_USERSTATIC) != 0) |
|
return (EINVAL); |
|
|
|
/* _REG_EXPEVT not restored */ |
|
tf->tf_spc = gr[_REG_PC]; |
|
tf->tf_ssr = gr[_REG_SR]; |
|
tf->tf_macl = gr[_REG_MACL]; |
|
tf->tf_mach = gr[_REG_MACH]; |
|
tf->tf_pr = gr[_REG_PR]; |
|
tf->tf_r14 = gr[_REG_R14]; |
|
tf->tf_r13 = gr[_REG_R13]; |
|
tf->tf_r12 = gr[_REG_R12]; |
|
tf->tf_r11 = gr[_REG_R11]; |
|
tf->tf_r10 = gr[_REG_R10]; |
|
tf->tf_r9 = gr[_REG_R9]; |
|
tf->tf_r8 = gr[_REG_R8]; |
|
tf->tf_r7 = gr[_REG_R7]; |
|
tf->tf_r6 = gr[_REG_R6]; |
|
tf->tf_r5 = gr[_REG_R5]; |
|
tf->tf_r4 = gr[_REG_R4]; |
|
tf->tf_r3 = gr[_REG_R3]; |
|
tf->tf_r2 = gr[_REG_R2]; |
|
tf->tf_r1 = gr[_REG_R1]; |
|
tf->tf_r0 = gr[_REG_R0]; |
|
tf->tf_r15 = gr[_REG_R15]; |
|
} |
|
|
|
return (0); |
|
} |
|
|
/* |
/* |
* Clear registers on exec |
* Clear registers on exec |
*/ |
*/ |
void |
void |
setregs(struct proc *p, struct exec_package *pack, u_long stack) |
setregs(struct lwp *l, struct exec_package *pack, u_long stack) |
{ |
{ |
struct trapframe *tf; |
struct trapframe *tf; |
|
|
p->p_md.md_flags &= ~MDP_USEDFPU; |
l->l_md.md_flags &= ~MDP_USEDFPU; |
|
|
tf = p->p_md.md_regs; |
tf = l->l_md.md_regs; |
|
|
tf->tf_r0 = 0; |
tf->tf_r0 = 0; |
tf->tf_r1 = 0; |
tf->tf_r1 = 0; |
Line 536 setregs(struct proc *p, struct exec_pack |
|
Line 681 setregs(struct proc *p, struct exec_pack |
|
tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */ |
tf->tf_r6 = stack + 4 * tf->tf_r4 + 8; /* envp */ |
tf->tf_r7 = 0; |
tf->tf_r7 = 0; |
tf->tf_r8 = 0; |
tf->tf_r8 = 0; |
tf->tf_r9 = (int)p->p_psstr; |
tf->tf_r9 = (int)l->l_proc->p_psstr; |
tf->tf_r10 = 0; |
tf->tf_r10 = 0; |
tf->tf_r11 = 0; |
tf->tf_r11 = 0; |
tf->tf_r12 = 0; |
tf->tf_r12 = 0; |