summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/vax/include/signal.h3
-rw-r--r--sys/arch/vax/vax/machdep.c89
-rw-r--r--sys/arch/vax/vax/subr.s12
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