diff options
-rw-r--r-- | sys/arch/vax/include/signal.h | 3 | ||||
-rw-r--r-- | sys/arch/vax/vax/machdep.c | 89 | ||||
-rw-r--r-- | sys/arch/vax/vax/subr.s | 12 |
3 files changed, 80 insertions, 24 deletions
diff --git a/sys/arch/vax/include/signal.h b/sys/arch/vax/include/signal.h index 75909a59e2e..3101c749350 100644 --- a/sys/arch/vax/include/signal.h +++ b/sys/arch/vax/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.5 2006/01/08 14:20:17 millert Exp $ */ +/* $OpenBSD: signal.h,v 1.6 2009/06/20 21:02:13 miod Exp $ */ /* $NetBSD: signal.h,v 1.4 1995/01/10 19:01:52 jtc Exp $ */ /* @@ -57,6 +57,7 @@ struct sigcontext { int sc_ap; /* ap to restore */ int sc_pc; /* pc to restore */ int sc_ps; /* psl to restore */ + int sc_r[12]; /* registers to restore */ }; #endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */ #endif /* !_VAX_SIGNAL_H_ */ diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c index 21aba9fe1d3..7d0ac9ae3b4 100644 --- a/sys/arch/vax/vax/machdep.c +++ b/sys/arch/vax/vax/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.101 2009/06/15 17:01:26 beck Exp $ */ +/* $OpenBSD: machdep.c,v 1.102 2009/06/20 21:02:15 miod Exp $ */ /* $NetBSD: machdep.c,v 1.108 2000/09/13 15:00:23 thorpej Exp $ */ /* @@ -385,6 +385,25 @@ consinit() #endif } +/* + * Old sigcontext structure, still used by userland until setjmp is fixed. + */ +struct osigcontext { + int sc_onstack; /* sigstack state to restore */ + int sc_mask; /* signal mask to restore */ + int sc_sp; /* sp to restore */ + int sc_fp; /* fp to restore */ + int sc_ap; /* ap to restore */ + int sc_pc; /* pc to restore */ + int sc_ps; /* psl to restore */ +}; + +/* + * Internal flags in the low order bits of sc_ap, to know whether this + * is an osigcontext or a sigcontext. + */ +#define SIGCONTEXT_NEW 0x01 + int sys_sigreturn(p, v, retval) struct proc *p; @@ -397,12 +416,20 @@ sys_sigreturn(p, v, retval) struct trapframe *scf; struct sigcontext *cntx; struct sigcontext ksc; + int error; scf = p->p_addr->u_pcb.framep; cntx = SCARG(uap, sigcntxp); - if (copyin((caddr_t)cntx, (caddr_t)&ksc, sizeof(struct sigcontext))) - return (EINVAL); + error = copyin((caddr_t)cntx, (caddr_t)&ksc, + sizeof(struct osigcontext)); + if (error == 0 && (ksc.sc_ap & SIGCONTEXT_NEW)) { + error = copyin((caddr_t)cntx + sizeof(struct osigcontext), + (caddr_t)&ksc.sc_r, + sizeof(struct sigcontext) - sizeof(struct osigcontext)); + } + if (error != 0) + return (error); /* Compatibility mode? */ if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) || @@ -418,20 +445,37 @@ sys_sigreturn(p, v, retval) p->p_sigmask = ksc.sc_mask & ~sigcantmask; scf->fp = ksc.sc_fp; - scf->ap = ksc.sc_ap; - scf->pc = ksc.sc_pc; + scf->ap = ksc.sc_ap & ~SIGCONTEXT_NEW; scf->sp = ksc.sc_sp; + if (ksc.sc_ap & SIGCONTEXT_NEW) { + scf->r0 = ksc.sc_r[0]; + scf->r1 = ksc.sc_r[1]; + scf->r2 = ksc.sc_r[2]; + scf->r3 = ksc.sc_r[3]; + scf->r4 = ksc.sc_r[4]; + scf->r5 = ksc.sc_r[5]; + scf->r6 = ksc.sc_r[6]; + scf->r7 = ksc.sc_r[7]; + scf->r8 = ksc.sc_r[8]; + scf->r9 = ksc.sc_r[9]; + scf->r10 = ksc.sc_r[10]; + scf->r11 = ksc.sc_r[11]; + } + scf->pc = ksc.sc_pc; scf->psl = ksc.sc_ps; return (EJUSTRETURN); } struct sigframe { + /* arguments of the signal handler */ int sf_signum; siginfo_t *sf_sip; struct sigcontext *sf_scp; - register_t sf_r0, sf_r1, sf_r2, sf_r3, sf_r4, sf_r5; + /* address of the signal handler */ register_t sf_pc; - register_t sf_arg; + /* sigcontext pointer for sigreturn */ + register_t sf_arg; + siginfo_t sf_si; struct sigcontext sf_sc; }; @@ -464,9 +508,9 @@ sendsig(catcher, sig, mask, code, type, val) sigf = (struct sigframe *) (cursp - sizeof(struct sigframe)); bzero(&gsigf, sizeof gsigf); - gsigf.sf_arg = (register_t)&sigf->sf_sc; gsigf.sf_pc = (register_t)catcher; gsigf.sf_scp = &sigf->sf_sc; + gsigf.sf_arg = (register_t)&sigf->sf_sc; gsigf.sf_signum = sig; if (psp->ps_siginfo & sigmask(sig)) { @@ -474,13 +518,25 @@ sendsig(catcher, sig, mask, code, type, val) initsiginfo(&gsigf.sf_si, sig, code, type, val); } - gsigf.sf_sc.sc_pc = syscf->pc; - gsigf.sf_sc.sc_ps = syscf->psl; - gsigf.sf_sc.sc_ap = syscf->ap; - gsigf.sf_sc.sc_fp = syscf->fp; - gsigf.sf_sc.sc_sp = syscf->sp; gsigf.sf_sc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; gsigf.sf_sc.sc_mask = mask; + gsigf.sf_sc.sc_sp = syscf->sp; + gsigf.sf_sc.sc_fp = syscf->fp; + gsigf.sf_sc.sc_ap = syscf->ap | SIGCONTEXT_NEW; + gsigf.sf_sc.sc_pc = syscf->pc; + gsigf.sf_sc.sc_ps = syscf->psl; + gsigf.sf_sc.sc_r[0] = syscf->r0; + gsigf.sf_sc.sc_r[1] = syscf->r1; + gsigf.sf_sc.sc_r[2] = syscf->r2; + gsigf.sf_sc.sc_r[3] = syscf->r3; + gsigf.sf_sc.sc_r[4] = syscf->r4; + gsigf.sf_sc.sc_r[5] = syscf->r5; + gsigf.sf_sc.sc_r[6] = syscf->r6; + gsigf.sf_sc.sc_r[7] = syscf->r7; + gsigf.sf_sc.sc_r[8] = syscf->r8; + gsigf.sf_sc.sc_r[9] = syscf->r9; + gsigf.sf_sc.sc_r[10] = syscf->r10; + gsigf.sf_sc.sc_r[11] = syscf->r11; #if defined(COMPAT_ULTRIX) native_sigset_to_sigset13(mask, &gsigf.sf_sc.__sc_mask13); @@ -494,10 +550,11 @@ sendsig(catcher, sig, mask, code, type, val) /* * Place sp at the beginning of sigf; this ensures that possible * further calls to sendsig won't overwrite this struct - * sigframe/struct sigcontext pair with their own. + * sigframe/struct sigcontext pair with their own. Also, set up + * ap for the sigreturn call from sigcode. */ - syscf->sp = syscf->ap = - (unsigned) sigf + offsetof(struct sigframe, sf_pc); + syscf->sp = (unsigned)sigf; + syscf->ap = (unsigned)sigf + offsetof(struct sigframe, sf_pc); if (onstack) psp->ps_sigstk.ss_flags |= SS_ONSTACK; diff --git a/sys/arch/vax/vax/subr.s b/sys/arch/vax/vax/subr.s index 68142c7d485..9b51e3017e6 100644 --- a/sys/arch/vax/vax/subr.s +++ b/sys/arch/vax/vax/subr.s @@ -1,4 +1,4 @@ -/* $OpenBSD: subr.s,v 1.28 2008/05/21 19:42:07 miod Exp $ */ +/* $OpenBSD: subr.s,v 1.29 2009/06/20 21:02:15 miod Exp $ */ /* $NetBSD: subr.s,v 1.32 1999/03/25 00:41:48 mrg Exp $ */ /* @@ -99,12 +99,10 @@ eskip: */ .globl _sigcode,_esigcode -_sigcode: pushr $0x3f - subl2 $0xc,sp - movl 0x24(sp),r0 - calls $3,(r0) - popr $0x3f - chmk $SYS_sigreturn +_sigcode: + movl 0x0c(sp),r0 /* get signal handler */ + calls $3,(r0) /* and call it */ + chmk $SYS_sigreturn /* sigreturn frame set up by sendsig */ chmk $SYS_exit halt .align 2 |