sig_machdep.c revision 1.7
1/* $NetBSD: sig_machdep.c,v 1.7 2002/07/04 23:32:06 thorpej Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include "opt_compat_netbsd.h" 35 36#include <sys/param.h> 37#include <sys/mount.h> 38#include <sys/proc.h> 39#include <sys/syscallargs.h> 40#include <sys/systm.h> 41#include <sys/user.h> 42 43/* 44 * Send a signal to process. 45 */ 46void 47sendsig(sig, mask, code) 48 int sig; 49 sigset_t *mask; 50 u_long code; 51{ 52 struct proc *p = curproc; 53 struct sigacts *ps = p->p_sigacts; 54 struct trapframe *tf; 55 struct sigframe *fp, frame; 56 int onstack; 57 sig_t catcher = SIGACTION(p, sig).sa_handler; 58 59 tf = trapframe(p); 60 61 /* Do we need to jump onto the signal stack? */ 62 onstack = 63 (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 64 (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 65 66 /* Allocate space for the signal handler context. */ 67 if (onstack) 68 fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp + 69 p->p_sigctx.ps_sigstk.ss_size); 70 else 71 fp = (struct sigframe *)tf->fixreg[1]; 72 fp = (struct sigframe *)((int)(fp - 1) & ~0xf); 73 74 /* Save register context. */ 75 frame.sf_sc.sc_frame = *tf; 76 77 /* Save signal stack. */ 78 frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; 79 80 /* Save signal mask. */ 81 frame.sf_sc.sc_mask = *mask; 82 83#ifdef COMPAT_13 84 /* 85 * XXX We always have to save an old style signal mask because 86 * XXX we might be delivering a signal to a process which will 87 * XXX escape from the signal in a non-standard way and invoke 88 * XXX sigreturn() directly. 89 */ 90 native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); 91#endif 92 93 if (copyout(&frame, fp, sizeof frame) != 0) { 94 /* 95 * Process has trashed its stack; give it an illegal 96 * instructoin to halt it in its tracks. 97 */ 98 sigexit(p, SIGILL); 99 /* NOTREACHED */ 100 } 101 102 /* 103 * Build context to run handler in. Note the trampoline version 104 * numbers are coordinated with machine-dependent code in libc. 105 */ 106 switch (ps->sa_sigdesc[sig].sd_vers) { 107#if 1 /* COMPAT_16 */ 108 case 0: /* legacy on-stack sigtramp */ 109 tf->fixreg[1] = (int)fp; 110 tf->lr = (int)catcher; 111 tf->fixreg[3] = (int)sig; 112 tf->fixreg[4] = (int)code; 113 tf->fixreg[5] = (int)&fp->sf_sc; 114 tf->srr0 = (int)p->p_sigctx.ps_sigcode; 115 break; 116#endif /* COMPAT_16 */ 117 118 case 1: 119 tf->fixreg[1] = (int)fp; 120 tf->lr = (int)catcher; 121 tf->fixreg[3] = (int)sig; 122 tf->fixreg[4] = (int)code; 123 tf->fixreg[5] = (int)&fp->sf_sc; 124 tf->srr0 = (int)ps->sa_sigdesc[sig].sd_tramp; 125 break; 126 127 default: 128 /* Don't know what trampoline version; kill it. */ 129 sigexit(p, SIGILL); 130 } 131 132 /* Remember that we're now on the signal stack. */ 133 if (onstack) 134 p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; 135} 136 137/* 138 * System call to cleanup state after a signal handler returns. 139 */ 140int 141sys___sigreturn14(p, v, retval) 142 struct proc *p; 143 void *v; 144 register_t *retval; 145{ 146 struct sys___sigreturn14_args /* { 147 syscallarg(struct sigcontext *) sigcntxp; 148 } */ *uap = v; 149 struct sigcontext sc; 150 struct trapframe *tf; 151 int error; 152 153 /* 154 * The trampoline hands us the context. 155 * It is unsafe to keep track of it ourselves, in the event that a 156 * program jumps out of a signal hander. 157 */ 158 if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0) 159 return (error); 160 161 /* Restore the register context. */ 162 tf = trapframe(p); 163 if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) 164 return (EINVAL); 165 *tf = sc.sc_frame; 166 167 /* Restore signal stack. */ 168 if (sc.sc_onstack & SS_ONSTACK) 169 p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; 170 else 171 p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; 172 173 /* Restore signal mask. */ 174 (void) sigprocmask1(p, SIG_SETMASK, &sc.sc_mask, 0); 175 176 return (EJUSTRETURN); 177} 178