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
native_sigrtmin()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
native_sigrtmax()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
s10sig_to_native(int sig)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
s10sigset_to_native(const sigset_t * s10_set,sigset_t * native_set)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
nativesig_to_s10(int sig)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
nativesigset_to_s10(const sigset_t * native_set,sigset_t * s10_set)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
s10_sigacthandler(int sig,siginfo_t * sip,void * uvp)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
s10_lwp_sigmask(sysret_t * rval,int how,uint_t bits0,uint_t bits1)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
s10_sigprocmask(sysret_t * rval,int how,const sigset_t * set,sigset_t * oset)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
s10_sigsuspend(sysret_t * rval,const sigset_t * set)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
s10_sigaction(sysret_t * rval,int sig,const struct sigaction * act,struct sigaction * oact)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
s10_sigpending(sysret_t * rval,int flag,sigset_t * set)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
s10_sigsendsys(sysret_t * rval,procset_t * psp,int sig)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
wstat(int code,int status)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
s10_wait(sysret_t * rval)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
s10_waitid(sysret_t * rval,idtype_t idtype,id_t id,siginfo_t * infop,int options)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
s10_sigtimedwait(sysret_t * rval,const sigset_t * set,siginfo_t * info,const timespec_t * timeout)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
s10_sigqueue(sysret_t * rval,pid_t pid,int signo,void * value,int si_code)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
s10_signotify(sysret_t * rval,int cmd,siginfo_t * siginfo,signotify_id_t * sn_id)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
s10_kill(sysret_t * rval,pid_t pid,int sig)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
s10_lwp_create(sysret_t * rval,ucontext_t * ucp,int flags,id_t * new_lwp)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
s10_lwp_kill(sysret_t * rval,id_t lwpid,int sig)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