sig_machdep.c revision 1.7
11.7Sthorpej/* $NetBSD: sig_machdep.c,v 1.7 2002/07/04 23:32:06 thorpej Exp $ */ 21.1Skleink 31.1Skleink/* 41.1Skleink * Copyright (C) 1995, 1996 Wolfgang Solfrank. 51.1Skleink * Copyright (C) 1995, 1996 TooLs GmbH. 61.1Skleink * All rights reserved. 71.1Skleink * 81.1Skleink * Redistribution and use in source and binary forms, with or without 91.1Skleink * modification, are permitted provided that the following conditions 101.1Skleink * are met: 111.1Skleink * 1. Redistributions of source code must retain the above copyright 121.1Skleink * notice, this list of conditions and the following disclaimer. 131.1Skleink * 2. Redistributions in binary form must reproduce the above copyright 141.1Skleink * notice, this list of conditions and the following disclaimer in the 151.1Skleink * documentation and/or other materials provided with the distribution. 161.1Skleink * 3. All advertising materials mentioning features or use of this software 171.1Skleink * must display the following acknowledgement: 181.1Skleink * This product includes software developed by TooLs GmbH. 191.1Skleink * 4. The name of TooLs GmbH may not be used to endorse or promote products 201.1Skleink * derived from this software without specific prior written permission. 211.1Skleink * 221.1Skleink * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 231.1Skleink * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 241.1Skleink * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 251.1Skleink * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 261.1Skleink * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 271.1Skleink * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 281.1Skleink * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 291.1Skleink * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 301.1Skleink * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 311.1Skleink * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321.1Skleink */ 331.2Stsubai 341.2Stsubai#include "opt_compat_netbsd.h" 351.1Skleink 361.1Skleink#include <sys/param.h> 371.1Skleink#include <sys/mount.h> 381.1Skleink#include <sys/proc.h> 391.1Skleink#include <sys/syscallargs.h> 401.1Skleink#include <sys/systm.h> 411.1Skleink#include <sys/user.h> 421.1Skleink 431.1Skleink/* 441.1Skleink * Send a signal to process. 451.1Skleink */ 461.1Skleinkvoid 471.7Sthorpejsendsig(sig, mask, code) 481.1Skleink int sig; 491.1Skleink sigset_t *mask; 501.1Skleink u_long code; 511.1Skleink{ 521.1Skleink struct proc *p = curproc; 531.7Sthorpej struct sigacts *ps = p->p_sigacts; 541.1Skleink struct trapframe *tf; 551.1Skleink struct sigframe *fp, frame; 561.1Skleink int onstack; 571.7Sthorpej sig_t catcher = SIGACTION(p, sig).sa_handler; 581.1Skleink 591.1Skleink tf = trapframe(p); 601.1Skleink 611.1Skleink /* Do we need to jump onto the signal stack? */ 621.1Skleink onstack = 631.4Sjdolecek (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 641.4Sjdolecek (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 651.1Skleink 661.1Skleink /* Allocate space for the signal handler context. */ 671.1Skleink if (onstack) 681.4Sjdolecek fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp + 691.4Sjdolecek p->p_sigctx.ps_sigstk.ss_size); 701.1Skleink else 711.1Skleink fp = (struct sigframe *)tf->fixreg[1]; 721.1Skleink fp = (struct sigframe *)((int)(fp - 1) & ~0xf); 731.1Skleink 741.1Skleink /* Save register context. */ 751.5Smatt frame.sf_sc.sc_frame = *tf; 761.1Skleink 771.1Skleink /* Save signal stack. */ 781.4Sjdolecek frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; 791.1Skleink 801.1Skleink /* Save signal mask. */ 811.1Skleink frame.sf_sc.sc_mask = *mask; 821.1Skleink 831.1Skleink#ifdef COMPAT_13 841.1Skleink /* 851.1Skleink * XXX We always have to save an old style signal mask because 861.1Skleink * XXX we might be delivering a signal to a process which will 871.1Skleink * XXX escape from the signal in a non-standard way and invoke 881.1Skleink * XXX sigreturn() directly. 891.1Skleink */ 901.1Skleink native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13); 911.1Skleink#endif 921.1Skleink 931.1Skleink if (copyout(&frame, fp, sizeof frame) != 0) { 941.1Skleink /* 951.1Skleink * Process has trashed its stack; give it an illegal 961.1Skleink * instructoin to halt it in its tracks. 971.1Skleink */ 981.1Skleink sigexit(p, SIGILL); 991.1Skleink /* NOTREACHED */ 1001.1Skleink } 1011.1Skleink 1021.1Skleink /* 1031.7Sthorpej * Build context to run handler in. Note the trampoline version 1041.7Sthorpej * numbers are coordinated with machine-dependent code in libc. 1051.1Skleink */ 1061.7Sthorpej switch (ps->sa_sigdesc[sig].sd_vers) { 1071.7Sthorpej#if 1 /* COMPAT_16 */ 1081.7Sthorpej case 0: /* legacy on-stack sigtramp */ 1091.7Sthorpej tf->fixreg[1] = (int)fp; 1101.7Sthorpej tf->lr = (int)catcher; 1111.7Sthorpej tf->fixreg[3] = (int)sig; 1121.7Sthorpej tf->fixreg[4] = (int)code; 1131.7Sthorpej tf->fixreg[5] = (int)&fp->sf_sc; 1141.7Sthorpej tf->srr0 = (int)p->p_sigctx.ps_sigcode; 1151.7Sthorpej break; 1161.7Sthorpej#endif /* COMPAT_16 */ 1171.7Sthorpej 1181.7Sthorpej case 1: 1191.7Sthorpej tf->fixreg[1] = (int)fp; 1201.7Sthorpej tf->lr = (int)catcher; 1211.7Sthorpej tf->fixreg[3] = (int)sig; 1221.7Sthorpej tf->fixreg[4] = (int)code; 1231.7Sthorpej tf->fixreg[5] = (int)&fp->sf_sc; 1241.7Sthorpej tf->srr0 = (int)ps->sa_sigdesc[sig].sd_tramp; 1251.7Sthorpej break; 1261.7Sthorpej 1271.7Sthorpej default: 1281.7Sthorpej /* Don't know what trampoline version; kill it. */ 1291.7Sthorpej sigexit(p, SIGILL); 1301.7Sthorpej } 1311.1Skleink 1321.1Skleink /* Remember that we're now on the signal stack. */ 1331.1Skleink if (onstack) 1341.4Sjdolecek p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; 1351.1Skleink} 1361.1Skleink 1371.1Skleink/* 1381.1Skleink * System call to cleanup state after a signal handler returns. 1391.1Skleink */ 1401.1Skleinkint 1411.1Skleinksys___sigreturn14(p, v, retval) 1421.1Skleink struct proc *p; 1431.1Skleink void *v; 1441.1Skleink register_t *retval; 1451.1Skleink{ 1461.1Skleink struct sys___sigreturn14_args /* { 1471.1Skleink syscallarg(struct sigcontext *) sigcntxp; 1481.1Skleink } */ *uap = v; 1491.1Skleink struct sigcontext sc; 1501.1Skleink struct trapframe *tf; 1511.1Skleink int error; 1521.1Skleink 1531.1Skleink /* 1541.1Skleink * The trampoline hands us the context. 1551.1Skleink * It is unsafe to keep track of it ourselves, in the event that a 1561.1Skleink * program jumps out of a signal hander. 1571.1Skleink */ 1581.1Skleink if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0) 1591.1Skleink return (error); 1601.1Skleink 1611.1Skleink /* Restore the register context. */ 1621.1Skleink tf = trapframe(p); 1631.1Skleink if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) 1641.1Skleink return (EINVAL); 1651.5Smatt *tf = sc.sc_frame; 1661.1Skleink 1671.1Skleink /* Restore signal stack. */ 1681.1Skleink if (sc.sc_onstack & SS_ONSTACK) 1691.4Sjdolecek p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; 1701.1Skleink else 1711.4Sjdolecek p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; 1721.1Skleink 1731.1Skleink /* Restore signal mask. */ 1741.1Skleink (void) sigprocmask1(p, SIG_SETMASK, &sc.sc_mask, 0); 1751.1Skleink 1761.1Skleink return (EJUSTRETURN); 1771.1Skleink} 178