sig_machdep.c revision 1.5
11.5Smatt/*	$NetBSD: sig_machdep.c,v 1.5 2001/05/28 00:12:21 matt 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.1Skleinksendsig(catcher, sig, mask, code)
481.1Skleink	sig_t catcher;
491.1Skleink	int sig;
501.1Skleink	sigset_t *mask;
511.1Skleink	u_long code;
521.1Skleink{
531.1Skleink	struct proc *p = curproc;
541.1Skleink	struct trapframe *tf;
551.1Skleink	struct sigframe *fp, frame;
561.1Skleink	int onstack;
571.1Skleink
581.1Skleink	tf = trapframe(p);
591.1Skleink
601.1Skleink	/* Do we need to jump onto the signal stack? */
611.1Skleink	onstack =
621.4Sjdolecek	    (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
631.4Sjdolecek	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
641.1Skleink
651.1Skleink	/* Allocate space for the signal handler context. */
661.1Skleink	if (onstack)
671.4Sjdolecek		fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
681.4Sjdolecek						p->p_sigctx.ps_sigstk.ss_size);
691.1Skleink	else
701.1Skleink		fp = (struct sigframe *)tf->fixreg[1];
711.1Skleink	fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
721.1Skleink
731.1Skleink	/* Build stack frame for signal trampoline. */
741.1Skleink	frame.sf_signum = sig;
751.1Skleink	frame.sf_code = code;
761.1Skleink
771.1Skleink	/* Save register context. */
781.5Smatt	frame.sf_sc.sc_frame = *tf;
791.1Skleink
801.1Skleink	/* Save signal stack. */
811.4Sjdolecek	frame.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
821.1Skleink
831.1Skleink	/* Save signal mask. */
841.1Skleink	frame.sf_sc.sc_mask = *mask;
851.1Skleink
861.1Skleink#ifdef COMPAT_13
871.1Skleink	/*
881.1Skleink	 * XXX We always have to save an old style signal mask because
891.1Skleink	 * XXX we might be delivering a signal to a process which will
901.1Skleink	 * XXX escape from the signal in a non-standard way and invoke
911.1Skleink	 * XXX sigreturn() directly.
921.1Skleink	 */
931.1Skleink	native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13);
941.1Skleink#endif
951.1Skleink
961.1Skleink	if (copyout(&frame, fp, sizeof frame) != 0) {
971.1Skleink		/*
981.1Skleink		 * Process has trashed its stack; give it an illegal
991.1Skleink		 * instructoin to halt it in its tracks.
1001.1Skleink		 */
1011.1Skleink		sigexit(p, SIGILL);
1021.1Skleink		/* NOTREACHED */
1031.1Skleink	}
1041.1Skleink
1051.1Skleink	/*
1061.1Skleink	 * Build context to run handler in.
1071.1Skleink	 */
1081.1Skleink	tf->fixreg[1] = (int)fp;
1091.1Skleink	tf->lr = (int)catcher;
1101.1Skleink	tf->fixreg[3] = (int)sig;
1111.1Skleink	tf->fixreg[4] = (int)code;
1121.3Stsubai	tf->fixreg[5] = (int)&fp->sf_sc;
1131.4Sjdolecek	tf->srr0 = (int)p->p_sigctx.ps_sigcode;
1141.1Skleink
1151.1Skleink	/* Remember that we're now on the signal stack. */
1161.1Skleink	if (onstack)
1171.4Sjdolecek		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
1181.1Skleink}
1191.1Skleink
1201.1Skleink/*
1211.1Skleink * System call to cleanup state after a signal handler returns.
1221.1Skleink */
1231.1Skleinkint
1241.1Skleinksys___sigreturn14(p, v, retval)
1251.1Skleink	struct proc *p;
1261.1Skleink	void *v;
1271.1Skleink	register_t *retval;
1281.1Skleink{
1291.1Skleink	struct sys___sigreturn14_args /* {
1301.1Skleink		syscallarg(struct sigcontext *) sigcntxp;
1311.1Skleink	} */ *uap = v;
1321.1Skleink	struct sigcontext sc;
1331.1Skleink	struct trapframe *tf;
1341.1Skleink	int error;
1351.1Skleink
1361.1Skleink	/*
1371.1Skleink	 * The trampoline hands us the context.
1381.1Skleink	 * It is unsafe to keep track of it ourselves, in the event that a
1391.1Skleink	 * program jumps out of a signal hander.
1401.1Skleink	 */
1411.1Skleink	if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0)
1421.1Skleink		return (error);
1431.1Skleink
1441.1Skleink	/* Restore the register context. */
1451.1Skleink	tf = trapframe(p);
1461.1Skleink	if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
1471.1Skleink		return (EINVAL);
1481.5Smatt	*tf = sc.sc_frame;
1491.1Skleink
1501.1Skleink	/* Restore signal stack. */
1511.1Skleink	if (sc.sc_onstack & SS_ONSTACK)
1521.4Sjdolecek		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
1531.1Skleink	else
1541.4Sjdolecek		p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
1551.1Skleink
1561.1Skleink	/* Restore signal mask. */
1571.1Skleink	(void) sigprocmask1(p, SIG_SETMASK, &sc.sc_mask, 0);
1581.1Skleink
1591.1Skleink	return (EJUSTRETURN);
1601.1Skleink}
161