1 /* $NetBSD: sunos_machdep.c,v 1.37 2009/11/23 00:11:44 rmind Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer 9 * Science Department. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * from: Utah $Hdr: machdep.c 1.63 91/04/24$ 36 * 37 * @(#)machdep.c 7.16 (Berkeley) 6/3/91 38 */ 39 /* 40 * Copyright (c) 1988 University of Utah. 41 * 42 * This code is derived from software contributed to Berkeley by 43 * the Systems Programming Group of the University of Utah Computer 44 * Science Department. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by the University of 57 * California, Berkeley and its contributors. 58 * 4. Neither the name of the University nor the names of its contributors 59 * may be used to endorse or promote products derived from this software 60 * without specific prior written permission. 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 72 * SUCH DAMAGE. 73 * 74 * from: Utah $Hdr: machdep.c 1.63 91/04/24$ 75 * 76 * @(#)machdep.c 7.16 (Berkeley) 6/3/91 77 */ 78 79 #include <sys/cdefs.h> 80 __KERNEL_RCSID(0, "$NetBSD: sunos_machdep.c,v 1.37 2009/11/23 00:11:44 rmind Exp $"); 81 82 #include <sys/param.h> 83 #include <sys/systm.h> 84 #include <sys/namei.h> 85 #include <sys/proc.h> 86 #include <sys/filedesc.h> 87 #include <sys/ioctl.h> 88 #include <sys/mount.h> 89 #include <sys/kernel.h> 90 #include <sys/signal.h> 91 #include <sys/signalvar.h> 92 #include <sys/malloc.h> 93 #include <sys/buf.h> 94 95 #include <sys/syscallargs.h> 96 #include <compat/sunos/sunos.h> 97 #include <compat/sunos/sunos_syscallargs.h> 98 #include <compat/sys/signal.h> 99 #include <compat/sys/signalvar.h> 100 101 #include <machine/reg.h> 102 103 #ifdef DEBUG 104 extern int sigdebug; 105 extern int sigpid; 106 #define SDB_FOLLOW 0x01 107 #define SDB_KSTACK 0x02 108 #define SDB_FPSTATE 0x04 109 #endif 110 111 /* sigh.. I guess it's too late to change now, but "our" sigcontext 112 is plain vax, not very 68000 (ap, for example..) */ 113 struct sunos_sigcontext { 114 int sc_onstack; /* sigstack state to restore */ 115 int sc_mask; /* signal mask to restore */ 116 int sc_sp; /* sp to restore */ 117 int sc_pc; /* pc to restore */ 118 int sc_ps; /* psl to restore */ 119 }; 120 struct sunos_sigframe { 121 int sf_signum; /* signo for handler */ 122 int sf_code; /* additional info for handler */ 123 struct sunos_sigcontext *sf_scp;/* context pointer for handler */ 124 u_int sf_addr; /* even more info for handler */ 125 struct sunos_sigcontext sf_sc; /* I don't know if that's what 126 comes here */ 127 }; 128 /* 129 * much simpler sendsig() for SunOS processes, as SunOS does the whole 130 * context-saving in usermode. For now, no hardware information (ie. 131 * frames for buserror etc) is saved. This could be fatal, so I take 132 * SIG_DFL for "dangerous" signals. 133 */ 134 void 135 sunos_sendsig(const ksiginfo_t *ksi, const sigset_t *mask) 136 { 137 u_long code = KSI_TRAPCODE(ksi); 138 int sig = ksi->ksi_signo; 139 struct lwp *l = curlwp; 140 struct proc *p = l->l_proc; 141 struct frame *frame = (struct frame *)l->l_md.md_regs; 142 int onstack, error; 143 struct sunos_sigframe *fp = getframe(l, sig, &onstack), kf; 144 sig_t catcher = SIGACTION(p, sig).sa_handler; 145 short ft = frame->f_format; 146 147 /* 148 * if this is a hardware fault (ft >= FMT9), sunos_sendsig 149 * can't currently handle it. Reset signal actions and 150 * have the process die unconditionally. 151 */ 152 if (ft >= FMT9) { 153 SIGACTION(p, sig).sa_handler = SIG_DFL; 154 sigdelset(&p->p_sigctx.ps_sigignore, sig); 155 sigdelset(&p->p_sigctx.ps_sigcatch, sig); 156 sigdelset(&l->l_sigmask, sig); 157 mutex_exit(p->p_lock); 158 psignal(p, sig); 159 mutex_enter(p->p_lock); 160 return; 161 } 162 163 fp--; 164 165 #ifdef DEBUG 166 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 167 printf("sunos_sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n", 168 p->p_pid, sig, &onstack, fp, &fp->sf_sc, ft); 169 #endif 170 171 /* Build stack frame for signal trampoline. */ 172 kf.sf_signum = sig; 173 kf.sf_code = code; 174 kf.sf_scp = &fp->sf_sc; 175 kf.sf_addr = ~0; /* means: not computable */ 176 177 /* Build the signal context to be used by sigreturn. */ 178 kf.sf_sc.sc_sp = frame->f_regs[SP]; 179 kf.sf_sc.sc_pc = frame->f_pc; 180 kf.sf_sc.sc_ps = frame->f_sr; 181 182 /* Save signal stack. */ 183 kf.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK; 184 185 /* Save signal mask. */ 186 native_sigset_to_sigset13(mask, &kf.sf_sc.sc_mask); 187 188 sendsig_reset(l, sig); 189 mutex_exit(p->p_lock); 190 error = copyout(&kf, fp, sizeof(kf)); 191 mutex_enter(p->p_lock); 192 193 if (error != 0) { 194 #ifdef DEBUG 195 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 196 printf("sendsig(%d): copyout failed on sig %d\n", 197 p->p_pid, sig); 198 #endif 199 /* 200 * Process has trashed its stack; give it an illegal 201 * instruction to halt it in its tracks. 202 */ 203 sigexit(l, SIGILL); 204 /* NOTREACHED */ 205 } 206 #ifdef DEBUG 207 if (sigdebug & SDB_FOLLOW) 208 printf("sunos_sendsig(%d): sig %d scp %p sc_sp %x\n", 209 p->p_pid, sig, &fp->sf_sc,kf.sf_sc.sc_sp); 210 #endif 211 212 buildcontext(l, catcher, fp); 213 214 /* Remember that we're now on the signal stack. */ 215 if (onstack) 216 l->l_sigstk.ss_flags |= SS_ONSTACK; 217 218 #ifdef DEBUG 219 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 220 printf("sunos_sendsig(%d): sig %d returns\n", 221 p->p_pid, sig); 222 #endif 223 } 224 225 226 /* 227 * System call to cleanup state after a signal 228 * has been taken. Reset signal mask and 229 * stack state from context left by sendsig (above). 230 * Return to previous pc and psl as specified by 231 * context left by sendsig. Check carefully to 232 * make sure that the user has not modified the 233 * psl to gain improper privileges or to cause 234 * a machine fault. 235 */ 236 int 237 sunos_sys_sigreturn(struct lwp *l, const struct sunos_sys_sigreturn_args *uap, register_t *retval) 238 { 239 struct proc *p = l->l_proc; 240 struct sunos_sigcontext *scp; 241 struct frame *frame; 242 struct sunos_sigcontext tsigc; 243 sigset_t mask; 244 245 scp = (struct sunos_sigcontext *) SCARG(uap, sigcntxp); 246 #ifdef DEBUG 247 if (sigdebug & SDB_FOLLOW) 248 printf("sunos_sigreturn: pid %d, scp %p\n", p->p_pid, scp); 249 #endif 250 if ((int)scp & 1) 251 return EINVAL; 252 if (copyin((void *)scp, (void *)&tsigc, sizeof(tsigc)) != 0) 253 return EFAULT; 254 scp = &tsigc; 255 256 /* Make sure the user isn't pulling a fast one on us! */ 257 if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0) 258 return EINVAL; 259 260 /* 261 * Restore the user supplied information 262 */ 263 264 frame = (struct frame *) l->l_md.md_regs; 265 frame->f_regs[SP] = scp->sc_sp; 266 frame->f_pc = scp->sc_pc; 267 frame->f_sr = scp->sc_ps; 268 269 mutex_enter(p->p_lock); 270 271 /* Restore signal stack. */ 272 if (scp->sc_onstack & SS_ONSTACK) 273 l->l_sigstk.ss_flags |= SS_ONSTACK; 274 else 275 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 276 277 /* Restore signal mask. */ 278 native_sigset13_to_sigset(&scp->sc_mask, &mask); 279 (void)sigprocmask1(l, SIG_SETMASK, &mask, 0); 280 281 mutex_exit(p->p_lock); 282 283 return EJUSTRETURN; 284 } 285