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 * 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 * Map S10 RT signals to their native counterparts to the degree 174 * possible. If the signal would be out of the native RT signal 175 * range, return an error to the caller. 176 */ 177 sig -= S10_SIGRTMIN; 178 179 if (sig > (NATIVE_SIGRTMAX - NATIVE_SIGRTMIN)) 180 return (-1); 181 182 return (NATIVE_SIGRTMIN + sig); 183 } 184 185 /* 186 * Convert an S10 sigset_t to its native version. 187 */ 188 int 189 s10sigset_to_native(const sigset_t *s10_set, sigset_t *native_set) 190 { 191 int sig; 192 int nativesig; 193 sigset_t srcset, newset; 194 195 if (s10_uucopy(s10_set, &srcset, sizeof (sigset_t)) != 0) 196 return (EFAULT); 197 198 (void) sigemptyset(&newset); 199 200 /* 201 * Shortcut: we know the first 32 signals are the same in both 202 * s10 and native Solaris. Just assign the first word. 203 */ 204 newset.__sigbits[0] = srcset.__sigbits[0]; 205 206 /* 207 * Copy the remainder of the initial set of common signals. 208 */ 209 for (sig = 33; sig <= SIGJVM2; sig++) 210 if (SIGISMEMBER(&srcset, sig)) 211 SIGADDSET(&newset, sig); 212 213 /* convert any S10 RT signals to their native equivalents */ 214 for (sig = S10_SIGRTMIN; sig <= S10_SIGRTMAX; sig++) { 215 if (SIGISMEMBER(&srcset, sig) && 216 (nativesig = s10sig_to_native(sig)) > 0) 217 SIGADDSET(&newset, nativesig); 218 } 219 220 if (s10_uucopy(&newset, native_set, sizeof (sigset_t)) != 0) 221 return (EFAULT); 222 223 return (0); 224 } 225 226 /* 227 * Convert a native signal number to its S10 value. 228 */ 229 int 230 nativesig_to_s10(int sig) 231 { 232 /* signals 1 .. SIGJVM2 are the same between native and S10 */ 233 if (sig <= SIGJVM2) 234 return (sig); 235 236 /* 237 * We have no way to emulate native signals between (SIGJVM2 + 1) and 238 * NATIVE_SIGRTMIN, so return an error to the caller. 239 */ 240 if (sig < NATIVE_SIGRTMIN) /* can't happen */ 241 return (-1); 242 243 /* 244 * Map native RT signals to their S10 counterparts to the degree 245 * possible. If the signal would be out of range for S10, return 246 * an error to the caller. 247 */ 248 sig -= NATIVE_SIGRTMIN; 249 250 if (sig > (S10_SIGRTMAX - S10_SIGRTMIN)) 251 return (-1); 252 253 return (S10_SIGRTMIN + sig); 254 } 255 256 /* 257 * Convert a native sigset_t to its S10 version. 258 */ 259 int 260 nativesigset_to_s10(const sigset_t *native_set, sigset_t *s10_set) 261 { 262 int sig; 263 int s10sig; 264 sigset_t srcset, newset; 265 266 if (s10_uucopy(native_set, &srcset, sizeof (sigset_t)) != 0) 267 return (EFAULT); 268 269 (void) sigemptyset(&newset); 270 271 /* 272 * Shortcut: we know the first 32 signals are the same in both 273 * s10 and native Solaris. Just assign the first word. 274 */ 275 newset.__sigbits[0] = srcset.__sigbits[0]; 276 277 /* 278 * Copy the remainder of the initial set of common signals. 279 */ 280 for (sig = 33; sig <= SIGJVM2; sig++) 281 if (SIGISMEMBER(&srcset, sig)) 282 SIGADDSET(&newset, sig); 283 284 /* convert any RT signals to their S10 values */ 285 for (sig = NATIVE_SIGRTMIN; sig <= NATIVE_SIGRTMAX; sig++) { 286 if (SIGISMEMBER(&srcset, sig) && 287 (s10sig = nativesig_to_s10(sig)) > 0) 288 SIGADDSET(&newset, s10sig); 289 } 290 291 if (s10_uucopy(&newset, s10_set, sizeof (sigset_t)) != 0) 292 return (EFAULT); 293 294 return (0); 295 } 296 297 /* 298 * This is our interposed signal handler. 299 * Fix up the arguments received from the kernel and jump 300 * to the s10 signal handler, normally libc's sigacthandler(). 301 */ 302 static void 303 s10_sigacthandler(int sig, siginfo_t *sip, void *uvp) 304 { 305 int s10_sig; 306 ucontext_t *ucp; 307 308 s10_sig = nativesig_to_s10(sig); 309 if (s10_sig <= 0) /* can't happen? */ 310 s10_abort(sig, "Received an impossible signal"); 311 if (sip != NULL) { 312 /* 313 * All we really have to do is map the signal number, 314 * which changes only for the realtime signals, 315 * so all the rest of the siginfo structure is the 316 * same between s10 and native. 317 */ 318 if (sip->si_signo != sig) /* can't happen? */ 319 s10_abort(sig, "Received an impossible siginfo"); 320 sip->si_signo = s10_sig; 321 } 322 if ((ucp = uvp) != NULL && 323 (ucp->uc_flags & UC_SIGMASK)) 324 (void) nativesigset_to_s10(&ucp->uc_sigmask, &ucp->uc_sigmask); 325 326 s10_handlers[s10_sig - 1](s10_sig, sip, uvp); 327 } 328 329 /* 330 * Interposition upon SYS_lwp_sigmask 331 */ 332 int 333 s10_lwp_sigmask(sysret_t *rval, int how, uint_t bits0, uint_t bits1) 334 { 335 sigset_t s10_blockset; 336 sigset_t native_blockset; 337 int err; 338 339 s10_blockset.__sigbits[0] = bits0; 340 s10_blockset.__sigbits[1] = bits1; 341 s10_blockset.__sigbits[2] = 0; 342 s10_blockset.__sigbits[3] = 0; 343 344 (void) s10sigset_to_native(&s10_blockset, &native_blockset); 345 346 err = __systemcall(rval, SYS_lwp_sigmask + 1024, 347 how, 348 native_blockset.__sigbits[0], 349 native_blockset.__sigbits[1], 350 native_blockset.__sigbits[2], 351 native_blockset.__sigbits[3]); 352 353 if (err != 0) 354 return (err); 355 356 native_blockset.__sigbits[0] = (int)rval->sys_rval1; 357 native_blockset.__sigbits[1] = (int)rval->sys_rval2; 358 native_blockset.__sigbits[2] = 0; 359 native_blockset.__sigbits[3] = 0; 360 361 (void) nativesigset_to_s10(&native_blockset, &s10_blockset); 362 363 rval->sys_rval1 = s10_blockset.__sigbits[0]; 364 rval->sys_rval2 = s10_blockset.__sigbits[1]; 365 366 return (0); 367 } 368 369 /* 370 * Interposition upon SYS_sigprocmask 371 */ 372 int 373 s10_sigprocmask(sysret_t *rval, int how, const sigset_t *set, sigset_t *oset) 374 { 375 sigset_t sigset_set, sigset_oset; 376 sigset_t *set_ptr, *oset_ptr; 377 int err; 378 379 oset_ptr = (oset == NULL) ? NULL : &sigset_oset; 380 set_ptr = (set == NULL) ? NULL : &sigset_set; 381 382 if (set_ptr != NULL && 383 (err = s10sigset_to_native(set, set_ptr)) != 0) 384 return (err); 385 386 if ((err = __systemcall(rval, SYS_sigprocmask + 1024, 387 how, set_ptr, oset_ptr)) != 0) 388 return (err); 389 390 if (oset_ptr != NULL && 391 (err = nativesigset_to_s10(oset_ptr, oset)) != 0) 392 return (err); 393 394 return (0); 395 } 396 397 /* 398 * Interposition upon SYS_sigsuspend 399 */ 400 int 401 s10_sigsuspend(sysret_t *rval, const sigset_t *set) 402 { 403 sigset_t sigset_set; 404 int err; 405 406 if ((err = s10sigset_to_native(set, &sigset_set)) != 0) { 407 (void) S10_TRUSS_POINT_1(rval, SYS_sigsuspend, err, set); 408 return (err); 409 } 410 411 return (__systemcall(rval, SYS_sigsuspend + 1024, &sigset_set)); 412 } 413 414 /* 415 * Interposition upon SYS_sigaction 416 * 417 * There is a fair amount of complexity here due to the need to interpose 418 * on any registered user signal handler. 419 * 420 * The idea is that if a user signal handler is installed, we must install 421 * our own signal handler between the system and the signal handler being 422 * registered. If the signal handler to be registered is SIG_DFL or SIG_IGN, 423 * we should remove our interpositioned handler as it's no longer needed. 424 * 425 * The way we do this is we set the signal handler to call s10_sigacthandler(), 426 * and then store the address of the passed signal handler in a global 427 * per-process array, s10_handlers[]. 428 * 429 * We rely on the fact that the s10 libc blocks all signals during 430 * its call to the sigaction() system call to guarantee atomicity. 431 */ 432 int 433 s10_sigaction(sysret_t *rval, 434 int sig, const struct sigaction *act, struct sigaction *oact) 435 { 436 struct sigaction sigact, osigact; 437 struct sigaction *sigactp, *osigactp; 438 int err, nativesig; 439 void (*handler)(); 440 441 if ((nativesig = s10sig_to_native(sig)) < 0) { 442 (void) S10_TRUSS_POINT_3(rval, SYS_sigaction, EINVAL, 443 sig, act, oact); 444 return (EINVAL); 445 } 446 447 if (act == NULL) { 448 sigactp = NULL; 449 } else { 450 sigactp = &sigact; 451 452 if (s10_uucopy(act, sigactp, sizeof (struct sigaction)) != 0) 453 return (EFAULT); 454 455 if ((err = s10sigset_to_native(&sigactp->sa_mask, 456 &sigactp->sa_mask)) != 0) { 457 (void) S10_TRUSS_POINT_3(rval, SYS_sigaction, err, 458 sig, act, oact); 459 return (err); 460 } 461 } 462 463 osigactp = ((oact == NULL) ? NULL : &osigact); 464 465 if (sigactp != NULL) { 466 handler = sigactp->sa_handler; 467 if (handler != SIG_DFL && handler != SIG_IGN) 468 sigactp->sa_handler = s10_sigacthandler; 469 } 470 471 if ((err = __systemcall(rval, SYS_sigaction + 1024, 472 nativesig, sigactp, osigactp)) != 0) 473 return (err); 474 475 /* 476 * Translate the old signal mask if we are supposed to return the old 477 * struct sigaction. 478 * 479 * Note that we may have set the signal handler, but may return EFAULT 480 * here if the oact parameter is bad. 481 * 482 * That's OK, because the direct system call acts the same way. 483 */ 484 if (osigactp != NULL) { 485 err = nativesigset_to_s10(&osigactp->sa_mask, 486 &osigactp->sa_mask); 487 488 if (osigactp->sa_handler == s10_sigacthandler) 489 osigactp->sa_handler = s10_handlers[sig - 1]; 490 491 if (err == 0 && 492 s10_uucopy(osigactp, oact, sizeof (struct sigaction)) != 0) 493 err = EFAULT; 494 } 495 496 /* 497 * Do not store SIG_DFL or SIG_IGN into the array of remembered 498 * signal handlers. Only store bona-fide function addresses. 499 * This is to avoid a race condition in which some thread 500 * sets the signal handler to SIG_DFL or SIG_IGN while some 501 * other thread is fielding the signal but has not yet reached 502 * s10_sigacthandler(). s10_sigacthandler() will unconditionally 503 * call the remembered signal handler and it it calls SIG_DFL or 504 * SIG_IGN, the process will incur a SIGSEGV or SIGBUS signal. 505 * This also allows a vfork() child to set signal handlers 506 * to SIG_DFL or SIG_IGN without corrupting the parent's 507 * address space. 508 */ 509 if (sigactp != NULL && 510 handler != SIG_DFL && handler != SIG_IGN) 511 s10_handlers[sig - 1] = handler; 512 513 return (err); 514 } 515 516 /* 517 * Interposition upon SYS_sigpending 518 */ 519 int 520 s10_sigpending(sysret_t *rval, int flag, sigset_t *set) 521 { 522 sigset_t sigset_set; 523 int err; 524 525 if ((err = __systemcall(rval, SYS_sigpending + 1024, 526 flag, &sigset_set)) != 0) 527 return (err); 528 529 if ((err = nativesigset_to_s10(&sigset_set, set)) != 0) 530 return (err); 531 532 return (0); 533 } 534 535 /* 536 * Interposition upon SYS_sigsendsys 537 */ 538 int 539 s10_sigsendsys(sysret_t *rval, procset_t *psp, int sig) 540 { 541 int nativesig; 542 543 if ((nativesig = s10sig_to_native(sig)) < 0) { 544 (void) S10_TRUSS_POINT_2(rval, SYS_sigsendsys, EINVAL, 545 psp, sig); 546 return (EINVAL); 547 } 548 549 return (__systemcall(rval, SYS_sigsendsys + 1024, psp, nativesig)); 550 } 551 552 /* 553 * Convert the siginfo_t code and status fields to an old style 554 * wait status for s10_wait(), below. 555 */ 556 static int 557 wstat(int code, int status) 558 { 559 int stat = (status & 0377); 560 561 switch (code) { 562 case CLD_EXITED: 563 stat <<= 8; 564 break; 565 case CLD_DUMPED: 566 stat |= WCOREFLG; 567 break; 568 case CLD_KILLED: 569 break; 570 case CLD_TRAPPED: 571 case CLD_STOPPED: 572 stat <<= 8; 573 stat |= WSTOPFLG; 574 break; 575 case CLD_CONTINUED: 576 stat = WCONTFLG; 577 break; 578 } 579 return (stat); 580 } 581 582 /* 583 * Interposition upon SYS_wait 584 */ 585 int 586 s10_wait(sysret_t *rval) 587 { 588 int err; 589 siginfo_t info; 590 591 err = s10_waitid(rval, P_ALL, 0, &info, WEXITED | WTRAPPED); 592 if (err != 0) 593 return (err); 594 595 rval->sys_rval1 = info.si_pid; 596 rval->sys_rval2 = wstat(info.si_code, info.si_status); 597 598 return (0); 599 } 600 601 /* 602 * Interposition upon SYS_waitid 603 */ 604 int 605 s10_waitid(sysret_t *rval, 606 idtype_t idtype, id_t id, siginfo_t *infop, int options) 607 { 608 int err, sig; 609 610 err = __systemcall(rval, SYS_waitid + 1024, idtype, id, infop, options); 611 if (err != 0) 612 return (err); 613 614 /* 615 * If the process being waited for terminated or stopped due to a 616 * signal, translate the signal number from its native value to its 617 * S10 equivalent. 618 * 619 * If we can't legally translate the signal number, just sort of punt 620 * and leave it untranslated. 621 * 622 * We shouldn't return EINVAL as the syscall didn't technically fail. 623 */ 624 if (infop->si_signo == SIGCLD && infop->si_code != CLD_EXITED && 625 (sig = nativesig_to_s10(infop->si_status)) > 0) 626 infop->si_status = sig; 627 628 return (0); 629 } 630 631 /* 632 * Interposition upon SYS_sigtimedwait 633 */ 634 int 635 s10_sigtimedwait(sysret_t *rval, 636 const sigset_t *set, siginfo_t *info, const timespec_t *timeout) 637 { 638 sigset_t sigset_set; 639 int err, sig; 640 641 if ((err = s10sigset_to_native(set, &sigset_set)) != 0) { 642 (void) S10_TRUSS_POINT_3(rval, SYS_sigtimedwait, err, 643 set, info, timeout); 644 return (err); 645 } 646 647 if ((err = __systemcall(rval, SYS_sigtimedwait + 1024, 648 &sigset_set, info, timeout)) != 0) 649 return (err); 650 651 if (info != NULL) { 652 /* 653 * If we can't legally translate the signal number in the 654 * siginfo_t, just sort of punt and leave it untranslated. 655 * 656 * We shouldn't return EINVAL as the syscall didn't technically 657 * fail. 658 */ 659 if ((sig = nativesig_to_s10(info->si_signo)) > 0) 660 info->si_signo = sig; 661 } 662 663 /* 664 * If we can't legally translate the signal number returned by the 665 * sigtimedwait syscall, just sort of punt and leave it untranslated. 666 * 667 * We shouldn't return EINVAL as the syscall didn't technically 668 * fail. 669 */ 670 if ((sig = nativesig_to_s10((int)rval->sys_rval1)) > 0) 671 rval->sys_rval1 = sig; 672 673 return (0); 674 } 675 676 /* 677 * Interposition upon SYS_sigqueue 678 */ 679 int 680 s10_sigqueue(sysret_t *rval, pid_t pid, int signo, void *value, int si_code) 681 { 682 int nativesig; 683 684 if ((nativesig = s10sig_to_native(signo)) < 0) { 685 (void) S10_TRUSS_POINT_4(rval, SYS_sigqueue, EINVAL, 686 pid, signo, value, si_code); 687 return (EINVAL); 688 } 689 690 if (pid == 1) 691 pid = zone_init_pid; 692 693 /* 694 * The native version of this syscall takes an extra argument. 695 * The new last arg "block" flag should be zero. The block flag 696 * is used by the Opensolaris AIO implementation, which is now 697 * part of libc. 698 */ 699 return (__systemcall(rval, SYS_sigqueue + 1024, 700 pid, nativesig, value, si_code, 0)); 701 } 702 703 /* 704 * Interposition upon SYS_signotify 705 */ 706 int 707 s10_signotify(sysret_t *rval, 708 int cmd, siginfo_t *siginfo, signotify_id_t *sn_id) 709 { 710 siginfo_t *infop, info; 711 712 infop = siginfo; 713 714 /* only check for a valid siginfo pointer in the case of SN_PROC */ 715 if (cmd == SN_PROC) { 716 int nativesig; 717 718 if (s10_uucopy(infop, &info, sizeof (siginfo_t)) != 0) 719 return (EFAULT); 720 721 if ((nativesig = s10sig_to_native(info.si_signo)) < 0) { 722 (void) S10_TRUSS_POINT_3(rval, SYS_signotify, EINVAL, 723 cmd, siginfo, sn_id); 724 return (EINVAL); 725 } 726 727 info.si_signo = nativesig; 728 infop = &info; 729 } 730 731 return (__systemcall(rval, SYS_signotify + 1024, cmd, infop, sn_id)); 732 } 733 734 /* 735 * Interposition upon SYS_kill 736 */ 737 int 738 s10_kill(sysret_t *rval, pid_t pid, int sig) 739 { 740 int nativesig; 741 742 if ((nativesig = s10sig_to_native(sig)) < 0) { 743 (void) S10_TRUSS_POINT_2(rval, SYS_kill, EINVAL, pid, sig); 744 return (EINVAL); 745 } 746 747 if (pid == 1) 748 pid = zone_init_pid; 749 750 return (__systemcall(rval, SYS_kill + 1024, pid, nativesig)); 751 } 752 753 /* 754 * Interposition upon SYS_lwp_create 755 * 756 * See also the s10_lwp_create_correct_fs() function in s10_brand.c 757 * for the special case of creating an lwp in a 64-bit x86 process. 758 */ 759 int 760 s10_lwp_create(sysret_t *rval, ucontext_t *ucp, int flags, id_t *new_lwp) 761 { 762 ucontext_t s10_uc; 763 764 if (s10_uucopy(ucp, &s10_uc, sizeof (ucontext_t)) != 0) 765 return (EFAULT); 766 767 if (s10_uc.uc_flags & UC_SIGMASK) 768 (void) s10sigset_to_native(&s10_uc.uc_sigmask, 769 &s10_uc.uc_sigmask); 770 771 return (__systemcall(rval, SYS_lwp_create + 1024, 772 &s10_uc, flags, new_lwp)); 773 } 774 775 /* 776 * Interposition upon SYS_lwp_kill 777 */ 778 int 779 s10_lwp_kill(sysret_t *rval, id_t lwpid, int sig) 780 { 781 int nativesig; 782 783 if ((nativesig = s10sig_to_native(sig)) < 0) { 784 (void) S10_TRUSS_POINT_2(rval, SYS_lwp_kill, EINVAL, 785 lwpid, sig); 786 return (EINVAL); 787 } 788 789 return (__systemcall(rval, SYS_lwp_kill + 1024, lwpid, nativesig)); 790 } 791