1 /* $NetBSD: netbsd32_signal.c,v 1.11 2005/08/19 04:24:38 christos 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.11 2005/08/19 04:24:38 christos 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 #include <sys/dirent.h> 44 45 #include <uvm/uvm_extern.h> 46 47 #include <compat/netbsd32/netbsd32.h> 48 #include <compat/netbsd32/netbsd32_conv.h> 49 #include <compat/netbsd32/netbsd32_syscallargs.h> 50 51 int 52 netbsd32_sigaction(l, v, retval) 53 struct lwp *l; 54 void *v; 55 register_t *retval; 56 { 57 struct netbsd32_sigaction_args /* { 58 syscallarg(int) signum; 59 syscallarg(const netbsd32_sigactionp_t) nsa; 60 syscallarg(netbsd32_sigactionp_t) osa; 61 } */ *uap = v; 62 struct sigaction nsa, osa; 63 struct netbsd32_sigaction *sa32p, sa32; 64 int error; 65 66 if (SCARG(uap, nsa)) { 67 sa32p = 68 (struct netbsd32_sigaction *)NETBSD32PTR64(SCARG(uap, nsa)); 69 if (copyin(sa32p, &sa32, sizeof(sa32))) 70 return EFAULT; 71 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 72 nsa.sa_mask = sa32.netbsd32_sa_mask; 73 nsa.sa_flags = sa32.netbsd32_sa_flags; 74 } 75 error = sigaction1(l->l_proc, SCARG(uap, signum), 76 SCARG(uap, nsa) ? &nsa : 0, 77 SCARG(uap, osa) ? &osa : 0, 78 NULL, 0); 79 80 if (error) 81 return (error); 82 83 if (SCARG(uap, osa)) { 84 sa32.netbsd32_sa_handler = (netbsd32_sigactionp_t)(u_long)osa.sa_handler; 85 sa32.netbsd32_sa_mask = osa.sa_mask; 86 sa32.netbsd32_sa_flags = osa.sa_flags; 87 sa32p = 88 (struct netbsd32_sigaction *)NETBSD32PTR64(SCARG(uap, osa)); 89 if (copyout(&sa32, sa32p, sizeof(sa32))) 90 return EFAULT; 91 } 92 93 return (0); 94 } 95 96 int 97 netbsd32___sigaltstack14(l, v, retval) 98 struct lwp *l; 99 void *v; 100 register_t *retval; 101 { 102 struct netbsd32___sigaltstack14_args /* { 103 syscallarg(const netbsd32_sigaltstackp_t) nss; 104 syscallarg(netbsd32_sigaltstackp_t) oss; 105 } */ *uap = v; 106 struct netbsd32_sigaltstack s32; 107 struct sigaltstack nss, oss; 108 int error; 109 110 if (SCARG(uap, nss)) { 111 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nss)), &s32, 112 sizeof(s32)); 113 if (error) 114 return (error); 115 nss.ss_sp = (void *)NETBSD32PTR64(s32.ss_sp); 116 nss.ss_size = (size_t)s32.ss_size; 117 nss.ss_flags = s32.ss_flags; 118 } 119 error = sigaltstack1(l->l_proc, 120 SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0); 121 if (error) 122 return (error); 123 if (SCARG(uap, oss)) { 124 s32.ss_sp = (netbsd32_voidp)(u_long)oss.ss_sp; 125 s32.ss_size = (netbsd32_size_t)oss.ss_size; 126 s32.ss_flags = oss.ss_flags; 127 error = copyout(&s32, (caddr_t)NETBSD32PTR64(SCARG(uap, oss)), 128 sizeof(s32)); 129 if (error) 130 return (error); 131 } 132 return (0); 133 } 134 135 /* ARGSUSED */ 136 int 137 netbsd32___sigaction14(l, v, retval) 138 struct lwp *l; 139 void *v; 140 register_t *retval; 141 { 142 struct netbsd32___sigaction14_args /* { 143 syscallarg(int) signum; 144 syscallarg(const struct sigaction *) nsa; 145 syscallarg(struct sigaction *) osa; 146 } */ *uap = v; 147 struct netbsd32_sigaction sa32; 148 struct sigaction nsa, osa; 149 int error; 150 151 if (SCARG(uap, nsa)) { 152 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsa)), &sa32, 153 sizeof(sa32)); 154 if (error) 155 return (error); 156 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 157 nsa.sa_mask = sa32.netbsd32_sa_mask; 158 nsa.sa_flags = sa32.netbsd32_sa_flags; 159 } 160 error = sigaction1(l->l_proc, SCARG(uap, signum), 161 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0, 162 NULL, 0); 163 if (error) 164 return (error); 165 if (SCARG(uap, osa)) { 166 sa32.netbsd32_sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler; 167 sa32.netbsd32_sa_mask = osa.sa_mask; 168 sa32.netbsd32_sa_flags = osa.sa_flags; 169 error = copyout(&sa32, (caddr_t)NETBSD32PTR64(SCARG(uap, osa)), 170 sizeof(sa32)); 171 if (error) 172 return (error); 173 } 174 return (0); 175 } 176 177 /* ARGSUSED */ 178 int 179 netbsd32___sigaction_sigtramp(l, v, retval) 180 struct lwp *l; 181 void *v; 182 register_t *retval; 183 { 184 struct netbsd32___sigaction_sigtramp_args /* { 185 syscallarg(int) signum; 186 syscallarg(const netbsd32_sigactionp_t) nsa; 187 syscallarg(netbsd32_sigactionp_t) osa; 188 syscallarg(netbsd32_voidp) tramp; 189 syscallarg(int) vers; 190 } */ *uap = v; 191 struct proc *p = l->l_proc; 192 struct netbsd32_sigaction sa32; 193 struct sigaction nsa, osa; 194 int error; 195 196 if (SCARG(uap, nsa)) { 197 error = copyin((caddr_t)NETBSD32PTR64(SCARG(uap, nsa)), &sa32, 198 sizeof(sa32)); 199 if (error) 200 return (error); 201 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 202 nsa.sa_mask = sa32.netbsd32_sa_mask; 203 nsa.sa_flags = sa32.netbsd32_sa_flags; 204 } 205 error = sigaction1(p, SCARG(uap, signum), 206 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0, 207 NETBSD32PTR64(SCARG(uap, tramp)), SCARG(uap, vers)); 208 if (error) 209 return (error); 210 if (SCARG(uap, osa)) { 211 sa32.netbsd32_sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler; 212 sa32.netbsd32_sa_mask = osa.sa_mask; 213 sa32.netbsd32_sa_flags = osa.sa_flags; 214 error = copyout(&sa32, (caddr_t)NETBSD32PTR64(SCARG(uap, osa)), 215 sizeof(sa32)); 216 if (error) 217 return (error); 218 } 219 return (0); 220 } 221 222 void 223 netbsd32_si32_to_si(siginfo_t *si, const siginfo32_t *si32) 224 { 225 memset(si, 0, sizeof (*si)); 226 si->si_signo = si32->si_signo; 227 si->si_code = si32->si_code; 228 si->si_errno = si32->si_errno; 229 230 switch (si32->si_signo) { 231 case SIGILL: 232 case SIGBUS: 233 case SIGSEGV: 234 case SIGFPE: 235 case SIGTRAP: 236 si->si_addr = (void *)NETBSD32PTR64(si32->si_addr); 237 si->si_trap = si32->si_trap; 238 break; 239 case SIGALRM: 240 case SIGVTALRM: 241 case SIGPROF: 242 si->si_pid = si32->si_pid; 243 si->si_uid = si32->si_uid; 244 /* 245 * XXX sival_ptr is currently unused. 246 */ 247 si->si_sigval.sival_int = si32->si_sigval.sival_int; 248 break; 249 case SIGCHLD: 250 si->si_pid = si32->si_pid; 251 si->si_uid = si32->si_uid; 252 si->si_utime = si32->si_utime; 253 si->si_stime = si32->si_stime; 254 break; 255 case SIGURG: 256 case SIGIO: 257 si->si_band = si32->si_band; 258 si->si_fd = si32->si_fd; 259 break; 260 } 261 } 262 263 void 264 netbsd32_si_to_si32(siginfo32_t *si32, const siginfo_t *si) 265 { 266 memset(si32, 0, sizeof (*si32)); 267 si32->si_signo = si->si_signo; 268 si32->si_code = si->si_code; 269 si32->si_errno = si->si_errno; 270 271 switch (si32->si_signo) { 272 case SIGILL: 273 case SIGBUS: 274 case SIGSEGV: 275 case SIGFPE: 276 case SIGTRAP: 277 si32->si_addr = (uint32_t)(uintptr_t)si->si_addr; 278 si32->si_trap = si->si_trap; 279 break; 280 case SIGALRM: 281 case SIGVTALRM: 282 case SIGPROF: 283 si32->si_pid = si->si_pid; 284 si32->si_uid = si->si_uid; 285 /* 286 * XXX sival_ptr is currently unused. 287 */ 288 si32->si_sigval.sival_int = si->si_sigval.sival_int; 289 break; 290 case SIGCHLD: 291 si32->si_pid = si->si_pid; 292 si32->si_uid = si->si_uid; 293 si32->si_status = si->si_status; 294 si32->si_utime = si->si_utime; 295 si32->si_stime = si->si_stime; 296 break; 297 case SIGURG: 298 case SIGIO: 299 si32->si_band = si->si_band; 300 si32->si_fd = si->si_fd; 301 break; 302 } 303 } 304 305 void 306 getucontext32(struct lwp *l, ucontext32_t *ucp) 307 { 308 struct proc *p; 309 310 p = l->l_proc; 311 312 ucp->uc_flags = 0; 313 ucp->uc_link = (uint32_t)(intptr_t)l->l_ctxlink; 314 315 (void)sigprocmask1(p, 0, NULL, &ucp->uc_sigmask); 316 ucp->uc_flags |= _UC_SIGMASK; 317 318 /* 319 * The (unsupplied) definition of the `current execution stack' 320 * in the System V Interface Definition appears to allow returning 321 * the main context stack. 322 */ 323 if ((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) == 0) { 324 ucp->uc_stack.ss_sp = USRSTACK32; 325 ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize); 326 ucp->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */ 327 } else { 328 /* Simply copy alternate signal execution stack. */ 329 ucp->uc_stack.ss_sp = 330 (uint32_t)(intptr_t)p->p_sigctx.ps_sigstk.ss_sp; 331 ucp->uc_stack.ss_size = p->p_sigctx.ps_sigstk.ss_size; 332 ucp->uc_stack.ss_flags = p->p_sigctx.ps_sigstk.ss_flags; 333 } 334 ucp->uc_flags |= _UC_STACK; 335 336 cpu_getmcontext32(l, &ucp->uc_mcontext, &ucp->uc_flags); 337 } 338 339 /* ARGSUSED */ 340 int 341 netbsd32_getcontext(struct lwp *l, void *v, register_t *retval) 342 { 343 struct netbsd32_getcontext_args /* { 344 syscallarg(netbsd32_ucontextp) ucp; 345 } */ *uap = v; 346 ucontext32_t uc; 347 348 getucontext32(l, &uc); 349 350 return copyout(&uc, NETBSD32PTR64(SCARG(uap, ucp)), 351 sizeof (ucontext32_t)); 352 } 353 354 int 355 setucontext32(struct lwp *l, const ucontext32_t *ucp) 356 { 357 struct proc *p; 358 int error; 359 360 p = l->l_proc; 361 if ((error = cpu_setmcontext32(l, &ucp->uc_mcontext, 362 ucp->uc_flags)) != 0) 363 return (error); 364 l->l_ctxlink = (void *)(intptr_t)ucp->uc_link; 365 /* 366 * We might want to take care of the stack portion here but currently 367 * don't; see the comment in getucontext(). 368 */ 369 if ((ucp->uc_flags & _UC_SIGMASK) != 0) 370 sigprocmask1(p, SIG_SETMASK, &ucp->uc_sigmask, NULL); 371 372 return 0; 373 } 374 375 /* ARGSUSED */ 376 int 377 netbsd32_setcontext(struct lwp *l, void *v, register_t *retval) 378 { 379 struct netbsd32_setcontext_args /* { 380 syscallarg(netbsd32_ucontextp) ucp; 381 } */ *uap = v; 382 ucontext32_t uc; 383 int error; 384 void *p; 385 386 p = NETBSD32PTR64(SCARG(uap, ucp)); 387 if (p == NULL) 388 exit1(l, W_EXITCODE(0, 0)); 389 else if ((error = copyin(p, &uc, sizeof (uc))) != 0 || 390 (error = setucontext32(l, &uc)) != 0) 391 return (error); 392 393 return (EJUSTRETURN); 394 } 395 396 static int 397 netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size) 398 { 399 const siginfo_t *info = src; 400 siginfo32_t info32; 401 402 netbsd32_si_to_si32(&info32, info); 403 404 return copyout(&info32, dst, sizeof(info32)); 405 } 406 407 static int 408 netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size) 409 { 410 struct timespec *ts = dst; 411 struct netbsd32_timespec ts32; 412 int error; 413 414 error = copyin(src, &ts32, sizeof(ts32)); 415 if (error) 416 return error; 417 418 netbsd32_to_timespec(&ts32, ts); 419 return 0; 420 } 421 422 static int 423 netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size) 424 { 425 const struct timespec *ts = src; 426 struct netbsd32_timespec ts32; 427 428 netbsd32_from_timespec(ts, &ts32); 429 430 return copyout(&ts32, dst, sizeof(ts32)); 431 } 432 433 int 434 netbsd32___sigtimedwait(struct lwp *l, void *v, register_t *retval) 435 { 436 struct netbsd32___sigtimedwait_args /* { 437 syscallarg(netbsd32_sigsetp_t) set; 438 syscallarg(netbsd32_siginfop_t) info; 439 syscallarg(netbsd32_timespecp_t) timeout; 440 } */ *uap = v; 441 struct sys___sigtimedwait_args ua; 442 443 NETBSD32TOP_UAP(set, const sigset_t); 444 NETBSD32TOP_UAP(info, siginfo_t); 445 NETBSD32TOP_UAP(timeout, struct timespec); 446 447 return __sigtimedwait1(l, &ua, retval, netbsd32_sigtimedwait_put_info, 448 netbsd32_sigtimedwait_fetch_timeout, 449 netbsd32_sigtimedwait_put_timeout); 450 } 451