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