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