From 43621cbb3a61256cafc674bdb14f56f911625407 Mon Sep 17 00:00:00 2001 From: simonb Date: Thu, 6 Nov 2003 00:41:20 +0000 Subject: [PATCH] Add kernel portion of siginfo for ns32k. Much thanks to Christos Zoulas for doing this. --- sys/arch/pc532/conf/files.pc532 | 3 +- sys/arch/pc532/include/frame.h | 9 +- sys/arch/pc532/include/mcontext.h | 8 +- sys/arch/pc532/include/signal.h | 9 +- sys/arch/pc532/pc532/compat_16_machdep.c | 288 +++++++++++++++++++++++ sys/arch/pc532/pc532/locore.s | 10 +- sys/arch/pc532/pc532/machdep.c | 200 +++++----------- sys/arch/pc532/pc532/trap.c | 45 +++- 8 files changed, 420 insertions(+), 152 deletions(-) create mode 100644 sys/arch/pc532/pc532/compat_16_machdep.c diff --git a/sys/arch/pc532/conf/files.pc532 b/sys/arch/pc532/conf/files.pc532 index 8d8533f70fbe..efa7fa74cb56 100644 --- a/sys/arch/pc532/conf/files.pc532 +++ b/sys/arch/pc532/conf/files.pc532 @@ -1,4 +1,4 @@ -# $NetBSD: files.pc532,v 1.52 2003/10/27 07:26:17 simonb Exp $ +# $NetBSD: files.pc532,v 1.53 2003/11/06 00:41:20 simonb Exp $ # # new style config file for pc532 architecture # @@ -75,6 +75,7 @@ file netns/ns_cksum.c ns # Binary compatibility with previous NetBSD releases. # file arch/pc532/pc532/compat_13_machdep.c compat_13 +file arch/pc532/pc532/compat_16_machdep.c compat_16 # egcs-1.1.2 bug fix; see doc/HACKS - egcs-pc532-ip6_mroute file netinet6/ip6_mroute.c compile-with "${CC_OPT1}" diff --git a/sys/arch/pc532/include/frame.h b/sys/arch/pc532/include/frame.h index 4f82de113c8c..d71fb35a2292 100644 --- a/sys/arch/pc532/include/frame.h +++ b/sys/arch/pc532/include/frame.h @@ -1,4 +1,4 @@ -/* $NetBSD: frame.h,v 1.10 2003/08/07 16:28:59 agc Exp $ */ +/* $NetBSD: frame.h,v 1.11 2003/11/06 00:41:20 simonb Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -109,4 +109,11 @@ struct saframe { void* sa_arg; }; +#ifdef _KERNEL +void *getframe(struct lwp *, int, int *); +#ifdef COMPAT_16 +void sendsig_sigcontext(const ksiginfo_t *, const sigset_t *); +#endif +#endif + #endif /* _NS532_FRAME_H_ */ diff --git a/sys/arch/pc532/include/mcontext.h b/sys/arch/pc532/include/mcontext.h index 46e0cc4add84..197c6f1633d3 100644 --- a/sys/arch/pc532/include/mcontext.h +++ b/sys/arch/pc532/include/mcontext.h @@ -1,4 +1,4 @@ -/* $NetBSD: mcontext.h,v 1.2 2003/10/08 22:43:01 thorpej Exp $ */ +/* $NetBSD: mcontext.h,v 1.3 2003/11/06 00:41:20 simonb Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -71,6 +71,12 @@ typedef struct { __gregset_t __gregs; __fpregset_t __fpregs; } mcontext_t; +/* + * mcontext extensions to handle signal delivery. + */ +#define _UC_SETSTACK 0x00010000 +#define _UC_CLRSTACK 0x00020000 + #define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_SP]) #define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_PC]) diff --git a/sys/arch/pc532/include/signal.h b/sys/arch/pc532/include/signal.h index 00021b4deffa..6531a6721588 100644 --- a/sys/arch/pc532/include/signal.h +++ b/sys/arch/pc532/include/signal.h @@ -1,4 +1,4 @@ -/* $NetBSD: signal.h,v 1.10 2003/08/07 16:29:00 agc Exp $ */ +/* $NetBSD: signal.h,v 1.11 2003/11/06 00:41:20 simonb Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. @@ -38,6 +38,13 @@ typedef int sig_atomic_t; +#define __HAVE_SIGINFO +#ifdef COMPAT_16 +#define SIGTRAMP_VALID(vers) ((unsigned)(vers) <= 2) +#else +#define SIGTRAMP_VALID(vers) ((vers) == 2) +#endif + #if defined(_NETBSD_SOURCE) /* * Get the "code" values diff --git a/sys/arch/pc532/pc532/compat_16_machdep.c b/sys/arch/pc532/pc532/compat_16_machdep.c new file mode 100644 index 000000000000..3778f3b16a19 --- /dev/null +++ b/sys/arch/pc532/pc532/compat_16_machdep.c @@ -0,0 +1,288 @@ +/* $NetBSD: compat_16_machdep.c,v 1.1 2003/11/06 00:41:20 simonb Exp $ */ + +/*- + * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)machdep.c 7.4 (Berkeley) 6/3/91 + */ + +/*- + * Copyright (c) 1996 Matthias Pfaller. + * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved. + * Copyright (c) 1993 Philip A. Nelson. + * Copyright (c) 1992 Terrence R. Lambert. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)machdep.c 7.4 (Berkeley) 6/3/91 + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.1 2003/11/06 00:41:20 simonb Exp $"); + +#include "opt_ddb.h" +#include "opt_kgdb.h" +#include "opt_compat_netbsd.h" +#include "opt_ns381.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef COMPAT_16 +/* + * Send an interrupt to process. + * + * Stack is set up to allow sigcode stored + * in u. to call routine, followed by kcall + * to sigreturn routine below. After sigreturn + * resets the signal mask, the stack, and the + * frame pointer, it returns to the user + * specified pc, psl. + */ +void +sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask) +{ + struct lwp *l = curlwp; + struct proc *p = l->l_proc; + struct sigacts *ps = p->p_sigacts; + struct reg *regs; + int sig = ksi->ksi_signo; + int onstack; + struct sigframe *fp = getframe(l, sig, &onstack), frame; + sig_t catcher = SIGACTION(p, sig).sa_handler; + + regs = l->l_md.md_regs; + + fp--; + + /* Build stack frame for signal trampoline. */ + switch (ps->sa_sigdesc[sig].sd_vers) { + case 0: + frame.sf_ra = (int)p->p_sigctx.ps_sigcode; + break; + + case 1: + frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp; + break; + + default: + /* Don't know what trampoline version; kill it. */ + sigexit(l, SIGILL); + } + frame.sf_signum = sig; + frame.sf_code = ksi->ksi_trap; + frame.sf_scp = &fp->sf_sc; + + /* Save the register context. */ + frame.sf_sc.sc_fp = regs->r_fp; + frame.sf_sc.sc_sp = regs->r_sp; + frame.sf_sc.sc_pc = regs->r_pc; + frame.sf_sc.sc_ps = regs->r_psr; + frame.sf_sc.sc_sb = regs->r_sb; + frame.sf_sc.sc_reg[REG_R7] = regs->r_r7; + frame.sf_sc.sc_reg[REG_R6] = regs->r_r6; + frame.sf_sc.sc_reg[REG_R5] = regs->r_r5; + frame.sf_sc.sc_reg[REG_R4] = regs->r_r4; + frame.sf_sc.sc_reg[REG_R3] = regs->r_r3; + frame.sf_sc.sc_reg[REG_R2] = regs->r_r2; + frame.sf_sc.sc_reg[REG_R1] = regs->r_r1; + frame.sf_sc.sc_reg[REG_R0] = regs->r_r0; + + /* Save signal stack. */ + frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; + + /* Save the signal mask. */ + frame.sf_sc.sc_mask = *mask; + +#ifdef COMPAT_13 + /* + * XXX We always have to save an old style signal mask because + * XXX we might be delivering a signal to a process which will + * XXX escape from the signal in a non-standard way and invoke + * XXX sigreturn() directly. + */ + native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); +#endif + + if (copyout(&frame, fp, sizeof(frame)) != 0) { + /* + * Process has trashed its stack; give it an illegal + * instruction to halt it in its tracks. + */ + sigexit(l, SIGILL); + /* NOTREACHED */ + } + + /* + * Build context to run handler in. We invoke the handler + * directly, only returning via the trampoline. Note the + * trampoline version numbers are coordinated with machine- + * dependent code in libc. + */ + regs->r_sp = (int)fp; + regs->r_pc = (int)catcher; + + /* Remember that we're now on the signal stack. */ + if (onstack) + p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; +} + +/* + * System call to cleanup state after a signal + * has been taken. Reset signal mask and + * stack state from context left by sendsig (above). + * Return to previous pc and psl as specified by + * context left by sendsig. Check carefully to + * make sure that the user has not modified the + * psl to gain improper privileges or to cause + * a machine fault. + */ +int compat_16_sys___sigreturn14(struct lwp *, void *, register_t *); + +int +compat_16_sys___sigreturn14(struct lwp *l, void *v, register_t *retval) +{ + struct compat_16_sys___sigreturn14_args /* { + syscallarg(struct sigcontext *) sigcntxp; + } */ *uap = v; + struct proc *p = l->l_proc; + struct sigcontext *scp, context; + struct reg *regs; + + /* + * The trampoline code hands us the context. + * It is unsafe to keep track of it ourselves, in the event that a + * program jumps out of a signal handler. + */ + scp = SCARG(uap, sigcntxp); + if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0) + return (EFAULT); + + /* Restore the register context. */ + regs = l->l_md.md_regs; + + /* + * Check for security violations. + */ + if (((context.sc_ps ^ regs->r_psr) & PSL_USERSTATIC) != 0) + return (EINVAL); + + regs->r_fp = context.sc_fp; + regs->r_sp = context.sc_sp; + regs->r_pc = context.sc_pc; + regs->r_psr = context.sc_ps; + regs->r_sb = context.sc_sb; + regs->r_r7 = context.sc_reg[REG_R7]; + regs->r_r6 = context.sc_reg[REG_R6]; + regs->r_r5 = context.sc_reg[REG_R5]; + regs->r_r4 = context.sc_reg[REG_R4]; + regs->r_r3 = context.sc_reg[REG_R3]; + regs->r_r2 = context.sc_reg[REG_R2]; + regs->r_r1 = context.sc_reg[REG_R1]; + regs->r_r0 = context.sc_reg[REG_R0]; + + /* Restore signal stack. */ + if (context.sc_onstack & SS_ONSTACK) + p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; + else + p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; + + /* Restore signal mask. */ + (void) sigprocmask1(p, SIG_SETMASK, &context.sc_mask, 0); + + return(EJUSTRETURN); +} +#endif diff --git a/sys/arch/pc532/pc532/locore.s b/sys/arch/pc532/pc532/locore.s index 3890abfc058f..01f1430ccc1e 100644 --- a/sys/arch/pc532/pc532/locore.s +++ b/sys/arch/pc532/pc532/locore.s @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.72 2003/06/24 04:57:59 thorpej Exp $ */ +/* $NetBSD: locore.s,v 1.73 2003/11/06 00:41:20 simonb Exp $ */ /* * Copyright (c) 1993 Philip A. Nelson. @@ -39,11 +39,12 @@ * Modified by Matthias Pfaller, Jan 1996. * */ - +#define __HAVE_SIGINFO #include "opt_ddb.h" #include "opt_kgdb.h" #include "opt_cpu30mhz.h" #include "opt_ns381.h" +#include "opt_compat_netbsd.h" #include "assym.h" @@ -148,7 +149,7 @@ KENTRY(delay, 4) /* bsr 2 cycles; 80 ns */ /* * Signal trampoline; copied to top of user stack. */ - +#ifdef COMPAT_16 ENTRY_NOPROFILE(sigcode) /* * Handler has returned here as if we called it. The sigcontext @@ -156,7 +157,7 @@ ENTRY_NOPROFILE(sigcode) */ addr 12(sp),4(sp) /* get pointer to sigcontext and put it in the argument slot */ - movd SYS___sigreturn14,r0 + movd SYS_compat_16___sigreturn14,r0 svc .long 0x0000a517 /* movd 0,0 -- illegal instruction. */ GLOBAL(esigcode) @@ -165,6 +166,7 @@ GLOBAL(esigcode) /* Just a gap between esigcode and the next label */ .long 0 #endif +#endif /****************************************************************************/ diff --git a/sys/arch/pc532/pc532/machdep.c b/sys/arch/pc532/pc532/machdep.c index c86c3a9ee36b..3f62ed4df0a7 100644 --- a/sys/arch/pc532/pc532/machdep.c +++ b/sys/arch/pc532/pc532/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.148 2003/10/26 01:07:25 simonb Exp $ */ +/* $NetBSD: machdep.c,v 1.149 2003/11/06 00:41:21 simonb Exp $ */ /*- * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. @@ -75,7 +75,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.148 2003/10/26 01:07:25 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.149 2003/11/06 00:41:21 simonb Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -348,6 +348,29 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) /* NOTREACHED */ } +void * +getframe(struct lwp *l, int sig, int *onstack) +{ + struct proc *p = l->l_proc; + stack_t *ss = &p->p_sigctx.ps_sigstk; + + /* Do we need to jump onto the signal stack? */ + *onstack = (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && + (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; + + /* Allocate space for the signal handler context. */ + if (*onstack) + return (caddr_t)ss->ss_sp + ss->ss_size; + else + return (void *)l->l_md.md_regs->r_sp; +} + +struct sigframe_siginfo { + int sf_ra; + siginfo_t sf_si; + ucontext_t sf_uc; +}; + /* * Send an interrupt to process. * @@ -358,87 +381,45 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) * frame pointer, it returns to the user * specified pc, psl. */ -void -sendsig(sig, mask, code) - int sig; - const sigset_t *mask; - u_long code; +static void +sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; struct sigacts *ps = p->p_sigacts; - struct reg *regs; - struct sigframe *fp, frame; + int sig = ksi->ksi_signo; int onstack; + ucontext_t uc; + struct sigframe_siginfo *fp = getframe(l, sig, &onstack); sig_t catcher = SIGACTION(p, sig).sa_handler; + struct reg *regs = l->l_md.md_regs; - regs = l->l_md.md_regs; - - /* Do we need to jump onto the signal stack? */ - onstack = - (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && - (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; - - /* Allocate space for the signal handler context. */ - if (onstack) - fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp + - p->p_sigctx.ps_sigstk.ss_size); - else - fp = (struct sigframe *)regs->r_sp; fp--; /* Build stack frame for signal trampoline. */ switch (ps->sa_sigdesc[sig].sd_vers) { -#if 1 /* COMPAT_16 */ - case 0: - frame.sf_ra = (int)p->p_sigctx.ps_sigcode; - break; -#endif /* COMPAT_16 */ - - case 1: - frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp; - break; - - default: - /* Don't know what trampoline version; kill it. */ + case 0: /* handled by sendsig_sigcontext */ + case 1: /* handled by sendsig_sigcontext */ + default: /* unknown version */ + printf("sendsig_siginfo: bad version %d\n", + ps->sa_sigdesc[sig].sd_vers); sigexit(l, SIGILL); + case 2: + break; } - frame.sf_signum = sig; - frame.sf_code = code; - frame.sf_scp = &fp->sf_sc; - /* Save the register context. */ - frame.sf_sc.sc_fp = regs->r_fp; - frame.sf_sc.sc_sp = regs->r_sp; - frame.sf_sc.sc_pc = regs->r_pc; - frame.sf_sc.sc_ps = regs->r_psr; - frame.sf_sc.sc_sb = regs->r_sb; - frame.sf_sc.sc_reg[REG_R7] = regs->r_r7; - frame.sf_sc.sc_reg[REG_R6] = regs->r_r6; - frame.sf_sc.sc_reg[REG_R5] = regs->r_r5; - frame.sf_sc.sc_reg[REG_R4] = regs->r_r4; - frame.sf_sc.sc_reg[REG_R3] = regs->r_r3; - frame.sf_sc.sc_reg[REG_R2] = regs->r_r2; - frame.sf_sc.sc_reg[REG_R1] = regs->r_r1; - frame.sf_sc.sc_reg[REG_R0] = regs->r_r0; + uc.uc_flags = _UC_SIGMASK + | (p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) + ? _UC_SETSTACK : _UC_CLRSTACK; + uc.uc_sigmask = *mask; + uc.uc_link = NULL; + memset(&uc.uc_stack, 0, sizeof(uc.uc_stack)); + cpu_getmcontext(l, &uc.uc_mcontext, &uc.uc_flags); - /* Save signal stack. */ - frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; - - /* Save the signal mask. */ - frame.sf_sc.sc_mask = *mask; - -#ifdef COMPAT_13 - /* - * XXX We always have to save an old style signal mask because - * XXX we might be delivering a signal to a process which will - * XXX escape from the signal in a non-standard way and invoke - * XXX sigreturn() directly. - */ - native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); -#endif - - if (copyout(&frame, fp, sizeof(frame)) != 0) { + if (copyout(&ksi->ksi_info, &fp->sf_si, sizeof(ksi->ksi_info)) != 0 || + copyout(&uc, &fp->sf_uc, sizeof(uc)) != 0 || + copyout(&ps->sa_sigdesc[sig].sd_tramp, &fp->sf_ra, + sizeof(fp->sf_ra)) != 0) { /* * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. @@ -447,6 +428,7 @@ sendsig(sig, mask, code) /* NOTREACHED */ } + /* * Build context to run handler in. We invoke the handler * directly, only returning via the trampoline. Note the @@ -461,6 +443,17 @@ sendsig(sig, mask, code) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; } +void +sendsig(const ksiginfo_t *ksi, const sigset_t *mask) +{ +#ifdef COMPAT_16 + if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2) + sendsig_sigcontext(ksi, mask); + else +#endif + sendsig_siginfo(ksi, mask); +} + void cpu_upcall(l, type, nevents, ninterrupted, sas, ap, sp, upcall) struct lwp *l; @@ -492,73 +485,6 @@ cpu_upcall(l, type, nevents, ninterrupted, sas, ap, sp, upcall) regs->r_pc = (int) upcall; } -/* - * System call to cleanup state after a signal - * has been taken. Reset signal mask and - * stack state from context left by sendsig (above). - * Return to previous pc and psl as specified by - * context left by sendsig. Check carefully to - * make sure that the user has not modified the - * psl to gain improper privileges or to cause - * a machine fault. - */ -int -sys___sigreturn14(l, v, retval) - struct lwp *l; - void *v; - register_t *retval; -{ - struct sys___sigreturn14_args /* { - syscallarg(struct sigcontext *) sigcntxp; - } */ *uap = v; - struct proc *p = l->l_proc; - struct sigcontext *scp, context; - struct reg *regs; - - /* - * The trampoline code hands us the context. - * It is unsafe to keep track of it ourselves, in the event that a - * program jumps out of a signal handler. - */ - scp = SCARG(uap, sigcntxp); - if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0) - return (EFAULT); - - /* Restore the register context. */ - regs = l->l_md.md_regs; - - /* - * Check for security violations. - */ - if (((context.sc_ps ^ regs->r_psr) & PSL_USERSTATIC) != 0) - return (EINVAL); - - regs->r_fp = context.sc_fp; - regs->r_sp = context.sc_sp; - regs->r_pc = context.sc_pc; - regs->r_psr = context.sc_ps; - regs->r_sb = context.sc_sb; - regs->r_r7 = context.sc_reg[REG_R7]; - regs->r_r6 = context.sc_reg[REG_R6]; - regs->r_r5 = context.sc_reg[REG_R5]; - regs->r_r4 = context.sc_reg[REG_R4]; - regs->r_r3 = context.sc_reg[REG_R3]; - regs->r_r2 = context.sc_reg[REG_R2]; - regs->r_r1 = context.sc_reg[REG_R1]; - regs->r_r0 = context.sc_reg[REG_R0]; - - /* Restore signal stack. */ - if (context.sc_onstack & SS_ONSTACK) - p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; - - /* Restore signal mask. */ - (void) sigprocmask1(p, SIG_SETMASK, &context.sc_mask, 0); - - return(EJUSTRETURN); -} - void cpu_getmcontext(l, mcp, flags) struct lwp *l; @@ -618,6 +544,10 @@ cpu_setmcontext(l, mcp, flags) restore_fpu_context(&l->l_addr->u_pcb); } #endif + if (flags & _UC_SETSTACK) + l->l_proc->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; + if (flags & _UC_CLRSTACK) + l->l_proc->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; return (0); } diff --git a/sys/arch/pc532/pc532/trap.c b/sys/arch/pc532/pc532/trap.c index 6798463a5f01..efcc578a02de 100644 --- a/sys/arch/pc532/pc532/trap.c +++ b/sys/arch/pc532/pc532/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.60 2003/11/04 02:19:28 simonb Exp $ */ +/* $NetBSD: trap.c,v 1.61 2003/11/06 00:41:21 simonb Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.60 2003/11/04 02:19:28 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.61 2003/11/06 00:41:21 simonb Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -233,6 +233,7 @@ trap(frame) #ifdef CINVSMALL extern char cinvstart[], cinvend[]; #endif + ksiginfo_t ksi; uvmexp.traps++; @@ -343,7 +344,12 @@ trap(frame) } case T_ILL | T_USER: /* privileged instruction fault */ - trapsignal(l, SIGILL, type &~ T_USER); + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGILL; + ksi.ksi_trap = type & ~T_USER; + ksi.ksi_code = ILL_PRVOPC; + ksi.ksi_addr = (void *)frame.tf_regs.r_pc; + (*p->p_emul->e_trapsignal)(l, &ksi); goto out; case T_AST | T_USER: /* Allow process switch */ @@ -356,7 +362,12 @@ trap(frame) case T_OVF | T_USER: case T_DVZ | T_USER: - trapsignal(l, SIGFPE, type &~ T_USER); + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGFPE; + ksi.ksi_trap = type & ~T_USER; + ksi.ksi_code = ksi.ksi_trap == T_OVF ? FPE_FLTOVF : FPE_FLTDIV; + ksi.ksi_addr = (void *)frame.tf_regs.r_pc; + (*p->p_emul->e_trapsignal)(l, &ksi); goto out; case T_SLAVE | T_USER: { @@ -381,7 +392,12 @@ trap(frame) restore_fpu_context(pcb); } sfsr(fsr); - trapsignal(l, sig, 0x80000000 | fsr); + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGFPE; + ksi.ksi_trap = 0x80000000 | fsr; + ksi.ksi_code = sig == SIGFPE ? FPE_FLTOVF : FPE_FLTINV; + ksi.ksi_addr = (void *)frame.tf_regs.r_pc; + (*p->p_emul->e_trapsignal)(l, &ksi); goto out; } @@ -414,7 +430,7 @@ trap(frame) vaddr_t va; struct vmspace *vm = p->p_vmspace; struct vm_map *map; - int rv; + int rv, sig; vm_prot_t ftype; extern struct vm_map *kernel_map; unsigned nss; @@ -489,10 +505,16 @@ trap(frame) p->p_pid, p->p_comm, p->p_cred && p->p_ucred ? p->p_ucred->cr_uid : -1); - trapsignal(l, SIGKILL, T_ABT); + sig = SIGKILL; } else { - trapsignal(l, SIGSEGV, T_ABT); + sig = SIGSEGV; } + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_trap = T_ABT; + ksi.ksi_code = sig == SIGKILL ? SI_NOINFO : SEGV_MAPERR; + ksi.ksi_addr = (void *)frame.tf_tear; + (*p->p_emul->e_trapsignal)(l, &ksi); l->l_flag &= ~L_SA_PAGEFAULT; break; } @@ -501,7 +523,12 @@ trap(frame) case T_BPT | T_USER: /* breakpoint instruction */ case T_DBG | T_USER: /* debug trap */ trace: - trapsignal(l, SIGTRAP, type &~ T_USER); + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGTRAP; + ksi.ksi_trap = type & ~T_USER; + ksi.ksi_code = ksi.ksi_trap == T_TRC ? TRAP_TRACE : TRAP_BRKPT; + ksi.ksi_addr = (void *)frame.tf_regs.r_pc; + (*p->p_emul->e_trapsignal)(l, &ksi); break; case T_NMI: /* non-maskable interrupt */