1 /* $NetBSD: netbsd32_signal.c,v 1.7 2003/10/13 18:55:30 fvdl Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2001 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.7 2003/10/13 18:55:30 fvdl Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/malloc.h> 37 #include <sys/mount.h> 38 #include <sys/stat.h> 39 #include <sys/time.h> 40 #include <sys/signalvar.h> 41 #include <sys/proc.h> 42 #include <sys/wait.h> 43 44 #include <uvm/uvm_extern.h> 45 46 #include <compat/netbsd32/netbsd32.h> 47 #include <compat/netbsd32/netbsd32_syscallargs.h> 48 49 int 50 netbsd32_sigaction(l, v, retval) 51 struct lwp *l; 52 void *v; 53 register_t *retval; 54 { 55 struct netbsd32_sigaction_args /* { 56 syscallarg(int) signum; 57 syscallarg(const netbsd32_sigactionp_t) nsa; 58 syscallarg(netbsd32_sigactionp_t) osa; 59 } */ *uap = v; 60 struct sigaction nsa, osa; 61 struct netbsd32_sigaction *sa32p, sa32; 62 int error; 63 64 if (SCARG(uap, nsa)) { 65 sa32p = 66 (struct netbsd32_sigaction *)NETBSD32PTR64(SCARG(uap, nsa)); 67 if (copyin(sa32p, &sa32, sizeof(sa32))) 68 return EFAULT; 69 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 70 nsa.sa_mask = sa32.netbsd32_sa_mask; 71 nsa.sa_flags = sa32.netbsd32_sa_flags; 72 } 73 error = sigaction1(l->l_proc, SCARG(uap, signum), 74 SCARG(uap, nsa) ? &nsa : 0, 75 SCARG(uap, osa) ? &osa : 0, 76 NULL, 0); 77 78 if (error) 79 return (error); 80 81 if (SCARG(uap, osa)) { 82 sa32.netbsd32_sa_handler = (netbsd32_sigactionp_t)(u_long)osa.sa_handler; 83 sa32.netbsd32_sa_mask = osa.sa_mask; 84 sa32.netbsd32_sa_flags = osa.sa_flags; 85 sa32p = 86 (struct netbsd32_sigaction *)NETBSD32PTR64(SCARG(uap, osa)); 87 if (copyout(&sa32, sa32p, sizeof(sa32))) 88 return EFAULT; 89 } 90 91 return (0); 92 } 93 94 int 95 netbsd32___sigaltstack14(l, v, retval) 96 struct lwp *l; 97 void *v; 98 register_t *retval; 99 { 100 struct netbsd32___sigaltstack14_args /* { 101 syscallarg(const netbsd32_sigaltstackp_t) nss; 102 syscallarg(netbsd32_sigaltstackp_t) oss; 103 } */ *uap = v; 104 struct netbsd32_sigaltstack s32; 105 struct sigaltstack nss, oss; 106 int error; 107 108 if (SCARG(uap, nss)) { 109 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nss)), &s32, 110 sizeof(s32)); 111 if (error) 112 return (error); 113 nss.ss_sp = (void *)NETBSD32PTR64(s32.ss_sp); 114 nss.ss_size = (size_t)s32.ss_size; 115 nss.ss_flags = s32.ss_flags; 116 } 117 error = sigaltstack1(l->l_proc, 118 SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0); 119 if (error) 120 return (error); 121 if (SCARG(uap, oss)) { 122 s32.ss_sp = (netbsd32_voidp)(u_long)oss.ss_sp; 123 s32.ss_size = (netbsd32_size_t)oss.ss_size; 124 s32.ss_flags = oss.ss_flags; 125 error = copyout(&s32, (caddr_t)NETBSD32PTR64(SCARG(uap, oss)), 126 sizeof(s32)); 127 if (error) 128 return (error); 129 } 130 return (0); 131 } 132 133 /* ARGSUSED */ 134 int 135 netbsd32___sigaction14(l, v, retval) 136 struct lwp *l; 137 void *v; 138 register_t *retval; 139 { 140 struct netbsd32___sigaction14_args /* { 141 syscallarg(int) signum; 142 syscallarg(const struct sigaction *) nsa; 143 syscallarg(struct sigaction *) osa; 144 } */ *uap = v; 145 struct netbsd32_sigaction sa32; 146 struct sigaction nsa, osa; 147 int error; 148 149 if (SCARG(uap, nsa)) { 150 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsa)), &sa32, 151 sizeof(sa32)); 152 if (error) 153 return (error); 154 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 155 nsa.sa_mask = sa32.netbsd32_sa_mask; 156 nsa.sa_flags = sa32.netbsd32_sa_flags; 157 } 158 error = sigaction1(l->l_proc, SCARG(uap, signum), 159 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0, 160 NULL, 0); 161 if (error) 162 return (error); 163 if (SCARG(uap, osa)) { 164 sa32.netbsd32_sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler; 165 sa32.netbsd32_sa_mask = osa.sa_mask; 166 sa32.netbsd32_sa_flags = osa.sa_flags; 167 error = copyout(&sa32, (caddr_t)NETBSD32PTR64(SCARG(uap, osa)), 168 sizeof(sa32)); 169 if (error) 170 return (error); 171 } 172 return (0); 173 } 174 175 /* ARGSUSED */ 176 int 177 netbsd32___sigaction_sigtramp(l, v, retval) 178 struct lwp *l; 179 void *v; 180 register_t *retval; 181 { 182 struct netbsd32___sigaction_sigtramp_args /* { 183 syscallarg(int) signum; 184 syscallarg(const netbsd32_sigactionp_t) nsa; 185 syscallarg(netbsd32_sigactionp_t) osa; 186 syscallarg(netbsd32_voidp) tramp; 187 syscallarg(int) vers; 188 } */ *uap = v; 189 struct proc *p = l->l_proc; 190 struct netbsd32_sigaction sa32; 191 struct sigaction nsa, osa; 192 int error; 193 194 if (SCARG(uap, nsa)) { 195 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsa)), &sa32, 196 sizeof(sa32)); 197 if (error) 198 return (error); 199 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 200 nsa.sa_mask = sa32.netbsd32_sa_mask; 201 nsa.sa_flags = sa32.netbsd32_sa_flags; 202 } 203 error = sigaction1(p, SCARG(uap, signum), 204 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0, 205 NETBSD32PTR64(SCARG(uap, tramp)), SCARG(uap, vers)); 206 if (error) 207 return (error); 208 if (SCARG(uap, osa)) { 209 sa32.netbsd32_sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler; 210 sa32.netbsd32_sa_mask = osa.sa_mask; 211 sa32.netbsd32_sa_flags = osa.sa_flags; 212 error = copyout(&sa32, (caddr_t)NETBSD32PTR64(SCARG(uap, osa)), 213 sizeof(sa32)); 214 if (error) 215 return (error); 216 } 217 return (0); 218 } 219 220 void 221 netbsd32_si32_to_si(siginfo_t *si, siginfo32_t *si32) 222 { 223 memset(si, 0, sizeof (*si)); 224 si->si_signo = si32->si_signo; 225 si->si_code = si32->si_code; 226 si->si_errno = si32->si_errno; 227 228 switch (si32->si_signo) { 229 case SIGILL: 230 case SIGBUS: 231 case SIGSEGV: 232 case SIGFPE: 233 case SIGTRAP: 234 si->si_addr = (void *)NETBSD32PTR64(si32->si_addr); 235 si->si_trap = si32->si_trap; 236 break; 237 case SIGALRM: 238 case SIGVTALRM: 239 case SIGPROF: 240 si->si_pid = si32->si_pid; 241 si->si_uid = si32->si_uid; 242 /* 243 * XXX sival_ptr is currently unused. 244 */ 245 si->si_sigval.sival_int = si32->si_sigval.sival_int; 246 break; 247 case SIGCHLD: 248 si->si_pid = si32->si_pid; 249 si->si_uid = si32->si_uid; 250 si->si_utime = si32->si_utime; 251 si->si_stime = si32->si_stime; 252 break; 253 case SIGURG: 254 case SIGIO: 255 si->si_band = si32->si_band; 256 si->si_fd = si32->si_fd; 257 break; 258 } 259 } 260 261 void 262 netbsd32_si_to_si32(siginfo32_t *si32, siginfo_t *si) 263 { 264 memset(si32, 0, sizeof (*si32)); 265 si32->si_signo = si->si_signo; 266 si32->si_code = si->si_code; 267 si32->si_errno = si->si_errno; 268 269 switch (si32->si_signo) { 270 case SIGILL: 271 case SIGBUS: 272 case SIGSEGV: 273 case SIGFPE: 274 case SIGTRAP: 275 si32->si_addr = (uint32_t)(uintptr_t)si->si_addr; 276 si32->si_trap = si->si_trap; 277 break; 278 case SIGALRM: 279 case SIGVTALRM: 280 case SIGPROF: 281 si32->si_pid = si->si_pid; 282 si32->si_uid = si->si_uid; 283 /* 284 * XXX sival_ptr is currently unused. 285 */ 286 si32->si_sigval.sival_int = si->si_sigval.sival_int; 287 break; 288 case SIGCHLD: 289 si32->si_pid = si->si_pid; 290 si32->si_uid = si->si_uid; 291 si32->si_status = si->si_status; 292 si32->si_utime = si->si_utime; 293 si32->si_stime = si->si_stime; 294 break; 295 case SIGURG: 296 case SIGIO: 297 si32->si_band = si->si_band; 298 si32->si_fd = si->si_fd; 299 break; 300 } 301 } 302 303 void 304 getucontext32(struct lwp *l, ucontext32_t *ucp) 305 { 306 struct proc *p; 307 308 p = l->l_proc; 309 310 ucp->uc_flags = 0; 311 ucp->uc_link = (uint32_t)(intptr_t)l->l_ctxlink; 312 313 (void)sigprocmask1(p, 0, NULL, &ucp->uc_sigmask); 314 ucp->uc_flags |= _UC_SIGMASK; 315 316 /* 317 * The (unsupplied) definition of the `current execution stack' 318 * in the System V Interface Definition appears to allow returning 319 * the main context stack. 320 */ 321 if ((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) == 0) { 322 ucp->uc_stack.ss_sp = USRSTACK32; 323 ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize); 324 ucp->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */ 325 } else { 326 /* Simply copy alternate signal execution stack. */ 327 ucp->uc_stack.ss_sp = 328 (uint32_t)(intptr_t)p->p_sigctx.ps_sigstk.ss_sp; 329 ucp->uc_stack.ss_size = p->p_sigctx.ps_sigstk.ss_size; 330 ucp->uc_stack.ss_flags = p->p_sigctx.ps_sigstk.ss_flags; 331 } 332 ucp->uc_flags |= _UC_STACK; 333 334 cpu_getmcontext32(l, &ucp->uc_mcontext, &ucp->uc_flags); 335 } 336 337 /* ARGSUSED */ 338 int 339 netbsd32_getcontext(struct lwp *l, void *v, register_t *retval) 340 { 341 struct netbsd32_getcontext_args /* { 342 syscallarg(netbsd32_ucontextp) ucp; 343 } */ *uap = v; 344 ucontext32_t uc; 345 346 getucontext32(l, &uc); 347 348 return copyout(&uc, NETBSD32PTR64(SCARG(uap, ucp)), 349 sizeof (ucontext32_t)); 350 } 351 352 int 353 setucontext32(struct lwp *l, const ucontext32_t *ucp) 354 { 355 struct proc *p; 356 int error; 357 358 p = l->l_proc; 359 if ((error = cpu_setmcontext32(l, &ucp->uc_mcontext, 360 ucp->uc_flags)) != 0) 361 return (error); 362 l->l_ctxlink = (void *)(intptr_t)ucp->uc_link; 363 /* 364 * We might want to take care of the stack portion here but currently 365 * don't; see the comment in getucontext(). 366 */ 367 if ((ucp->uc_flags & _UC_SIGMASK) != 0) 368 sigprocmask1(p, SIG_SETMASK, &ucp->uc_sigmask, NULL); 369 370 return 0; 371 } 372 373 /* ARGSUSED */ 374 int 375 netbsd32_setcontext(struct lwp *l, void *v, register_t *retval) 376 { 377 struct netbsd32_setcontext_args /* { 378 syscallarg(netbsd32_ucontextp) ucp; 379 } */ *uap = v; 380 ucontext32_t uc; 381 int error; 382 void *p; 383 384 p = NETBSD32PTR64(SCARG(uap, ucp)); 385 if (p == NULL) 386 exit1(l, W_EXITCODE(0, 0)); 387 else if ((error = copyin(p, &uc, sizeof (uc))) != 0 || 388 (error = setucontext32(l, &uc)) != 0) 389 return (error); 390 391 return (EJUSTRETURN); 392 } 393