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