sig_machdep.c revision 1.1
11.1Skleink/*	$NetBSD: sig_machdep.c,v 1.1 1999/11/17 14:56:11 kleink 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.1Skleink
341.1Skleink#include <sys/param.h>
351.1Skleink#include <sys/mount.h>
361.1Skleink#include <sys/proc.h>
371.1Skleink#include <sys/syscallargs.h>
381.1Skleink#include <sys/systm.h>
391.1Skleink#include <sys/user.h>
401.1Skleink
411.1Skleink/*
421.1Skleink * Send a signal to process.
431.1Skleink */
441.1Skleinkvoid
451.1Skleinksendsig(catcher, sig, mask, code)
461.1Skleink	sig_t catcher;
471.1Skleink	int sig;
481.1Skleink	sigset_t *mask;
491.1Skleink	u_long code;
501.1Skleink{
511.1Skleink	struct proc *p = curproc;
521.1Skleink	struct trapframe *tf;
531.1Skleink	struct sigframe *fp, frame;
541.1Skleink	struct sigacts *psp = p->p_sigacts;
551.1Skleink	int onstack;
561.1Skleink
571.1Skleink	tf = trapframe(p);
581.1Skleink
591.1Skleink	/* Do we need to jump onto the signal stack? */
601.1Skleink	onstack =
611.1Skleink	    (psp->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
621.1Skleink	    (psp->ps_sigact[sig].sa_flags & SA_ONSTACK) != 0;
631.1Skleink
641.1Skleink	/* Allocate space for the signal handler context. */
651.1Skleink	if (onstack)
661.1Skleink		fp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp +
671.1Skleink						  psp->ps_sigstk.ss_size);
681.1Skleink	else
691.1Skleink		fp = (struct sigframe *)tf->fixreg[1];
701.1Skleink	fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
711.1Skleink
721.1Skleink	/* Build stack frame for signal trampoline. */
731.1Skleink	frame.sf_signum = sig;
741.1Skleink	frame.sf_code = code;
751.1Skleink
761.1Skleink	/* Save register context. */
771.1Skleink	bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
781.1Skleink
791.1Skleink	/* Save signal stack. */
801.1Skleink	frame.sf_sc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
811.1Skleink
821.1Skleink	/* Save signal mask. */
831.1Skleink	frame.sf_sc.sc_mask = *mask;
841.1Skleink
851.1Skleink#ifdef COMPAT_13
861.1Skleink	/*
871.1Skleink	 * XXX We always have to save an old style signal mask because
881.1Skleink	 * XXX we might be delivering a signal to a process which will
891.1Skleink	 * XXX escape from the signal in a non-standard way and invoke
901.1Skleink	 * XXX sigreturn() directly.
911.1Skleink	 */
921.1Skleink	native_sigset_to_sigset13(mask, &frame.sf_sc.__sc_mask13);
931.1Skleink#endif
941.1Skleink
951.1Skleink	if (copyout(&frame, fp, sizeof frame) != 0) {
961.1Skleink		/*
971.1Skleink		 * Process has trashed its stack; give it an illegal
981.1Skleink		 * instructoin to halt it in its tracks.
991.1Skleink		 */
1001.1Skleink		sigexit(p, SIGILL);
1011.1Skleink		/* NOTREACHED */
1021.1Skleink	}
1031.1Skleink
1041.1Skleink	/*
1051.1Skleink	 * Build context to run handler in.
1061.1Skleink	 */
1071.1Skleink	tf->fixreg[1] = (int)fp;
1081.1Skleink	tf->lr = (int)catcher;
1091.1Skleink	tf->fixreg[3] = (int)sig;
1101.1Skleink	tf->fixreg[4] = (int)code;
1111.1Skleink	tf->fixreg[5] = (int)&frame.sf_sc;
1121.1Skleink	tf->srr0 = (int)psp->ps_sigcode;
1131.1Skleink
1141.1Skleink	/* Remember that we're now on the signal stack. */
1151.1Skleink	if (onstack)
1161.1Skleink		psp->ps_sigstk.ss_flags |= SS_ONSTACK;
1171.1Skleink}
1181.1Skleink
1191.1Skleink/*
1201.1Skleink * System call to cleanup state after a signal handler returns.
1211.1Skleink */
1221.1Skleinkint
1231.1Skleinksys___sigreturn14(p, v, retval)
1241.1Skleink	struct proc *p;
1251.1Skleink	void *v;
1261.1Skleink	register_t *retval;
1271.1Skleink{
1281.1Skleink	struct sys___sigreturn14_args /* {
1291.1Skleink		syscallarg(struct sigcontext *) sigcntxp;
1301.1Skleink	} */ *uap = v;
1311.1Skleink	struct sigcontext sc;
1321.1Skleink	struct trapframe *tf;
1331.1Skleink	int error;
1341.1Skleink
1351.1Skleink	/*
1361.1Skleink	 * The trampoline hands us the context.
1371.1Skleink	 * It is unsafe to keep track of it ourselves, in the event that a
1381.1Skleink	 * program jumps out of a signal hander.
1391.1Skleink	 */
1401.1Skleink	if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0)
1411.1Skleink		return (error);
1421.1Skleink
1431.1Skleink	/* Restore the register context. */
1441.1Skleink	tf = trapframe(p);
1451.1Skleink	if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
1461.1Skleink		return (EINVAL);
1471.1Skleink	bcopy(&sc.sc_frame, tf, sizeof *tf);
1481.1Skleink
1491.1Skleink	/* Restore signal stack. */
1501.1Skleink	if (sc.sc_onstack & SS_ONSTACK)
1511.1Skleink		p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
1521.1Skleink	else
1531.1Skleink		p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
1541.1Skleink
1551.1Skleink	/* Restore signal mask. */
1561.1Skleink	(void) sigprocmask1(p, SIG_SETMASK, &sc.sc_mask, 0);
1571.1Skleink
1581.1Skleink	return (EJUSTRETURN);
1591.1Skleink}
160