Home | History | Annotate | Line # | Download | only in hppa
sig_machdep.c revision 1.10
      1  1.10       chs /*	$NetBSD: sig_machdep.c,v 1.10 2004/07/18 23:21:35 chs Exp $	*/
      2   1.1  fredette 
      3   1.1  fredette /*-
      4   1.1  fredette  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      5   1.1  fredette  * All rights reserved.
      6   1.1  fredette  *
      7   1.1  fredette  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1  fredette  * by Matthew Fredette.
      9   1.1  fredette  *
     10   1.1  fredette  * Redistribution and use in source and binary forms, with or without
     11   1.1  fredette  * modification, are permitted provided that the following conditions
     12   1.1  fredette  * are met:
     13   1.1  fredette  * 1. Redistributions of source code must retain the above copyright
     14   1.1  fredette  *    notice, this list of conditions and the following disclaimer.
     15   1.1  fredette  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  fredette  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  fredette  *    documentation and/or other materials provided with the distribution.
     18   1.1  fredette  * 3. All advertising materials mentioning features or use of this software
     19   1.1  fredette  *    must display the following acknowledgement:
     20   1.1  fredette  *      This product includes software developed by the NetBSD
     21   1.1  fredette  *      Foundation, Inc. and its contributors.
     22   1.1  fredette  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23   1.1  fredette  *    contributors may be used to endorse or promote products derived
     24   1.1  fredette  *    from this software without specific prior written permission.
     25   1.1  fredette  *
     26   1.1  fredette  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27   1.1  fredette  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28   1.1  fredette  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29   1.1  fredette  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30   1.1  fredette  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31   1.1  fredette  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32   1.1  fredette  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33   1.1  fredette  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34   1.1  fredette  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35   1.1  fredette  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36   1.1  fredette  * POSSIBILITY OF SUCH DAMAGE.
     37   1.1  fredette  */
     38   1.1  fredette 
     39   1.1  fredette /*
     40   1.1  fredette  * Copyright (c) 1982, 1986, 1990, 1993
     41   1.1  fredette  *	The Regents of the University of California.  All rights reserved.
     42   1.1  fredette  *
     43   1.1  fredette  * This code is derived from software contributed to Berkeley by
     44   1.1  fredette  * the Systems Programming Group of the University of Utah Computer
     45   1.1  fredette  * Science Department.
     46   1.1  fredette  *
     47   1.1  fredette  * Redistribution and use in source and binary forms, with or without
     48   1.1  fredette  * modification, are permitted provided that the following conditions
     49   1.1  fredette  * are met:
     50   1.1  fredette  * 1. Redistributions of source code must retain the above copyright
     51   1.1  fredette  *    notice, this list of conditions and the following disclaimer.
     52   1.1  fredette  * 2. Redistributions in binary form must reproduce the above copyright
     53   1.1  fredette  *    notice, this list of conditions and the following disclaimer in the
     54   1.1  fredette  *    documentation and/or other materials provided with the distribution.
     55   1.4       agc  * 3. Neither the name of the University nor the names of its contributors
     56   1.4       agc  *    may be used to endorse or promote products derived from this software
     57   1.4       agc  *    without specific prior written permission.
     58   1.4       agc  *
     59   1.4       agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     60   1.4       agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     61   1.4       agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     62   1.4       agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     63   1.4       agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     64   1.4       agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     65   1.4       agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     66   1.4       agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     67   1.4       agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     68   1.4       agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     69   1.4       agc  * SUCH DAMAGE.
     70   1.4       agc  *
     71   1.4       agc  *	from: Utah Hdr: machdep.c 1.74 92/12/20
     72   1.4       agc  *	from: @(#)machdep.c	8.10 (Berkeley) 4/20/94
     73   1.4       agc  */
     74   1.4       agc /*
     75   1.4       agc  * Copyright (c) 1988 University of Utah.
     76   1.4       agc  *
     77   1.4       agc  * This code is derived from software contributed to Berkeley by
     78   1.4       agc  * the Systems Programming Group of the University of Utah Computer
     79   1.4       agc  * Science Department.
     80   1.4       agc  *
     81   1.4       agc  * Redistribution and use in source and binary forms, with or without
     82   1.4       agc  * modification, are permitted provided that the following conditions
     83   1.4       agc  * are met:
     84   1.4       agc  * 1. Redistributions of source code must retain the above copyright
     85   1.4       agc  *    notice, this list of conditions and the following disclaimer.
     86   1.4       agc  * 2. Redistributions in binary form must reproduce the above copyright
     87   1.4       agc  *    notice, this list of conditions and the following disclaimer in the
     88   1.4       agc  *    documentation and/or other materials provided with the distribution.
     89   1.1  fredette  * 3. All advertising materials mentioning features or use of this software
     90   1.1  fredette  *    must display the following acknowledgement:
     91   1.1  fredette  *	This product includes software developed by the University of
     92   1.1  fredette  *	California, Berkeley and its contributors.
     93   1.1  fredette  * 4. Neither the name of the University nor the names of its contributors
     94   1.1  fredette  *    may be used to endorse or promote products derived from this software
     95   1.1  fredette  *    without specific prior written permission.
     96   1.1  fredette  *
     97   1.1  fredette  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     98   1.1  fredette  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     99   1.1  fredette  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    100   1.1  fredette  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    101   1.1  fredette  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    102   1.1  fredette  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    103   1.1  fredette  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    104   1.1  fredette  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    105   1.1  fredette  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    106   1.1  fredette  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    107   1.1  fredette  * SUCH DAMAGE.
    108   1.1  fredette  *
    109   1.1  fredette  *	from: Utah Hdr: machdep.c 1.74 92/12/20
    110   1.1  fredette  *	from: @(#)machdep.c	8.10 (Berkeley) 4/20/94
    111   1.1  fredette  */
    112   1.3     lukem 
    113   1.3     lukem #include <sys/cdefs.h>
    114  1.10       chs __KERNEL_RCSID(0, "$NetBSD: sig_machdep.c,v 1.10 2004/07/18 23:21:35 chs Exp $");
    115   1.1  fredette 
    116   1.1  fredette #include "opt_compat_netbsd.h"
    117   1.1  fredette 
    118   1.1  fredette #define __HPPA_SIGNAL_PRIVATE
    119   1.1  fredette 
    120   1.1  fredette #include <sys/param.h>
    121   1.1  fredette #include <sys/systm.h>
    122   1.1  fredette #include <sys/kernel.h>
    123   1.1  fredette #include <sys/proc.h>
    124   1.1  fredette #include <sys/user.h>
    125   1.1  fredette #include <sys/signal.h>
    126   1.1  fredette #include <sys/signalvar.h>
    127   1.1  fredette 
    128   1.1  fredette #include <sys/mount.h>
    129   1.5       chs #include <sys/sa.h>
    130   1.1  fredette #include <sys/syscallargs.h>
    131   1.1  fredette 
    132   1.1  fredette #include <machine/cpu.h>
    133   1.1  fredette #include <machine/reg.h>
    134  1.10       chs #include <machine/frame.h>
    135   1.1  fredette 
    136   1.1  fredette #ifdef DEBUG
    137   1.9       chs int sigdebug = 0;
    138   1.1  fredette int sigpid = 0;
    139   1.1  fredette #define SDB_FOLLOW	0x01
    140   1.1  fredette #define SDB_KSTACK	0x02
    141   1.1  fredette #define SDB_FPSTATE	0x04
    142   1.1  fredette #endif
    143   1.1  fredette 
    144  1.10       chs void sendsig_sigcontext(const struct ksiginfo *, const sigset_t *);
    145  1.10       chs 
    146   1.1  fredette /*
    147   1.1  fredette  * Send an interrupt to process.
    148   1.1  fredette  */
    149   1.1  fredette void
    150  1.10       chs sendsig_sigcontext(const struct ksiginfo *ksi, const sigset_t *mask)
    151   1.1  fredette {
    152   1.8  drochner 	int sig = ksi->ksi_signo;
    153   1.8  drochner 	u_long code = ksi->ksi_trap;
    154   1.8  drochner 
    155   1.5       chs 	struct lwp *l = curlwp;
    156   1.5       chs 	struct proc *p = l->l_proc;
    157   1.2   thorpej 	struct sigacts *ps = p->p_sigacts;
    158   1.1  fredette 	struct sigframe *fp, kf;
    159   1.1  fredette 	caddr_t sp;
    160   1.1  fredette 	struct trapframe *tf;
    161   1.1  fredette 	int onstack, fsize;
    162   1.2   thorpej 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    163   1.1  fredette 
    164   1.5       chs 	tf = (struct trapframe *)l->l_md.md_regs;
    165   1.1  fredette 
    166   1.1  fredette 	/* Do we need to jump onto the signal stack? */
    167   1.1  fredette 	onstack =
    168   1.1  fredette 	    (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
    169   1.1  fredette 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    170   1.1  fredette 
    171   1.1  fredette 	/*
    172   1.1  fredette 	 * Allocate space for the signal handler context.
    173   1.1  fredette 	 * The PA-RISC calling convention mandates that
    174   1.1  fredette 	 * the stack pointer must always be 64-byte aligned,
    175   1.1  fredette 	 * and points to the first *unused* byte.
    176   1.1  fredette 	 */
    177   1.1  fredette 	fsize = sizeof(struct sigframe);
    178   1.1  fredette 	sp = (onstack ?
    179   1.1  fredette 	      (caddr_t)p->p_sigctx.ps_sigstk.ss_sp :
    180   1.1  fredette 	      (caddr_t)tf->tf_sp);
    181   1.1  fredette 	sp = (caddr_t)(((u_int)(sp + fsize + 63)) & ~63);
    182   1.1  fredette 	fp = (struct sigframe *) (sp - fsize);
    183   1.1  fredette 
    184   1.1  fredette #ifdef DEBUG
    185   1.1  fredette 	if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
    186   1.1  fredette 		printf("sendsig: %s[%d] sig %d catcher %p\n",
    187   1.1  fredette 		    p->p_comm, p->p_pid, sig, catcher);
    188   1.1  fredette #endif
    189   1.1  fredette 
    190   1.1  fredette 	/*
    191   1.1  fredette 	 * Save necessary hardware state.  Currently this includes:
    192   1.1  fredette 	 *      - original exception frame
    193   1.1  fredette 	 *      - FP coprocessor state
    194   1.1  fredette 	 */
    195   1.1  fredette 	kf.sf_state.ss_flags = SS_USERREGS;
    196   1.1  fredette 	memcpy(&kf.sf_state.ss_frame, tf, sizeof(*tf));
    197   1.1  fredette 	/* XXX FP state */
    198   1.1  fredette 
    199   1.1  fredette 	/* Build the signal context to be used by sigreturn. */
    200   1.1  fredette 	kf.sf_sc.sc_sp = tf->tf_sp;
    201   1.1  fredette 	kf.sf_sc.sc_fp = tf->tf_sp;	/* XXX fredette - is this right? */
    202   1.1  fredette 	kf.sf_sc.sc_ap = (int)&fp->sf_state;
    203   1.1  fredette 	kf.sf_sc.sc_pcsqh = tf->tf_iisq_head;
    204   1.1  fredette 	kf.sf_sc.sc_pcoqh = tf->tf_iioq_head;
    205   1.1  fredette 	kf.sf_sc.sc_pcsqt = tf->tf_iisq_tail;
    206   1.1  fredette 	kf.sf_sc.sc_pcoqt = tf->tf_iioq_tail;
    207   1.1  fredette 	kf.sf_sc.sc_ps = tf->tf_ipsw;
    208   1.1  fredette 
    209   1.1  fredette 	/* Save signal stack. */
    210   1.1  fredette 	kf.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
    211   1.1  fredette 
    212   1.1  fredette 	/* Save signal mask. */
    213   1.1  fredette 	kf.sf_sc.sc_mask = *mask;
    214   1.1  fredette 
    215   1.1  fredette 	/* Fill the calling convention part of the signal frame. */
    216   1.1  fredette 	kf.sf_psp = 0;
    217   1.1  fredette 	kf.sf_clup = 0;		/* XXX fredette - is this right? */
    218   1.1  fredette 	kf.sf_sl = 0;		/* XXX fredette - is this right? */
    219   1.1  fredette 	kf.sf_edp = 0;		/* XXX fredette - is this right? */
    220   1.1  fredette 
    221   1.1  fredette 	/* Copy out the signal frame. */
    222   1.1  fredette 	if (copyout(&kf, fp, fsize)) {
    223   1.1  fredette #ifdef DEBUG
    224   1.1  fredette 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
    225   1.1  fredette 			printf("sendsig(%d): copyout failed on sig %d\n",
    226   1.1  fredette 			       p->p_pid, sig);
    227   1.1  fredette #endif
    228   1.1  fredette 		/*
    229   1.1  fredette 		 * Process has trashed its stack; give it an illegal
    230   1.1  fredette 		 * instruction to halt it in its tracks.
    231   1.1  fredette 		 */
    232   1.5       chs 		sigexit(l, SIGILL);
    233   1.1  fredette 		/* NOTREACHED */
    234   1.1  fredette 	}
    235   1.1  fredette #ifdef DEBUG
    236   1.1  fredette 	if (sigdebug & SDB_FOLLOW)
    237   1.1  fredette 		printf("sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n",
    238   1.1  fredette 		       p->p_pid, sig, &fp->sf_sc, fp,
    239   1.1  fredette 		       kf.sf_sc.sc_sp, kf.sf_sc.sc_ap);
    240   1.1  fredette #endif
    241   1.1  fredette 
    242   1.1  fredette 	/* Set up the registers to return to sigcode. */
    243   1.2   thorpej 	switch (ps->sa_sigdesc[sig].sd_vers) {
    244   1.2   thorpej #if 1 /* COMPAT_16 */
    245   1.2   thorpej 	case 0:		/* legacy on-stack sigtramp */
    246   1.2   thorpej 		tf->tf_iioq_head =
    247   1.2   thorpej 		    (int)p->p_sigctx.ps_sigcode | HPPA_PC_PRIV_USER;
    248   1.2   thorpej 		tf->tf_iioq_tail = tf->tf_iioq_head + 4;
    249   1.2   thorpej 		break;
    250   1.2   thorpej #endif
    251   1.2   thorpej 
    252   1.2   thorpej 	case 1:
    253   1.2   thorpej 		tf->tf_iioq_head =
    254   1.2   thorpej 		    (int)ps->sa_sigdesc[sig].sd_tramp | HPPA_PC_PRIV_USER;
    255   1.2   thorpej 		tf->tf_iioq_tail = tf->tf_iioq_head + 4;
    256   1.2   thorpej 		break;
    257   1.2   thorpej 
    258   1.2   thorpej 	default:
    259   1.2   thorpej 		/* Don't know what trampoline version; kill it. */
    260   1.5       chs 		sigexit(l, SIGILL);
    261   1.2   thorpej 	}
    262   1.2   thorpej 
    263   1.1  fredette 	tf->tf_sp = (int)sp;
    264   1.1  fredette 	tf->tf_r3 = (int)&fp->sf_sc;
    265   1.1  fredette 	tf->tf_arg0 = sig;
    266   1.1  fredette 	tf->tf_arg1 = code;
    267   1.1  fredette 	tf->tf_arg2 = (int)&fp->sf_sc;
    268   1.1  fredette 	tf->tf_arg3 = (int)catcher;
    269   1.2   thorpej 
    270   1.1  fredette 	/* Remember that we're now on the signal stack. */
    271   1.1  fredette 	if (onstack)
    272   1.1  fredette 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
    273   1.1  fredette 
    274   1.1  fredette #ifdef DEBUG
    275   1.1  fredette 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
    276   1.1  fredette 		printf("sendsig(%d): sig %d returns\n",
    277   1.1  fredette 		       p->p_pid, sig);
    278   1.1  fredette #endif
    279   1.1  fredette }
    280   1.1  fredette 
    281  1.10       chs void *getframe(struct lwp *, int, int *);
    282  1.10       chs void sendsig_siginfo(const struct ksiginfo *, const sigset_t *);
    283  1.10       chs 
    284  1.10       chs void *
    285  1.10       chs getframe(struct lwp *l, int sig, int *onstack)
    286  1.10       chs {
    287  1.10       chs 	struct proc *p = l->l_proc;
    288  1.10       chs 	struct sigctx *ctx = &p->p_sigctx;
    289  1.10       chs 	struct trapframe *tf = l->l_md.md_regs;
    290  1.10       chs 
    291  1.10       chs 	/* Do we need to jump onto the signal stack? */
    292  1.10       chs 	*onstack = (ctx->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
    293  1.10       chs 	    && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
    294  1.10       chs 	if (*onstack)
    295  1.10       chs 		return (void *)ctx->ps_sigstk.ss_sp;
    296  1.10       chs 	else
    297  1.10       chs 		return (void *)tf->tf_sp;
    298  1.10       chs }
    299  1.10       chs 
    300  1.10       chs struct sigframe_siginfo {
    301  1.10       chs 	siginfo_t sf_si;
    302  1.10       chs 	ucontext_t sf_uc;
    303  1.10       chs };
    304  1.10       chs 
    305  1.10       chs void
    306  1.10       chs sendsig_siginfo(const struct ksiginfo *ksi, const sigset_t *mask)
    307  1.10       chs {
    308  1.10       chs 	struct lwp *l = curlwp;
    309  1.10       chs 	struct proc *p = l->l_proc;
    310  1.10       chs 	struct sigacts *ps = p->p_sigacts;
    311  1.10       chs 	struct sigframe_siginfo *fp, frame;
    312  1.10       chs 	struct trapframe *tf;
    313  1.10       chs 	int sig = ksi->ksi_signo;
    314  1.10       chs 	sig_t catcher = SIGACTION(p, sig).sa_handler;
    315  1.10       chs 	int onstack;
    316  1.10       chs 
    317  1.10       chs 	fp = getframe(l, sig, &onstack);
    318  1.10       chs 	tf = (struct trapframe *)l->l_md.md_regs;
    319  1.10       chs 
    320  1.10       chs 	/* Build stack frame for signal trampoline. */
    321  1.10       chs 	switch (ps->sa_sigdesc[sig].sd_vers) {
    322  1.10       chs 	default:
    323  1.10       chs 		printf("sendsig_siginfo: bad version %d\n",
    324  1.10       chs 		       ps->sa_sigdesc[sig].sd_vers);
    325  1.10       chs 		sigexit(l, SIGILL);
    326  1.10       chs 	case 2:
    327  1.10       chs 		break;
    328  1.10       chs 	}
    329  1.10       chs 
    330  1.10       chs 	frame.sf_uc.uc_flags = _UC_SIGMASK |
    331  1.10       chs 		((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) ?
    332  1.10       chs 		 _UC_SETSTACK : _UC_CLRSTACK);
    333  1.10       chs 	frame.sf_uc.uc_sigmask = *mask;
    334  1.10       chs 	frame.sf_uc.uc_link = NULL;
    335  1.10       chs 	memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
    336  1.10       chs 	cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
    337  1.10       chs 
    338  1.10       chs 	if (copyout(&frame, fp, sizeof(frame)) != 0) {
    339  1.10       chs 
    340  1.10       chs 		/*
    341  1.10       chs 		 * Process has trashed its stack; give it an illegal
    342  1.10       chs 		 * instruction to halt it in its tracks.
    343  1.10       chs 		 */
    344  1.10       chs 		sigexit(l, SIGILL);
    345  1.10       chs 		/* NOTREACHED */
    346  1.10       chs 	}
    347  1.10       chs 
    348  1.10       chs 	/*
    349  1.10       chs 	 * Set up the registers to invoke the signal trampoline.
    350  1.10       chs 	 */
    351  1.10       chs 	tf->tf_arg0 = sig;
    352  1.10       chs 	tf->tf_arg1 = (__greg_t)&fp->sf_si;
    353  1.10       chs 	tf->tf_arg2 = (__greg_t)&fp->sf_uc;
    354  1.10       chs 	tf->tf_r3 = (__greg_t)&fp->sf_uc;
    355  1.10       chs 
    356  1.10       chs 	tf->tf_iioq_head =
    357  1.10       chs 		(__greg_t)ps->sa_sigdesc[sig].sd_tramp | HPPA_PC_PRIV_USER;
    358  1.10       chs 	tf->tf_iioq_tail = tf->tf_iioq_head + 4;
    359  1.10       chs 	tf->tf_arg3 = (__greg_t)catcher;
    360  1.10       chs 	tf->tf_sp = HPPA_FRAME_ROUND((uintptr_t)fp + sizeof(*fp) +
    361  1.10       chs 				     HPPA_FRAME_SIZE);
    362  1.10       chs 
    363  1.10       chs 	/* Remember that we're now on the signal stack. */
    364  1.10       chs 	if (onstack)
    365  1.10       chs 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
    366  1.10       chs }
    367  1.10       chs 
    368  1.10       chs void
    369  1.10       chs sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
    370  1.10       chs {
    371  1.10       chs 	if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
    372  1.10       chs 		sendsig_sigcontext(ksi, mask);
    373  1.10       chs 	else
    374  1.10       chs 		sendsig_siginfo(ksi, mask);
    375  1.10       chs }
    376  1.10       chs 
    377   1.1  fredette int
    378   1.8  drochner compat_16_sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
    379   1.1  fredette {
    380   1.8  drochner 	struct compat_16_sys___sigreturn14_args /* {
    381   1.1  fredette 		syscallarg(struct sigcontext *) sigcntxp;
    382   1.1  fredette 	} */ *uap = v;
    383   1.5       chs 	struct proc *p = l->l_proc;
    384   1.1  fredette 	struct sigcontext *scp;
    385   1.1  fredette 	struct trapframe *tf;
    386   1.1  fredette 	struct sigcontext tsigc;
    387   1.1  fredette 	struct sigstate tstate;
    388   1.1  fredette 	int rf, flags;
    389   1.1  fredette 
    390   1.1  fredette 	/*
    391   1.1  fredette 	 * The trampoline code hands us the context.
    392   1.1  fredette 	 * It is unsafe to keep track of it ourselves, in the event that a
    393   1.1  fredette 	 * program jumps out of a signal handler.
    394   1.1  fredette 	 */
    395   1.1  fredette 	scp = SCARG(uap, sigcntxp);
    396   1.1  fredette #ifdef DEBUG
    397   1.1  fredette 	if (sigdebug & SDB_FOLLOW)
    398   1.1  fredette 		printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
    399   1.1  fredette #endif
    400   1.1  fredette 	if ((int)scp & 3)
    401   1.1  fredette 		return (EINVAL);
    402   1.1  fredette 
    403   1.1  fredette 	if (copyin(scp, &tsigc, sizeof(tsigc)) != 0)
    404   1.1  fredette 		return (EFAULT);
    405   1.1  fredette 	scp = &tsigc;
    406   1.1  fredette 
    407   1.1  fredette 	/* Make sure the user isn't pulling a fast one on us! */
    408   1.1  fredette 	/* XXX fredette - until this is done, huge security hole here. */
    409   1.1  fredette 	/* XXX fredette - requiring that PSL_R be zero will hurt debuggers. */
    410   1.1  fredette 	if ((scp->sc_ps & (PSW_MBS|PSW_MBZ)) != PSW_MBS)
    411   1.1  fredette 		return (EINVAL);
    412   1.1  fredette 
    413   1.1  fredette 	/* Restore register context. */
    414   1.5       chs 	tf = (struct trapframe *)l->l_md.md_regs;
    415   1.1  fredette 
    416   1.1  fredette 	/*
    417   1.1  fredette 	 * Grab pointer to hardware state information.
    418   1.1  fredette 	 * If zero, the user is probably doing a longjmp.
    419   1.1  fredette 	 */
    420   1.1  fredette 	if ((rf = scp->sc_ap) == 0)
    421   1.1  fredette 		goto restore;
    422   1.1  fredette 
    423   1.1  fredette 	/*
    424   1.1  fredette 	 * See if there is anything to do before we go to the
    425   1.1  fredette 	 * expense of copying in the trapframe
    426   1.1  fredette 	 */
    427   1.1  fredette 	flags = fuword((caddr_t)rf);
    428   1.1  fredette #ifdef DEBUG
    429   1.1  fredette 	if (sigdebug & SDB_FOLLOW)
    430   1.1  fredette 		printf("sigreturn(%d): sc_ap %x flags %x\n",
    431   1.1  fredette 		       p->p_pid, rf, flags);
    432   1.1  fredette #endif
    433   1.1  fredette 	/* fuword failed (bogus sc_ap value). */
    434   1.1  fredette 	if (flags == -1)
    435   1.1  fredette 		return (EINVAL);
    436   1.1  fredette 
    437   1.1  fredette 	if (flags == 0 || copyin((caddr_t)rf, &tstate, sizeof(tstate)) != 0)
    438   1.1  fredette 		goto restore;
    439   1.1  fredette #ifdef DEBUG
    440   1.1  fredette 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
    441   1.1  fredette 		printf("sigreturn(%d): ssp %p usp %x scp %p\n",
    442   1.1  fredette 		       p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp));
    443   1.1  fredette #endif
    444   1.1  fredette 
    445   1.1  fredette 	/*
    446   1.1  fredette 	 * Restore most of the users registers except for those
    447   1.1  fredette 	 * in the sigcontext; they will be handled below.
    448   1.1  fredette 	 */
    449   1.1  fredette 	if (flags & SS_USERREGS) {
    450   1.1  fredette 
    451   1.1  fredette 		/*
    452   1.1  fredette 		 * There are more registers that the user can tell
    453   1.1  fredette 		 * us to bash than registers that, for security
    454   1.1  fredette 		 * or other reasons, we must protect.  So it's
    455   1.1  fredette 		 * easier (but not faster), to copy these sensitive
    456   1.1  fredette 		 * register values into the user-provided frame,
    457   1.1  fredette 		 * then bulk-copy the user-provided frame into
    458   1.1  fredette 		 * the process' frame.
    459   1.1  fredette 		 */
    460   1.1  fredette #define	SIG_PROTECT(r) tstate.ss_frame.r = tf->r
    461   1.1  fredette 		/* SRs 5,6,7 must be protected. */
    462   1.1  fredette 		SIG_PROTECT(tf_sr5);
    463   1.1  fredette 		SIG_PROTECT(tf_sr6);
    464   1.1  fredette 		SIG_PROTECT(tf_sr7);
    465   1.1  fredette 
    466   1.1  fredette 		/* all CRs except CR11 must be protected. */
    467   1.1  fredette 		SIG_PROTECT(tf_rctr);	/* CR0 */
    468   1.1  fredette 		/* CRs 1-8 are reserved */
    469   1.1  fredette 		SIG_PROTECT(tf_pidr1);	/* CR8 */
    470   1.1  fredette 		SIG_PROTECT(tf_pidr2);	/* CR9 */
    471   1.1  fredette 		SIG_PROTECT(tf_ccr);	/* CR10 */
    472   1.1  fredette 		SIG_PROTECT(tf_pidr3);	/* CR12 */
    473   1.1  fredette 		SIG_PROTECT(tf_pidr4);	/* CR14 */
    474   1.1  fredette 		SIG_PROTECT(tf_eiem);	/* CR15 */
    475   1.1  fredette 		/* CR17 is the IISQ head */
    476   1.1  fredette 		/* CR18 is the IIOQ head */
    477   1.1  fredette 		SIG_PROTECT(tf_iir);	/* CR19 */
    478   1.1  fredette 		SIG_PROTECT(tf_isr);	/* CR20 */
    479   1.1  fredette 		SIG_PROTECT(tf_ior);	/* CR21 */
    480   1.1  fredette 		/* CR22 is the IPSW */
    481   1.1  fredette 		SIG_PROTECT(tf_eirr);	/* CR23 */
    482   1.1  fredette 		SIG_PROTECT(tf_hptm);	/* CR24 */
    483   1.1  fredette 		SIG_PROTECT(tf_vtop);	/* CR25 */
    484   1.1  fredette 		/* XXX where are CR26, CR27, CR29, CR31? */
    485   1.1  fredette 		SIG_PROTECT(tf_cr28);	/* CR28 */
    486   1.1  fredette 		SIG_PROTECT(tf_cr30);	/* CR30 */
    487   1.1  fredette #undef	SIG_PROTECT
    488   1.1  fredette 
    489   1.1  fredette 		/* The bulk copy. */
    490   1.1  fredette 		*tf = tstate.ss_frame;
    491   1.1  fredette 	}
    492   1.1  fredette 
    493   1.1  fredette 	/*
    494   1.1  fredette 	 * Restore the original FP context
    495   1.1  fredette 	 */
    496   1.1  fredette 	/* XXX fredette */
    497   1.1  fredette 
    498   1.1  fredette  restore:
    499   1.1  fredette 	/*
    500   1.1  fredette 	 * Restore the user supplied information.
    501   1.1  fredette 	 * This should be at the last so that the error (EINVAL)
    502   1.1  fredette 	 * is reported to the sigreturn caller, not to the
    503   1.1  fredette 	 * jump destination.
    504   1.1  fredette 	 */
    505   1.1  fredette 
    506   1.1  fredette 	tf->tf_sp = scp->sc_sp;
    507   1.1  fredette 	/* XXX should we be doing the space registers? */
    508   1.1  fredette 	tf->tf_iisq_head = scp->sc_pcsqh;
    509   1.1  fredette 	tf->tf_iioq_head = scp->sc_pcoqh | HPPA_PC_PRIV_USER;
    510   1.1  fredette 	tf->tf_iisq_tail = scp->sc_pcsqt;
    511   1.1  fredette 	tf->tf_iioq_tail = scp->sc_pcoqt | HPPA_PC_PRIV_USER;
    512   1.1  fredette 	tf->tf_ipsw = scp->sc_ps;
    513   1.1  fredette 
    514   1.1  fredette 	/* Restore signal stack. */
    515   1.1  fredette 	if (scp->sc_onstack & SS_ONSTACK)
    516   1.1  fredette 		p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
    517   1.1  fredette 	else
    518   1.1  fredette 		p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
    519   1.1  fredette 
    520   1.1  fredette 	/* Restore signal mask. */
    521   1.1  fredette 	(void) sigprocmask1(p, SIG_SETMASK, &scp->sc_mask, 0);
    522   1.1  fredette 
    523   1.1  fredette #ifdef DEBUG
    524   1.1  fredette #if 0 /* XXX FP state */
    525   1.1  fredette 	if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
    526   1.1  fredette 		printf("sigreturn(%d): copied in FP state (%x) at %p\n",
    527   1.1  fredette 		       p->p_pid, *(u_int *)&tstate.ss_fpstate,
    528   1.1  fredette 		       &tstate.ss_fpstate);
    529   1.1  fredette #endif
    530   1.1  fredette 	if ((sigdebug & SDB_FOLLOW) ||
    531   1.1  fredette 	    ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
    532   1.1  fredette 		printf("sigreturn(%d): returns\n", p->p_pid);
    533   1.1  fredette #endif
    534   1.1  fredette 	return (EJUSTRETURN);
    535   1.1  fredette }
    536   1.1  fredette 
    537