1 /* $NetBSD: svr4_32_signal.c,v 1.25 2008/04/24 18:39:23 ad Exp $ */
4 * Copyright (c) 1994, 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas and by Charles M. Hannum.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: svr4_32_signal.c,v 1.25 2008/04/24 18:39:23 ad Exp $");
35 #if defined(_KERNEL_OPT)
36 #include "opt_compat_svr4.h"
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/namei.h>
43 #include <sys/filedesc.h>
44 #include <sys/ioctl.h>
45 #include <sys/mount.h>
46 #include <sys/kernel.h>
47 #include <sys/signal.h>
48 #include <sys/signalvar.h>
49 #include <sys/malloc.h>
52 #include <sys/syscallargs.h>
54 #include <compat/svr4_32/svr4_32_types.h>
55 #include <compat/svr4_32/svr4_32_signal.h>
56 #include <compat/svr4_32/svr4_32_lwp.h>
57 #include <compat/svr4_32/svr4_32_ucontext.h>
58 #include <compat/svr4_32/svr4_32_syscallargs.h>
59 #include <compat/svr4_32/svr4_32_util.h>
61 #include <compat/common/compat_sigaltstack.h>
63 #define svr4_sigmask(n) (1 << (((n) - 1) & 31))
64 #define svr4_sigword(n) (((n) - 1) >> 5)
65 #define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s)))
66 #define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
67 #define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
69 static inline void svr4_32_sigfillset(svr4_32_sigset_t
*);
70 void svr4_32_to_native_sigaction(const struct svr4_32_sigaction
*,
72 void native_to_svr4_32_sigaction(const struct sigaction
*,
73 struct svr4_32_sigaction
*);
76 const int native_to_svr4_signo
[NSIG
] = {
88 SVR4_SIGSEGV
, /* 11 */
90 SVR4_SIGPIPE
, /* 13 */
91 SVR4_SIGALRM
, /* 14 */
92 SVR4_SIGTERM
, /* 15 */
94 SVR4_SIGSTOP
, /* 17 */
95 SVR4_SIGTSTP
, /* 18 */
96 SVR4_SIGCONT
, /* 19 */
97 SVR4_SIGCHLD
, /* 20 */
98 SVR4_SIGTTIN
, /* 21 */
99 SVR4_SIGTTOU
, /* 22 */
101 SVR4_SIGXCPU
, /* 24 */
102 SVR4_SIGXFSZ
, /* 25 */
103 SVR4_SIGVTALRM
, /* 26 */
104 SVR4_SIGPROF
, /* 27 */
105 SVR4_SIGWINCH
, /* 28 */
107 SVR4_SIGUSR1
, /* 30 */
108 SVR4_SIGUSR2
, /* 31 */
109 SVR4_SIGPWR
, /* 32 */
110 SVR4_SIGRTMIN
+ 0, /* 33 */
111 SVR4_SIGRTMIN
+ 1, /* 34 */
112 SVR4_SIGRTMIN
+ 2, /* 35 */
113 SVR4_SIGRTMIN
+ 3, /* 36 */
114 SVR4_SIGRTMIN
+ 4, /* 37 */
115 SVR4_SIGRTMIN
+ 5, /* 38 */
116 SVR4_SIGRTMIN
+ 6, /* 39 */
117 SVR4_SIGRTMIN
+ 7, /* 40 */
118 SVR4_SIGRTMIN
+ 8, /* 41 */
119 SVR4_SIGRTMIN
+ 9, /* 42 */
120 SVR4_SIGRTMIN
+ 10, /* 43 */
121 SVR4_SIGRTMIN
+ 11, /* 44 */
122 SVR4_SIGRTMIN
+ 12, /* 45 */
123 SVR4_SIGRTMIN
+ 13, /* 46 */
124 SVR4_SIGRTMIN
+ 14, /* 47 */
125 SVR4_SIGRTMIN
+ 15, /* 48 */
126 SVR4_SIGRTMIN
+ 16, /* 49 */
127 SVR4_SIGRTMIN
+ 17, /* 50 */
128 SVR4_SIGRTMIN
+ 18, /* 51 */
129 SVR4_SIGRTMIN
+ 19, /* 52 */
130 SVR4_SIGRTMIN
+ 20, /* 53 */
131 SVR4_SIGRTMIN
+ 21, /* 54 */
132 SVR4_SIGRTMIN
+ 22, /* 55 */
133 SVR4_SIGRTMIN
+ 23, /* 56 */
134 SVR4_SIGRTMIN
+ 24, /* 57 */
135 SVR4_SIGRTMIN
+ 25, /* 58 */
136 SVR4_SIGRTMIN
+ 26, /* 59 */
137 SVR4_SIGRTMIN
+ 27, /* 60 */
138 SVR4_SIGRTMIN
+ 28, /* 61 */
139 SVR4_SIGRTMIN
+ 29, /* 62 */
140 SVR4_SIGRTMIN
+ 30, /* 63 */
143 const int svr4_to_native_signo
[SVR4_NSIG
] = {
176 SIGRTMIN
+ 0, /* 32 */
177 SIGRTMIN
+ 1, /* 33 */
178 SIGRTMIN
+ 2, /* 34 */
179 SIGRTMIN
+ 3, /* 35 */
180 SIGRTMIN
+ 4, /* 36 */
181 SIGRTMIN
+ 5, /* 37 */
182 SIGRTMIN
+ 6, /* 38 */
183 SIGRTMIN
+ 7, /* 39 */
184 SIGRTMIN
+ 8, /* 40 */
185 SIGRTMIN
+ 9, /* 41 */
186 SIGRTMIN
+ 10, /* 42 */
187 SIGRTMIN
+ 11, /* 43 */
188 SIGRTMIN
+ 12, /* 44 */
189 SIGRTMIN
+ 13, /* 45 */
190 SIGRTMIN
+ 14, /* 46 */
191 SIGRTMIN
+ 15, /* 47 */
192 SIGRTMIN
+ 16, /* 48 */
193 SIGRTMIN
+ 17, /* 49 */
194 SIGRTMIN
+ 18, /* 50 */
195 SIGRTMIN
+ 19, /* 51 */
196 SIGRTMIN
+ 20, /* 52 */
197 SIGRTMIN
+ 21, /* 53 */
198 SIGRTMIN
+ 22, /* 54 */
199 SIGRTMIN
+ 23, /* 55 */
200 SIGRTMIN
+ 24, /* 56 */
201 SIGRTMIN
+ 25, /* 57 */
202 SIGRTMIN
+ 26, /* 58 */
203 SIGRTMIN
+ 27, /* 59 */
204 SIGRTMIN
+ 28, /* 60 */
205 SIGRTMIN
+ 29, /* 61 */
206 SIGRTMIN
+ 30, /* 62 */
212 svr4_32_sigfillset(svr4_32_sigset_t
*s
)
217 for (i
= 1; i
< SVR4_NSIG
; i
++)
218 if (svr4_to_native_signo
[i
] != 0)
219 svr4_sigaddset(s
, i
);
223 svr4_32_to_native_sigset(const svr4_32_sigset_t
*sss
, sigset_t
*bss
)
228 for (i
= 1; i
< SVR4_NSIG
; i
++) {
229 if (svr4_sigismember(sss
, i
)) {
230 newsig
= svr4_to_native_signo
[i
];
232 sigaddset(bss
, newsig
);
239 native_to_svr4_32_sigset(const sigset_t
*bss
, svr4_32_sigset_t
*sss
)
243 svr4_sigemptyset(sss
);
244 for (i
= 1; i
< NSIG
; i
++) {
245 if (sigismember(bss
, i
)) {
246 newsig
= native_to_svr4_signo
[i
];
248 svr4_sigaddset(sss
, newsig
);
254 * XXX: Only a subset of the flags is currently implemented.
257 svr4_32_to_native_sigaction(const struct svr4_32_sigaction
*ssa
, struct sigaction
*bsa
)
260 bsa
->sa_handler
= NETBSD32PTR64(ssa
->svr4_32_sa_handler
);
261 svr4_32_to_native_sigset(&ssa
->svr4_32_sa_mask
, &bsa
->sa_mask
);
263 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_ONSTACK
) != 0)
264 bsa
->sa_flags
|= SA_ONSTACK
;
265 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_RESETHAND
) != 0)
266 bsa
->sa_flags
|= SA_RESETHAND
;
267 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_RESTART
) != 0)
268 bsa
->sa_flags
|= SA_RESTART
;
269 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_SIGINFO
) != 0) {
270 DPRINTF(("svr4_to_native_sigaction: SA_SIGINFO ignored\n"));
272 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_NODEFER
) != 0)
273 bsa
->sa_flags
|= SA_NODEFER
;
274 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_NOCLDWAIT
) != 0)
275 bsa
->sa_flags
|= SA_NOCLDWAIT
;
276 if ((ssa
->svr4_32_sa_flags
& SVR4_SA_NOCLDSTOP
) != 0)
277 bsa
->sa_flags
|= SA_NOCLDSTOP
;
278 if ((ssa
->svr4_32_sa_flags
& ~SVR4_SA_ALLBITS
) != 0) {
279 DPRINTF(("svr4_32_to_native_sigaction: extra bits %x ignored\n",
280 ssa
->svr4_32_sa_flags
& ~SVR4_SA_ALLBITS
));
285 native_to_svr4_32_sigaction(const struct sigaction
*bsa
, struct svr4_32_sigaction
*ssa
)
288 NETBSD32PTR32(ssa
->svr4_32_sa_handler
, bsa
->sa_handler
);
289 native_to_svr4_32_sigset(&bsa
->sa_mask
, &ssa
->svr4_32_sa_mask
);
290 ssa
->svr4_32_sa_flags
= 0;
291 if ((bsa
->sa_flags
& SA_ONSTACK
) != 0)
292 ssa
->svr4_32_sa_flags
|= SVR4_SA_ONSTACK
;
293 if ((bsa
->sa_flags
& SA_RESETHAND
) != 0)
294 ssa
->svr4_32_sa_flags
|= SVR4_SA_RESETHAND
;
295 if ((bsa
->sa_flags
& SA_RESTART
) != 0)
296 ssa
->svr4_32_sa_flags
|= SVR4_SA_RESTART
;
297 if ((bsa
->sa_flags
& SA_NODEFER
) != 0)
298 ssa
->svr4_32_sa_flags
|= SVR4_SA_NODEFER
;
299 if ((bsa
->sa_flags
& SA_NOCLDSTOP
) != 0)
300 ssa
->svr4_32_sa_flags
|= SVR4_SA_NOCLDSTOP
;
304 svr4_32_sys_sigaction(struct lwp
*l
, const struct svr4_32_sys_sigaction_args
*uap
, register_t
*retval
)
307 syscallarg(int) signum;
308 syscallarg(const struct svr4_32_sigaction *) nsa;
309 syscallarg(struct svr4_32_sigaction *) osa;
311 struct svr4_32_sigaction nssa
, ossa
;
312 struct sigaction nbsa
, obsa
;
315 if (SCARG_P32(uap
, nsa
)) {
316 error
= copyin(SCARG_P32(uap
, nsa
),
317 &nssa
, sizeof(nssa
));
320 svr4_32_to_native_sigaction(&nssa
, &nbsa
);
322 error
= sigaction1(l
,
323 svr4_to_native_signo
[SVR4_SIGNO(SCARG(uap
, signum
))],
324 SCARG_P32(uap
, nsa
) ? &nbsa
: 0, SCARG_P32(uap
, osa
) ? &obsa
: 0,
328 if (SCARG_P32(uap
, osa
)) {
329 native_to_svr4_32_sigaction(&obsa
, &ossa
);
330 error
= copyout(&ossa
, SCARG_P32(uap
, osa
),
339 svr4_32_sys_sigaltstack(struct lwp
*l
, const struct svr4_32_sys_sigaltstack_args
*uap
, register_t
*retval
)
342 syscallarg(const struct svr4_32_sigaltstack_tp) nss;
343 syscallarg(struct svr4_32_sigaltstack_tp) oss;
345 compat_sigaltstack(uap
, svr4_32_sigaltstack
,
346 SVR4_SS_ONSTACK
, SVR4_SS_DISABLE
);
350 * Stolen from the ibcs2 one
353 svr4_32_sys_signal(struct lwp
*l
, const struct svr4_32_sys_signal_args
*uap
, register_t
*retval
)
356 syscallarg(int) signum;
357 syscallarg(svr4_32_sig_t) handler;
359 struct proc
*p
= l
->l_proc
;
360 int signum
= svr4_to_native_signo
[SVR4_SIGNO(SCARG(uap
, signum
))];
361 struct sigaction nbsa
, obsa
;
365 if (signum
<= 0 || signum
>= SVR4_NSIG
)
368 switch (SVR4_SIGCALL(SCARG(uap
, signum
))) {
369 case SVR4_SIGDEFER_MASK
:
370 if (SCARG(uap
, handler
) == SVR4_SIG_HOLD
)
374 case SVR4_SIGNAL_MASK
:
375 nbsa
.sa_handler
= (sig_t
)SCARG(uap
, handler
);
376 sigemptyset(&nbsa
.sa_mask
);
378 error
= sigaction1(l
, signum
, &nbsa
, &obsa
, NULL
, 0);
381 *retval
= (u_int
)(u_long
)obsa
.sa_handler
;
384 case SVR4_SIGHOLD_MASK
:
387 sigaddset(&ss
, signum
);
388 mutex_enter(p
->p_lock
);
389 error
= sigprocmask1(l
, SIG_BLOCK
, &ss
, 0);
390 mutex_exit(p
->p_lock
);
393 case SVR4_SIGRELSE_MASK
:
395 sigaddset(&ss
, signum
);
396 mutex_enter(p
->p_lock
);
397 error
= sigprocmask1(l
, SIG_UNBLOCK
, &ss
, 0);
398 mutex_exit(p
->p_lock
);
401 case SVR4_SIGIGNORE_MASK
:
402 nbsa
.sa_handler
= SIG_IGN
;
403 sigemptyset(&nbsa
.sa_mask
);
405 return (sigaction1(l
, signum
, &nbsa
, 0, NULL
, 0));
407 case SVR4_SIGPAUSE_MASK
:
408 mutex_enter(p
->p_lock
);
410 mutex_exit(p
->p_lock
);
411 sigdelset(&ss
, signum
);
412 return (sigsuspend1(l
, &ss
));
420 svr4_32_sys_sigprocmask(struct lwp
*l
, const struct svr4_32_sys_sigprocmask_args
*uap
, register_t
*retval
)
424 syscallarg(const svr4_32_sigset_t *) set;
425 syscallarg(svr4_32_sigset_t *) oset;
427 struct proc
*p
= l
->l_proc
;
428 svr4_32_sigset_t nsss
, osss
;
434 * Initialize how to 0 to avoid a compiler warning. Note that
435 * this is safe because of the check in the default: case.
439 switch (SCARG(uap
, how
)) {
443 case SVR4_SIG_UNBLOCK
:
446 case SVR4_SIG_SETMASK
:
450 if (SCARG_P32(uap
, set
))
455 if (SCARG_P32(uap
, set
)) {
456 error
= copyin(SCARG_P32(uap
, set
),
457 &nsss
, sizeof(nsss
));
460 svr4_32_to_native_sigset(&nsss
, &nbss
);
462 mutex_enter(p
->p_lock
);
463 error
= sigprocmask1(l
, how
,
464 SCARG_P32(uap
, set
) ? &nbss
: NULL
, SCARG_P32(uap
, oset
) ? &obss
: NULL
);
465 mutex_exit(p
->p_lock
);
468 if (SCARG_P32(uap
, oset
)) {
469 native_to_svr4_32_sigset(&obss
, &osss
);
470 error
= copyout(&osss
, SCARG_P32(uap
, oset
),
479 svr4_32_sys_sigpending(struct lwp
*l
, const struct svr4_32_sys_sigpending_args
*uap
, register_t
*retval
)
482 syscallarg(int) what;
483 syscallarg(svr4_sigset_t *) set;
486 svr4_32_sigset_t sss
;
488 switch (SCARG(uap
, what
)) {
489 case 1: /* sigpending */
490 sigpending1(l
, &bss
);
491 native_to_svr4_32_sigset(&bss
, &sss
);
494 case 2: /* sigfillset */
495 svr4_32_sigfillset(&sss
);
501 return (copyout(&sss
, SCARG_P32(uap
, set
), sizeof(sss
)));
505 svr4_32_sys_sigsuspend(struct lwp
*l
, const struct svr4_32_sys_sigsuspend_args
*uap
, register_t
*retval
)
508 syscallarg(const svr4_32_sigset_t *) set;
510 svr4_32_sigset_t sss
;
514 if (SCARG_P32(uap
, set
)) {
515 error
= copyin(SCARG_P32(uap
, set
), &sss
, sizeof(sss
));
518 svr4_32_to_native_sigset(&sss
, &bss
);
521 return (sigsuspend1(l
, SCARG_P32(uap
, set
) ? &bss
: 0));
525 svr4_32_sys_pause(struct lwp
*l
, const void *v
, register_t
*retval
)
528 return (sigsuspend1(l
, 0));
532 svr4_32_sys_kill(struct lwp
*l
, const struct svr4_32_sys_kill_args
*uap
, register_t
*retval
)
536 syscallarg(int) signum;
538 struct sys_kill_args ka
;
540 SCARG(&ka
, pid
) = SCARG(uap
, pid
);
541 SCARG(&ka
, signum
) = svr4_to_native_signo
[SVR4_SIGNO(SCARG(uap
, signum
))];
542 return sys_kill(l
, &ka
, retval
);
546 svr4_32_getcontext(struct lwp
*l
, struct svr4_32_ucontext
*uc
, const sigset_t
*mask
)
549 struct svr4_32_sigaltstack
*ss
= &uc
->uc_stack
;
551 memset(uc
, 0, sizeof(*uc
));
553 /* get machine context */
554 sp
= svr4_32_getmcontext(l
, &uc
->uc_mcontext
, &uc
->uc_flags
);
557 NETBSD32PTR32(uc
->uc_link
, l
->l_ctxlink
);
559 /* get stack state. XXX: solaris appears to do this */
561 svr4_32_to_native_sigaltstack(&uc
->uc_stack
, &p
->p_sigacts
->ps_sigstk
);
563 NETBSD32PTR32(ss
->ss_sp
, (void *)(((u_long
) sp
) & ~(16384 - 1)));
567 /* get signal mask */
568 mutex_enter(l
->l_proc
->p_lock
);
569 native_to_svr4_32_sigset(mask
, &uc
->uc_sigmask
);
570 mutex_exit(l
->l_proc
->p_lock
);
572 uc
->uc_flags
|= SVR4_UC_STACK
|SVR4_UC_SIGMASK
;
577 svr4_32_setcontext(struct lwp
*l
, struct svr4_32_ucontext
*uc
)
580 struct proc
*p
= l
->l_proc
;
582 /* set machine context */
583 if ((error
= svr4_32_setmcontext(l
, &uc
->uc_mcontext
, uc
->uc_flags
)) != 0)
587 l
->l_ctxlink
= NETBSD32PTR64(uc
->uc_link
);
589 mutex_enter(p
->p_lock
);
591 /* set signal stack */
592 if (uc
->uc_flags
& SVR4_UC_STACK
) {
593 l
->l_sigstk
.ss_sp
= NETBSD32PTR64(uc
->uc_stack
.ss_sp
);
594 l
->l_sigstk
.ss_size
= uc
->uc_stack
.ss_size
;
595 l
->l_sigstk
.ss_flags
=
596 (uc
->uc_stack
.ss_flags
& SVR4_SS_ONSTACK
? SS_ONSTACK
: 0) |
597 (uc
->uc_stack
.ss_flags
& SVR4_SS_DISABLE
? SS_DISABLE
: 0);
600 /* set signal mask */
601 if (uc
->uc_flags
& SVR4_UC_SIGMASK
) {
604 svr4_32_to_native_sigset(&uc
->uc_sigmask
, &mask
);
605 (void)sigprocmask1(l
, SIG_SETMASK
, &mask
, 0);
608 mutex_exit(p
->p_lock
);
614 svr4_32_sys_context(struct lwp
*l
, const struct svr4_32_sys_context_args
*uap
, register_t
*retval
)
617 syscallarg(int) func;
618 syscallarg(struct svr4_32_ucontext *) uc;
620 struct svr4_32_ucontext uc
;
624 switch (SCARG(uap
, func
)) {
625 case SVR4_GETCONTEXT
:
626 DPRINTF(("getcontext(%p)\n", SCARG(uap
, uc
)));
627 svr4_32_getcontext(l
, &uc
, &l
->l_sigmask
);
628 return copyout(&uc
, SCARG_P32(uap
, uc
), sizeof(uc
));
630 case SVR4_SETCONTEXT
:
631 DPRINTF(("setcontext(%p)\n", SCARG(uap
, uc
)));
632 if (!SCARG_P32(uap
, uc
))
633 exit1(l
, W_EXITCODE(0, 0));
634 else if ((error
= copyin(SCARG_P32(uap
, uc
),
635 &uc
, sizeof(uc
))) != 0)
638 return svr4_32_setcontext(l
, &uc
);
641 DPRINTF(("context(%d, %p)\n", SCARG(uap
, func
),