1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/brand.h> 29 #include <sys/errno.h> 30 #include <sys/sysconfig.h> 31 #include <sys/ucontext.h> 32 #include <sys/wait.h> 33 #include <stdlib.h> 34 #include <strings.h> 35 #include <signal.h> 36 37 #include <s10_brand.h> 38 #include <s10_misc.h> 39 #include <s10_signal.h> 40 41 s10_sighandler_t s10_handlers[S10_NSIG - 1]; 42 43 /* 44 * Theory of operation: 45 * 46 * As of now, Solaris 10 and solaris_nevada signal numbers match all the 47 * way through SIGJVM2 (1 - 40) and the first 8 realtime signals (41 - 48). 48 * However, solaris_nevada provides 32 realtime signals rather than 8 for S10. 49 * 50 * We do not assume that the current range of realtime signals is 51 * _SIGRTMIN - _SIGRTMAX. As a hedge against future changes, 52 * we obtain the realtime signal range via SIGRTMIN and SIGRTMAX. 53 * 54 * Therefore, we must interpose on the various signal calls to translate 55 * signal masks and signal handlers that deal with SIGRTMIN - SIGRTMAX to 56 * refer to a potentially different range and to intercenpt any "illegal" 57 * signals that might otherwise be sent to an S10 process. 58 * 59 * Simple translation is all that is required to handle most system calls, 60 * but signal handlers also must be interposed upon so that a user signal 61 * handler sees proper signal numbers in its arguments, any passed siginfo_t 62 * and in the signal mask reported in its ucontext_t. 63 * 64 * libc adds its own signal handler to handled signals such that the 65 * signal delivery mechanism looks like: 66 * 67 * signal -> libc sigacthandler() -> user signal handler 68 * 69 * With interposition, this will instead look like: 70 * 71 * signal -> 72 * s10_sigacthandler() -> 73 * libc sigacthandler() -> 74 * user signal handler() 75 */ 76 77 /* 78 * A little exposition on SIGRTMIN and SIGRTMAX: 79 * 80 * For configurability reasons, in Solaris SIGRTMIN and SIGRTMAX are actually 81 * #defined to be routines: 82 * 83 * #define SIGRTMIN ((int)_sysconf(_SC_SIGRT_MIN)) 84 * #define SIGRTMAX ((int)_sysconf(_SC_SIGRT_MAX)) 85 * 86 * This means we need routines that will call the native sysconfig() system 87 * call to find out what the native values for SIGRTMIN and SIGRTMAX are, and 88 * those are native_sigrtmin() and native_sigrtmax(), respectively. 89 * 90 * To try and mitigate confusion this might cause, rather than use SIGRTMIN and 91 * SIGRTMAX directly, mnemonic convenience macros are #defined to clarify the 92 * matter: 93 * 94 * S10_SIGRTMIN 95 * S10_SIGRTMAX 96 * NATIVE_SIGRTMIN 97 * NATIVE_SIGRTMAX 98 */ 99 100 static int 101 native_sigrtmin() 102 { 103 static int sigrtmin; 104 sysret_t rval; 105 106 if (sigrtmin) 107 return (sigrtmin); 108 sigrtmin = __systemcall(&rval, SYS_sysconfig + 1024, _CONFIG_SIGRT_MIN)? 109 _SIGRTMIN : (int)rval.sys_rval1; 110 return (sigrtmin); 111 } 112 113 static int 114 native_sigrtmax() 115 { 116 static int sigrtmax; 117 sysret_t rval; 118 119 if (sigrtmax) 120 return (sigrtmax); 121 sigrtmax = __systemcall(&rval, SYS_sysconfig + 1024, _CONFIG_SIGRT_MAX)? 122 _SIGRTMAX : (int)rval.sys_rval1; 123 return (sigrtmax); 124 } 125 126 #define NATIVE_SIGRTMIN (native_sigrtmin()) 127 #define NATIVE_SIGRTMAX (native_sigrtmax()) 128 129 /* 130 * These #defines are setup to create the SIGADDSET and SIGISMEMBER macros, 131 * needed because the sigaddset(3C) and sigismember(3C) calls make function 132 * calls that end up being recursive in an interpositioned system call 133 * environment. 134 */ 135 #define MAXBITNO (NBPW*8) 136 #define SIGWORD(n) ((n-1)/MAXBITNO) 137 #define BITMASK(n) (1L<<((n-1)%MAXBITNO)) 138 139 #define SIGADDSET(sigset, sig) \ 140 ((sigset)->__sigbits[SIGWORD(sig)] |= BITMASK(sig)) 141 142 #define SIGISMEMBER(sigset, sig) \ 143 (((sigset)->__sigbits[SIGWORD(sig)] & BITMASK(sig)) != 0) 144 145 /* 146 * Convert an S10 signal number to its native value. 147 */ 148 static int 149 s10sig_to_native(int sig) 150 { 151 /* signals 1 .. SIGJVM2 are the same between S10 and native */ 152 if (sig <= SIGJVM2) 153 return (sig); 154 155 /* 156 * If a signal is > SIGJVM2 but is < S10_SIGRTMIN, it's being used 157 * for some private purpose we likely wouldn't emulate properly. 158 */ 159 if (sig < S10_SIGRTMIN) /* can't happen */ 160 return (-1); 161 162 /* 163 * Map S10 RT signals to their native counterparts to the degree 164 * possible. If the signal would be out of the native RT signal 165 * range, return an error to the caller. 166 */ 167 sig -= S10_SIGRTMIN; 168 169 if (sig > (NATIVE_SIGRTMAX - NATIVE_SIGRTMIN)) 170 return (-1); 171 172 return (NATIVE_SIGRTMIN + sig); 173 } 174 175 /* 176 * Convert an S10 sigset_t to its native version. 177 */ 178 int 179 s10sigset_to_native(const sigset_t *s10_set, sigset_t *native_set) 180 { 181 int sig; 182 int nativesig; 183 sigset_t srcset, newset; 184 185 if (s10_uucopy(s10_set, &srcset, sizeof (sigset_t)) != 0) 186 return (EFAULT); 187 188 (void) sigemptyset(&newset); 189 190 /* 191 * Shortcut: we know the first 32 signals are the same in both 192 * s10 and native Solaris. Just assign the first word. 193 */ 194 newset.__sigbits[0] = srcset.__sigbits[0]; 195 196 /* 197 * Copy the remainder of the initial set of common signals. 198 */ 199 for (sig = 33; sig <= SIGJVM2; sig++) 200 if (SIGISMEMBER(&srcset, sig)) 201 SIGADDSET(&newset, sig); 202 203 /* convert any S10 RT signals to their native equivalents */ 204 for (sig = S10_SIGRTMIN; sig <= S10_SIGRTMAX; sig++) { 205 if (SIGISMEMBER(&srcset, sig) && 206 (nativesig = s10sig_to_native(sig)) > 0) 207 SIGADDSET(&newset, nativesig); 208 } 209 210 if (s10_uucopy(&newset, native_set, sizeof (sigset_t)) != 0) 211 return (EFAULT); 212 213 return (0); 214 } 215 216 /* 217 * Convert a native signal number to its S10 value. 218 */ 219 int 220 nativesig_to_s10(int sig) 221 { 222 /* signals 1 .. SIGJVM2 are the same between native and S10 */ 223 if (sig <= SIGJVM2) 224 return (sig); 225 226 /* 227 * We have no way to emulate native signals between (SIGJVM2 + 1) and 228 * NATIVE_SIGRTMIN, so return an error to the caller. 229 */ 230 if (sig < NATIVE_SIGRTMIN) /* can't happen */ 231 return (-1); 232 233 /* 234 * Map native RT signals to their S10 counterparts to the degree 235 * possible. If the signal would be out of range for S10, return 236 * an error to the caller. 237 */ 238 sig -= NATIVE_SIGRTMIN; 239 240 if (sig > (S10_SIGRTMAX - S10_SIGRTMIN)) 241 return (-1); 242 243 return (S10_SIGRTMIN + sig); 244 } 245 246 /* 247 * Convert a native sigset_t to its S10 version. 248 */ 249 int 250 nativesigset_to_s10(const sigset_t *native_set, sigset_t *s10_set) 251 { 252 int sig; 253 int s10sig; 254 sigset_t srcset, newset; 255 256 if (s10_uucopy(native_set, &srcset, sizeof (sigset_t)) != 0) 257 return (EFAULT); 258 259 (void) sigemptyset(&newset); 260 261 /* 262 * Shortcut: we know the first 32 signals are the same in both 263 * s10 and native Solaris. Just assign the first word. 264 */ 265 newset.__sigbits[0] = srcset.__sigbits[0]; 266 267 /* 268 * Copy the remainder of the initial set of common signals. 269 */ 270 for (sig = 33; sig <= SIGJVM2; sig++) 271 if (SIGISMEMBER(&srcset, sig)) 272 SIGADDSET(&newset, sig); 273 274 /* convert any RT signals to their S10 values */ 275 for (sig = NATIVE_SIGRTMIN; sig <= NATIVE_SIGRTMAX; sig++) { 276 if (SIGISMEMBER(&srcset, sig) && 277 (s10sig = nativesig_to_s10(sig)) > 0) 278 SIGADDSET(&newset, s10sig); 279 } 280 281 if (s10_uucopy(&newset, s10_set, sizeof (sigset_t)) != 0) 282 return (EFAULT); 283 284 return (0); 285 } 286 287 /* 288 * This is our interposed signal handler. 289 * Fix up the arguments received from the kernel and jump 290 * to the s10 signal handler, normally libc's sigacthandler(). 291 */ 292 static void 293 s10_sigacthandler(int sig, siginfo_t *sip, void *uvp) 294 { 295 int s10_sig; 296 ucontext_t *ucp; 297 298 s10_sig = nativesig_to_s10(sig); 299 if (s10_sig <= 0) /* can't happen? */ 300 s10_abort(sig, "Received an impossible signal"); 301 if (sip != NULL) { 302 /* 303 * All we really have to do is map the signal number, 304 * which changes only for the realtime signals, 305 * so all the rest of the siginfo structure is the 306 * same between s10 and native. 307 */ 308 if (sip->si_signo != sig) /* can't happen? */ 309 s10_abort(sig, "Received an impossible siginfo"); 310 sip->si_signo = s10_sig; 311 } 312 if ((ucp = uvp) != NULL && 313 (ucp->uc_flags & UC_SIGMASK)) 314 (void) nativesigset_to_s10(&ucp->uc_sigmask, &ucp->uc_sigmask); 315 316 s10_handlers[s10_sig - 1](s10_sig, sip, uvp); 317 } 318 319 /* 320 * Interposition upon SYS_lwp_sigmask 321 */ 322 int 323 s10_lwp_sigmask(sysret_t *rval, int how, uint_t bits0, uint_t bits1) 324 { 325 sigset_t s10_blockset; 326 sigset_t native_blockset; 327 int err; 328 329 s10_blockset.__sigbits[0] = bits0; 330 s10_blockset.__sigbits[1] = bits1; 331 s10_blockset.__sigbits[2] = 0; 332 s10_blockset.__sigbits[3] = 0; 333 334 (void) s10sigset_to_native(&s10_blockset, &native_blockset); 335 336 err = __systemcall(rval, SYS_lwp_sigmask + 1024, 337 how, 338 native_blockset.__sigbits[0], 339 native_blockset.__sigbits[1], 340 native_blockset.__sigbits[2], 341 native_blockset.__sigbits[3]); 342 343 if (err != 0) 344 return (err); 345 346 native_blockset.__sigbits[0] = (int)rval->sys_rval1; 347 native_blockset.__sigbits[1] = (int)rval->sys_rval2; 348 native_blockset.__sigbits[2] = 0; 349 native_blockset.__sigbits[3] = 0; 350 351 (void) nativesigset_to_s10(&native_blockset, &s10_blockset); 352 353 rval->sys_rval1 = s10_blockset.__sigbits[0]; 354 rval->sys_rval2 = s10_blockset.__sigbits[1]; 355 356 return (0); 357 } 358 359 /* 360 * Interposition upon SYS_sigprocmask 361 */ 362 int 363 s10_sigprocmask(sysret_t *rval, int how, const sigset_t *set, sigset_t *oset) 364 { 365 sigset_t sigset_set, sigset_oset; 366 sigset_t *set_ptr, *oset_ptr; 367 int err; 368 369 oset_ptr = (oset == NULL) ? NULL : &sigset_oset; 370 set_ptr = (set == NULL) ? NULL : &sigset_set; 371 372 if (set_ptr != NULL && 373 (err = s10sigset_to_native(set, set_ptr)) != 0) 374 return (err); 375 376 if ((err = __systemcall(rval, SYS_sigprocmask + 1024, 377 how, set_ptr, oset_ptr)) != 0) 378 return (err); 379 380 if (oset_ptr != NULL && 381 (err = nativesigset_to_s10(oset_ptr, oset)) != 0) 382 return (err); 383 384 return (0); 385 } 386 387 /* 388 * Interposition upon SYS_sigsuspend 389 */ 390 int 391 s10_sigsuspend(sysret_t *rval, const sigset_t *set) 392 { 393 sigset_t sigset_set; 394 int err; 395 396 if ((err = s10sigset_to_native(set, &sigset_set)) != 0) { 397 (void) S10_TRUSS_POINT_1(rval, SYS_sigsuspend, err, set); 398 return (err); 399 } 400 401 return (__systemcall(rval, SYS_sigsuspend + 1024, &sigset_set)); 402 } 403 404 /* 405 * Interposition upon SYS_sigaction 406 * 407 * There is a fair amount of complexity here due to the need to interpose 408 * on any registered user signal handler. 409 * 410 * The idea is that if a user signal handler is installed, we must install 411 * our own signal handler between the system and the signal handler being 412 * registered. If the signal handler to be registered is SIG_DFL or SIG_IGN, 413 * we should remove our interpositioned handler as it's no longer needed. 414 * 415 * The way we do this is we set the signal handler to call s10_sigacthandler(), 416 * and then store the address of the passed signal handler in a global 417 * per-process array, s10_handlers[]. 418 * 419 * We rely on the fact that the s10 libc blocks all signals during 420 * its call to the sigaction() system call to guarantee atomicity. 421 */ 422 int 423 s10_sigaction(sysret_t *rval, 424 int sig, const struct sigaction *act, struct sigaction *oact) 425 { 426 struct sigaction sigact, osigact; 427 struct sigaction *sigactp, *osigactp; 428 int err, nativesig; 429 void (*handler)(); 430 431 if ((nativesig = s10sig_to_native(sig)) < 0) { 432 (void) S10_TRUSS_POINT_3(rval, SYS_sigaction, EINVAL, 433 sig, act, oact); 434 return (EINVAL); 435 } 436 437 if (act == NULL) { 438 sigactp = NULL; 439 } else { 440 sigactp = &sigact; 441 442 if (s10_uucopy(act, sigactp, sizeof (struct sigaction)) != 0) 443 return (EFAULT); 444 445 if ((err = s10sigset_to_native(&sigactp->sa_mask, 446 &sigactp->sa_mask)) != 0) { 447 (void) S10_TRUSS_POINT_3(rval, SYS_sigaction, err, 448 sig, act, oact); 449 return (err); 450 } 451 } 452 453 osigactp = ((oact == NULL) ? NULL : &osigact); 454 455 if (sigactp != NULL) { 456 handler = sigactp->sa_handler; 457 if (handler != SIG_DFL && handler != SIG_IGN) 458 sigactp->sa_handler = s10_sigacthandler; 459 } 460 461 if ((err = __systemcall(rval, SYS_sigaction + 1024, 462 nativesig, sigactp, osigactp)) != 0) 463 return (err); 464 465 /* 466 * Translate the old signal mask if we are supposed to return the old 467 * struct sigaction. 468 * 469 * Note that we may have set the signal handler, but may return EFAULT 470 * here if the oact parameter is bad. 471 * 472 * That's OK, because the direct system call acts the same way. 473 */ 474 if (osigactp != NULL) { 475 err = nativesigset_to_s10(&osigactp->sa_mask, 476 &osigactp->sa_mask); 477 478 if (osigactp->sa_handler == s10_sigacthandler) 479 osigactp->sa_handler = s10_handlers[sig - 1]; 480 481 if (err == 0 && 482 s10_uucopy(osigactp, oact, sizeof (struct sigaction)) != 0) 483 err = EFAULT; 484 } 485 486 /* 487 * Do not store SIG_DFL or SIG_IGN into the array of remembered 488 * signal handlers. Only store bona-fide function addresses. 489 * This is to avoid a race condition in which some thread 490 * sets the signal handler to SIG_DFL or SIG_IGN while some 491 * other thread is fielding the signal but has not yet reached 492 * s10_sigacthandler(). s10_sigacthandler() will unconditionally 493 * call the remembered signal handler and it it calls SIG_DFL or 494 * SIG_IGN, the process will incur a SIGSEGV or SIGBUS signal. 495 * This also allows a vfork() child to set signal handlers 496 * to SIG_DFL or SIG_IGN without corrupting the parent's 497 * address space. 498 */ 499 if (sigactp != NULL && 500 handler != SIG_DFL && handler != SIG_IGN) 501 s10_handlers[sig - 1] = handler; 502 503 return (err); 504 } 505 506 /* 507 * Interposition upon SYS_sigpending 508 */ 509 int 510 s10_sigpending(sysret_t *rval, int flag, sigset_t *set) 511 { 512 sigset_t sigset_set; 513 int err; 514 515 if ((err = __systemcall(rval, SYS_sigpending + 1024, 516 flag, &sigset_set)) != 0) 517 return (err); 518 519 if ((err = nativesigset_to_s10(&sigset_set, set)) != 0) 520 return (err); 521 522 return (0); 523 } 524 525 /* 526 * Interposition upon SYS_context 527 */ 528 int 529 s10_context(sysret_t *rval, int flag, ucontext_t *ucp) 530 { 531 ucontext_t uc; 532 int err; 533 534 if (flag == SETCONTEXT) { 535 if (s10_uucopy(ucp, &uc, sizeof (ucontext_t)) != 0) 536 return (EFAULT); 537 if (uc.uc_flags & UC_SIGMASK) { 538 if ((err = s10sigset_to_native(&uc.uc_sigmask, 539 &uc.uc_sigmask)) != 0) { 540 (void) S10_TRUSS_POINT_2(rval, SYS_context, err, 541 flag, ucp); 542 return (err); 543 } 544 } 545 ucp = &uc; 546 } 547 548 err = __systemcall(rval, SYS_context + 1024, flag, ucp); 549 if (err != 0) 550 return (err); 551 552 if (flag == GETCONTEXT && (ucp->uc_flags & UC_SIGMASK)) 553 (void) nativesigset_to_s10(&ucp->uc_sigmask, &ucp->uc_sigmask); 554 555 return (0); 556 } 557 558 /* 559 * Interposition upon SYS_sigsendsys 560 */ 561 int 562 s10_sigsendsys(sysret_t *rval, procset_t *psp, int sig) 563 { 564 int nativesig; 565 566 if ((nativesig = s10sig_to_native(sig)) < 0) { 567 (void) S10_TRUSS_POINT_2(rval, SYS_sigsendsys, EINVAL, 568 psp, sig); 569 return (EINVAL); 570 } 571 572 return (__systemcall(rval, SYS_sigsendsys + 1024, psp, nativesig)); 573 } 574 575 /* 576 * Convert the siginfo_t code and status fields to an old style 577 * wait status for s10_wait(), below. 578 */ 579 static int 580 wstat(int code, int status) 581 { 582 int stat = (status & 0377); 583 584 switch (code) { 585 case CLD_EXITED: 586 stat <<= 8; 587 break; 588 case CLD_DUMPED: 589 stat |= WCOREFLG; 590 break; 591 case CLD_KILLED: 592 break; 593 case CLD_TRAPPED: 594 case CLD_STOPPED: 595 stat <<= 8; 596 stat |= WSTOPFLG; 597 break; 598 case CLD_CONTINUED: 599 stat = WCONTFLG; 600 break; 601 } 602 return (stat); 603 } 604 605 /* 606 * Interposition upon SYS_wait 607 */ 608 int 609 s10_wait(sysret_t *rval) 610 { 611 int err; 612 siginfo_t info; 613 614 err = s10_waitid(rval, P_ALL, 0, &info, WEXITED | WTRAPPED); 615 if (err != 0) 616 return (err); 617 618 rval->sys_rval1 = info.si_pid; 619 rval->sys_rval2 = wstat(info.si_code, info.si_status); 620 621 return (0); 622 } 623 624 /* 625 * Interposition upon SYS_waitid 626 */ 627 int 628 s10_waitid(sysret_t *rval, 629 idtype_t idtype, id_t id, siginfo_t *infop, int options) 630 { 631 int err, sig; 632 633 err = __systemcall(rval, SYS_waitid + 1024, idtype, id, infop, options); 634 if (err != 0) 635 return (err); 636 637 /* 638 * If the process being waited for terminated or stopped due to a 639 * signal, translate the signal number from its native value to its 640 * S10 equivalent. 641 * 642 * If we can't legally translate the signal number, just sort of punt 643 * and leave it untranslated. 644 * 645 * We shouldn't return EINVAL as the syscall didn't technically fail. 646 */ 647 if (infop->si_signo == SIGCLD && infop->si_code != CLD_EXITED && 648 (sig = nativesig_to_s10(infop->si_status)) > 0) 649 infop->si_status = sig; 650 651 return (0); 652 } 653 654 /* 655 * Interposition upon SYS_sigtimedwait 656 */ 657 int 658 s10_sigtimedwait(sysret_t *rval, 659 const sigset_t *set, siginfo_t *info, const timespec_t *timeout) 660 { 661 sigset_t sigset_set; 662 int err, sig; 663 664 if ((err = s10sigset_to_native(set, &sigset_set)) != 0) { 665 (void) S10_TRUSS_POINT_3(rval, SYS_sigtimedwait, err, 666 set, info, timeout); 667 return (err); 668 } 669 670 if ((err = __systemcall(rval, SYS_sigtimedwait + 1024, 671 &sigset_set, info, timeout)) != 0) 672 return (err); 673 674 if (info != NULL) { 675 /* 676 * If we can't legally translate the signal number in the 677 * siginfo_t, just sort of punt and leave it untranslated. 678 * 679 * We shouldn't return EINVAL as the syscall didn't technically 680 * fail. 681 */ 682 if ((sig = nativesig_to_s10(info->si_signo)) > 0) 683 info->si_signo = sig; 684 } 685 686 /* 687 * If we can't legally translate the signal number returned by the 688 * sigtimedwait syscall, just sort of punt and leave it untranslated. 689 * 690 * We shouldn't return EINVAL as the syscall didn't technically 691 * fail. 692 */ 693 if ((sig = nativesig_to_s10((int)rval->sys_rval1)) > 0) 694 rval->sys_rval1 = sig; 695 696 return (0); 697 } 698 699 /* 700 * Interposition upon SYS_sigqueue 701 */ 702 int 703 s10_sigqueue(sysret_t *rval, pid_t pid, int signo, void *value, int si_code) 704 { 705 int nativesig; 706 707 if ((nativesig = s10sig_to_native(signo)) < 0) { 708 (void) S10_TRUSS_POINT_4(rval, SYS_sigqueue, EINVAL, 709 pid, signo, value, si_code); 710 return (EINVAL); 711 } 712 713 if (pid == 1) 714 pid = zone_init_pid; 715 716 /* 717 * The native version of this syscall takes an extra argument. 718 * The new last arg "block" flag should be zero. The block flag 719 * is used by the Opensolaris AIO implementation, which is now 720 * part of libc. 721 */ 722 return (__systemcall(rval, SYS_sigqueue + 1024, 723 pid, nativesig, value, si_code, 0)); 724 } 725 726 /* 727 * Interposition upon SYS_signotify 728 */ 729 int 730 s10_signotify(sysret_t *rval, 731 int cmd, siginfo_t *siginfo, signotify_id_t *sn_id) 732 { 733 siginfo_t *infop, info; 734 735 infop = siginfo; 736 737 /* only check for a valid siginfo pointer in the case of SN_PROC */ 738 if (cmd == SN_PROC) { 739 int nativesig; 740 741 if (s10_uucopy(infop, &info, sizeof (siginfo_t)) != 0) 742 return (EFAULT); 743 744 if ((nativesig = s10sig_to_native(info.si_signo)) < 0) { 745 (void) S10_TRUSS_POINT_3(rval, SYS_signotify, EINVAL, 746 cmd, siginfo, sn_id); 747 return (EINVAL); 748 } 749 750 info.si_signo = nativesig; 751 infop = &info; 752 } 753 754 return (__systemcall(rval, SYS_signotify + 1024, cmd, infop, sn_id)); 755 } 756 757 /* 758 * Interposition upon SYS_kill 759 */ 760 int 761 s10_kill(sysret_t *rval, pid_t pid, int sig) 762 { 763 int nativesig; 764 765 if ((nativesig = s10sig_to_native(sig)) < 0) { 766 (void) S10_TRUSS_POINT_2(rval, SYS_kill, EINVAL, pid, sig); 767 return (EINVAL); 768 } 769 770 if (pid == 1) 771 pid = zone_init_pid; 772 773 return (__systemcall(rval, SYS_kill + 1024, pid, nativesig)); 774 } 775 776 /* 777 * Interposition upon SYS_lwp_create 778 * 779 * See also the s10_lwp_create_correct_fs() function in s10_brand.c 780 * for the special case of creating an lwp in a 64-bit x86 process. 781 */ 782 int 783 s10_lwp_create(sysret_t *rval, ucontext_t *ucp, int flags, id_t *new_lwp) 784 { 785 ucontext_t s10_uc; 786 787 if (s10_uucopy(ucp, &s10_uc, sizeof (ucontext_t)) != 0) 788 return (EFAULT); 789 790 if (s10_uc.uc_flags & UC_SIGMASK) 791 (void) s10sigset_to_native(&s10_uc.uc_sigmask, 792 &s10_uc.uc_sigmask); 793 794 return (__systemcall(rval, SYS_lwp_create + 1024, 795 &s10_uc, flags, new_lwp)); 796 } 797 798 /* 799 * Interposition upon SYS_lwp_kill 800 */ 801 int 802 s10_lwp_kill(sysret_t *rval, id_t lwpid, int sig) 803 { 804 int nativesig; 805 806 if ((nativesig = s10sig_to_native(sig)) < 0) { 807 (void) S10_TRUSS_POINT_2(rval, SYS_lwp_kill, EINVAL, 808 lwpid, sig); 809 return (EINVAL); 810 } 811 812 return (__systemcall(rval, SYS_lwp_kill + 1024, lwpid, nativesig)); 813 } 814