1 /* $NetBSD: netbsd32_signal.c,v 1.31.8.1 2009/01/04 01:56:02 christos Exp $ */
4 * Copyright (c) 1998, 2001 Matthew R. Green
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.31.8.1 2009/01/04 01:56:02 christos Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/mount.h>
38 #include <sys/signalvar.h>
41 #include <sys/savar.h>
43 #include <sys/dirent.h>
45 #include <uvm/uvm_extern.h>
47 #include <compat/netbsd32/netbsd32.h>
48 #include <compat/netbsd32/netbsd32_conv.h>
49 #include <compat/netbsd32/netbsd32_syscallargs.h>
50 #include <compat/netbsd32/netbsd32_sa.h>
52 #include <compat/sys/signal.h>
53 #include <compat/sys/signalvar.h>
54 #include <compat/sys/siginfo.h>
55 #include <compat/sys/ucontext.h>
56 #include <compat/common/compat_sigaltstack.h>
59 static void netbsd32_si32_to_si(siginfo_t
*, const siginfo32_t
*);
64 netbsd32_sigaction(struct lwp
*l
, const struct netbsd32_sigaction_args
*uap
, register_t
*retval
)
67 syscallarg(int) signum;
68 syscallarg(const netbsd32_sigactionp_t) nsa;
69 syscallarg(netbsd32_sigactionp_t) osa;
71 struct sigaction nsa
, osa
;
72 struct netbsd32_sigaction
*sa32p
, sa32
;
75 if (SCARG_P32(uap
, nsa
)) {
76 sa32p
= SCARG_P32(uap
, nsa
);
77 if (copyin(sa32p
, &sa32
, sizeof(sa32
)))
79 nsa
.sa_handler
= (void *)NETBSD32PTR64(sa32
.netbsd32_sa_handler
);
80 nsa
.sa_mask
= sa32
.netbsd32_sa_mask
;
81 nsa
.sa_flags
= sa32
.netbsd32_sa_flags
;
83 error
= sigaction1(l
, SCARG(uap
, signum
),
84 SCARG_P32(uap
, nsa
) ? &nsa
: 0,
85 SCARG_P32(uap
, osa
) ? &osa
: 0,
91 if (SCARG_P32(uap
, osa
)) {
92 NETBSD32PTR32(sa32
.netbsd32_sa_handler
, osa
.sa_handler
);
93 sa32
.netbsd32_sa_mask
= osa
.sa_mask
;
94 sa32
.netbsd32_sa_flags
= osa
.sa_flags
;
95 sa32p
= SCARG_P32(uap
, osa
);
96 if (copyout(&sa32
, sa32p
, sizeof(sa32
)))
104 netbsd32___sigaltstack14(struct lwp
*l
, const struct netbsd32___sigaltstack14_args
*uap
, register_t
*retval
)
107 syscallarg(const netbsd32_sigaltstackp_t) nss;
108 syscallarg(netbsd32_sigaltstackp_t) oss;
110 compat_sigaltstack(uap
, netbsd32_sigaltstack
, SS_ONSTACK
, SS_DISABLE
);
115 netbsd32___sigaction14(struct lwp
*l
, const struct netbsd32___sigaction14_args
*uap
, register_t
*retval
)
118 syscallarg(int) signum;
119 syscallarg(const struct sigaction *) nsa;
120 syscallarg(struct sigaction *) osa;
122 struct netbsd32_sigaction sa32
;
123 struct sigaction nsa
, osa
;
126 if (SCARG_P32(uap
, nsa
)) {
127 error
= copyin(SCARG_P32(uap
, nsa
), &sa32
, sizeof(sa32
));
130 nsa
.sa_handler
= NETBSD32PTR64(sa32
.netbsd32_sa_handler
);
131 nsa
.sa_mask
= sa32
.netbsd32_sa_mask
;
132 nsa
.sa_flags
= sa32
.netbsd32_sa_flags
;
134 error
= sigaction1(l
, SCARG(uap
, signum
),
135 SCARG_P32(uap
, nsa
) ? &nsa
: 0,
136 SCARG_P32(uap
, osa
) ? &osa
: 0,
140 if (SCARG_P32(uap
, osa
)) {
141 NETBSD32PTR32(sa32
.netbsd32_sa_handler
, osa
.sa_handler
);
142 sa32
.netbsd32_sa_mask
= osa
.sa_mask
;
143 sa32
.netbsd32_sa_flags
= osa
.sa_flags
;
144 error
= copyout(&sa32
, SCARG_P32(uap
, osa
), sizeof(sa32
));
153 netbsd32___sigaction_sigtramp(struct lwp
*l
, const struct netbsd32___sigaction_sigtramp_args
*uap
, register_t
*retval
)
156 syscallarg(int) signum;
157 syscallarg(const netbsd32_sigactionp_t) nsa;
158 syscallarg(netbsd32_sigactionp_t) osa;
159 syscallarg(netbsd32_voidp) tramp;
160 syscallarg(int) vers;
162 struct netbsd32_sigaction sa32
;
163 struct sigaction nsa
, osa
;
166 if (SCARG_P32(uap
, nsa
)) {
167 error
= copyin(SCARG_P32(uap
, nsa
), &sa32
, sizeof(sa32
));
170 nsa
.sa_handler
= NETBSD32PTR64(sa32
.netbsd32_sa_handler
);
171 nsa
.sa_mask
= sa32
.netbsd32_sa_mask
;
172 nsa
.sa_flags
= sa32
.netbsd32_sa_flags
;
174 error
= sigaction1(l
, SCARG(uap
, signum
),
175 SCARG_P32(uap
, nsa
) ? &nsa
: 0,
176 SCARG_P32(uap
, osa
) ? &osa
: 0,
177 SCARG_P32(uap
, tramp
), SCARG(uap
, vers
));
180 if (SCARG_P32(uap
, osa
)) {
181 NETBSD32PTR32(sa32
.netbsd32_sa_handler
, osa
.sa_handler
);
182 sa32
.netbsd32_sa_mask
= osa
.sa_mask
;
183 sa32
.netbsd32_sa_flags
= osa
.sa_flags
;
184 error
= copyout(&sa32
, SCARG_P32(uap
, osa
), sizeof(sa32
));
193 netbsd32_si32_to_si(siginfo_t
*si
, const siginfo32_t
*si32
)
195 memset(si
, 0, sizeof (*si
));
196 si
->si_signo
= si32
->si_signo
;
197 si
->si_code
= si32
->si_code
;
198 si
->si_errno
= si32
->si_errno
;
200 switch (si32
->si_signo
) {
206 si
->si_addr
= NETBSD32PTR64(si32
->si_addr
);
207 si
->si_trap
= si32
->si_trap
;
212 si
->si_pid
= si32
->si_pid
;
213 si
->si_uid
= si32
->si_uid
;
215 * XXX sival_ptr is currently unused.
217 si
->si_value
.sival_int
= si32
->si_value
.sival_int
;
220 si
->si_pid
= si32
->si_pid
;
221 si
->si_uid
= si32
->si_uid
;
222 si
->si_utime
= si32
->si_utime
;
223 si
->si_stime
= si32
->si_stime
;
227 si
->si_band
= si32
->si_band
;
228 si
->si_fd
= si32
->si_fd
;
235 netbsd32_si_to_si32(siginfo32_t
*si32
, const siginfo_t
*si
)
237 memset(si32
, 0, sizeof (*si32
));
238 si32
->si_signo
= si
->si_signo
;
239 si32
->si_code
= si
->si_code
;
240 si32
->si_errno
= si
->si_errno
;
242 switch (si32
->si_signo
) {
244 si32
->si_value
.sival_int
= si
->si_value
.sival_int
;
251 si32
->si_addr
= (uint32_t)(uintptr_t)si
->si_addr
;
252 si32
->si_trap
= si
->si_trap
;
257 si32
->si_pid
= si
->si_pid
;
258 si32
->si_uid
= si
->si_uid
;
260 * XXX sival_ptr is currently unused.
262 si32
->si_value
.sival_int
= si
->si_value
.sival_int
;
265 si32
->si_pid
= si
->si_pid
;
266 si32
->si_uid
= si
->si_uid
;
267 si32
->si_status
= si
->si_status
;
268 si32
->si_utime
= si
->si_utime
;
269 si32
->si_stime
= si
->si_stime
;
273 si32
->si_band
= si
->si_band
;
274 si32
->si_fd
= si
->si_fd
;
280 getucontext32(struct lwp
*l
, ucontext32_t
*ucp
)
282 struct proc
*p
= l
->l_proc
;
284 KASSERT(mutex_owned(p
->p_lock
));
287 ucp
->uc_link
= (uint32_t)(intptr_t)l
->l_ctxlink
;
290 ucp
->uc_sigmask
= p
->p_sa
->sa_sigmask
;
292 ucp
->uc_sigmask
= l
->l_sigmask
;
293 ucp
->uc_flags
|= _UC_SIGMASK
;
296 * The (unsupplied) definition of the `current execution stack'
297 * in the System V Interface Definition appears to allow returning
298 * the main context stack.
300 if ((l
->l_sigstk
.ss_flags
& SS_ONSTACK
) == 0) {
301 ucp
->uc_stack
.ss_sp
= USRSTACK32
;
302 ucp
->uc_stack
.ss_size
= ctob(p
->p_vmspace
->vm_ssize
);
303 ucp
->uc_stack
.ss_flags
= 0; /* XXX, def. is Very Fishy */
305 /* Simply copy alternate signal execution stack. */
306 ucp
->uc_stack
.ss_sp
=
307 (uint32_t)(intptr_t)l
->l_sigstk
.ss_sp
;
308 ucp
->uc_stack
.ss_size
= l
->l_sigstk
.ss_size
;
309 ucp
->uc_stack
.ss_flags
= l
->l_sigstk
.ss_flags
;
311 ucp
->uc_flags
|= _UC_STACK
;
312 mutex_exit(p
->p_lock
);
313 cpu_getmcontext32(l
, &ucp
->uc_mcontext
, &ucp
->uc_flags
);
314 mutex_enter(p
->p_lock
);
319 * Get a ucontext32_t for use in SA upcall generation.
320 * Tweaked version of getucontext32. We 1) do not take p_lock, 2)
321 * fudge things with uc_link (which is usually NULL for libpthread
322 * code), and 3) we report an empty signal mask.
325 getucontext32_sa(struct lwp
*l
, ucontext32_t
*ucp
)
327 struct proc
*p
= l
->l_proc
;
330 ucp
->uc_link
= (uint32_t)(intptr_t)l
->l_ctxlink
;
332 sigemptyset(&ucp
->uc_sigmask
);
333 ucp
->uc_flags
|= _UC_SIGMASK
;
336 * The (unsupplied) definition of the `current execution stack'
337 * in the System V Interface Definition appears to allow returning
338 * the main context stack.
340 if ((l
->l_sigstk
.ss_flags
& SS_ONSTACK
) == 0) {
341 ucp
->uc_stack
.ss_sp
= USRSTACK32
;
342 ucp
->uc_stack
.ss_size
= ctob(p
->p_vmspace
->vm_ssize
);
343 ucp
->uc_stack
.ss_flags
= 0; /* XXX, def. is Very Fishy */
345 /* Simply copy alternate signal execution stack. */
346 ucp
->uc_stack
.ss_sp
=
347 (uint32_t)(intptr_t)l
->l_sigstk
.ss_sp
;
348 ucp
->uc_stack
.ss_size
= l
->l_sigstk
.ss_size
;
349 ucp
->uc_stack
.ss_flags
= l
->l_sigstk
.ss_flags
;
351 ucp
->uc_flags
|= _UC_STACK
;
352 cpu_getmcontext32(l
, &ucp
->uc_mcontext
, &ucp
->uc_flags
);
357 netbsd32_getcontext(struct lwp
*l
, const struct netbsd32_getcontext_args
*uap
, register_t
*retval
)
360 syscallarg(netbsd32_ucontextp) ucp;
362 struct proc
*p
= l
->l_proc
;
365 mutex_enter(p
->p_lock
);
366 getucontext32(l
, &uc
);
367 mutex_exit(p
->p_lock
);
369 return copyout(&uc
, SCARG_P32(uap
, ucp
), sizeof (ucontext32_t
));
373 setucontext32(struct lwp
*l
, const ucontext32_t
*ucp
)
375 struct proc
*p
= l
->l_proc
;
378 KASSERT(mutex_owned(p
->p_lock
));
380 if ((ucp
->uc_flags
& _UC_SIGMASK
) != 0) {
381 error
= sigprocmask1(l
, SIG_SETMASK
, &ucp
->uc_sigmask
, NULL
);
386 mutex_exit(p
->p_lock
);
387 error
= cpu_setmcontext32(l
, &ucp
->uc_mcontext
, ucp
->uc_flags
);
388 mutex_enter(p
->p_lock
);
392 l
->l_ctxlink
= (void *)(intptr_t)ucp
->uc_link
;
395 * If there was stack information, update whether or not we are
396 * still running on an alternate signal stack.
398 if ((ucp
->uc_flags
& _UC_STACK
) != 0) {
399 if (ucp
->uc_stack
.ss_flags
& SS_ONSTACK
)
400 l
->l_sigstk
.ss_flags
|= SS_ONSTACK
;
402 l
->l_sigstk
.ss_flags
&= ~SS_ONSTACK
;
410 netbsd32_setcontext(struct lwp
*l
, const struct netbsd32_setcontext_args
*uap
, register_t
*retval
)
413 syscallarg(netbsd32_ucontextp) ucp;
417 struct proc
*p
= l
->l_proc
;
419 error
= copyin(SCARG_P32(uap
, ucp
), &uc
, sizeof (uc
));
422 if (!(uc
.uc_flags
& _UC_CPU
))
424 mutex_enter(p
->p_lock
);
425 error
= setucontext32(l
, &uc
);
426 mutex_exit(p
->p_lock
);
430 return (EJUSTRETURN
);
434 netbsd32_sigtimedwait_put_info(const void *src
, void *dst
, size_t size
)
436 const siginfo_t
*info
= src
;
439 netbsd32_si_to_si32(&info32
, info
);
441 return copyout(&info32
, dst
, sizeof(info32
));
445 netbsd32_sigtimedwait_fetch_timeout(const void *src
, void *dst
, size_t size
)
447 struct timespec
*ts
= dst
;
448 struct netbsd32_timespec ts32
;
451 error
= copyin(src
, &ts32
, sizeof(ts32
));
455 netbsd32_to_timespec(&ts32
, ts
);
460 netbsd32_sigtimedwait_put_timeout(const void *src
, void *dst
, size_t size
)
462 const struct timespec
*ts
= src
;
463 struct netbsd32_timespec ts32
;
465 netbsd32_from_timespec(ts
, &ts32
);
467 return copyout(&ts32
, dst
, sizeof(ts32
));
471 netbsd32_____sigtimedwait50(struct lwp
*l
, const struct netbsd32_____sigtimedwait50_args
*uap
, register_t
*retval
)
474 syscallarg(netbsd32_sigsetp_t) set;
475 syscallarg(netbsd32_siginfop_t) info;
476 syscallarg(netbsd32_timespec50p_t) timeout;
478 struct sys_____sigtimedwait50_args ua
;
480 NETBSD32TOP_UAP(set
, const sigset_t
);
481 NETBSD32TOP_UAP(info
, siginfo_t
);
482 NETBSD32TOP_UAP(timeout
, struct timespec
);
484 return __sigtimedwait1(l
, &ua
, retval
,
485 netbsd32_sigtimedwait_put_info
,
486 netbsd32_sigtimedwait_fetch_timeout
,
487 netbsd32_sigtimedwait_put_timeout
);