2 * Emulation of BSD signals
4 * Copyright (c) 2003 - 2008 Fabrice Bellard
5 * Copyright (c) 2013 Stacey Son
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "signal-common.h"
25 #include "hw/core/tcg-cpu-ops.h"
26 #include "host-signal.h"
29 * Stubbed out routines until we merge signal support from bsd-user
33 static struct target_sigaction sigact_table
[TARGET_NSIG
];
34 static void host_signal_handler(int host_sig
, siginfo_t
*info
, void *puc
);
37 * The BSD ABIs use the same singal numbers across all the CPU architectures, so
38 * (unlike Linux) these functions are just the identity mapping. This might not
39 * be true for XyzBSD running on AbcBSD, which doesn't currently work.
41 int host_to_target_signal(int sig
)
46 int target_to_host_signal(int sig
)
51 static bool has_trapno(int tsig
)
53 return tsig
== TARGET_SIGILL
||
54 tsig
== TARGET_SIGFPE
||
55 tsig
== TARGET_SIGSEGV
||
56 tsig
== TARGET_SIGBUS
||
57 tsig
== TARGET_SIGTRAP
;
61 /* Siginfo conversion. */
64 * Populate tinfo w/o swapping based on guessing which fields are valid.
66 static inline void host_to_target_siginfo_noswap(target_siginfo_t
*tinfo
,
67 const siginfo_t
*info
)
69 int sig
= host_to_target_signal(info
->si_signo
);
70 int si_code
= info
->si_code
;
74 * Make sure we that the variable portion of the target siginfo is zeroed
75 * out so we don't leak anything into that.
77 memset(&tinfo
->_reason
, 0, sizeof(tinfo
->_reason
));
80 * This is awkward, because we have to use a combination of the si_code and
81 * si_signo to figure out which of the union's members are valid.o We
82 * therefore make our best guess.
84 * Once we have made our guess, we record it in the top 16 bits of
85 * the si_code, so that tswap_siginfo() later can use it.
86 * tswap_siginfo() will strip these top bits out before writing
87 * si_code to the guest (sign-extending the lower bits).
89 tinfo
->si_signo
= sig
;
90 tinfo
->si_errno
= info
->si_errno
;
91 tinfo
->si_code
= info
->si_code
;
92 tinfo
->si_pid
= info
->si_pid
;
93 tinfo
->si_uid
= info
->si_uid
;
94 tinfo
->si_status
= info
->si_status
;
95 tinfo
->si_addr
= (abi_ulong
)(unsigned long)info
->si_addr
;
97 * si_value is opaque to kernel. On all FreeBSD platforms,
98 * sizeof(sival_ptr) >= sizeof(sival_int) so the following
99 * always will copy the larger element.
101 tinfo
->si_value
.sival_ptr
=
102 (abi_ulong
)(unsigned long)info
->si_value
.sival_ptr
;
106 * All the SI_xxx codes that are defined here are global to
107 * all the signals (they have values that none of the other,
108 * more specific signal info will set).
116 * Only the fixed parts are valid (though FreeBSD doesn't always
117 * set all the fields to non-zero values.
119 si_type
= QEMU_SI_NOINFO
;
122 tinfo
->_reason
._timer
._timerid
= info
->_reason
._timer
._timerid
;
123 tinfo
->_reason
._timer
._overrun
= info
->_reason
._timer
._overrun
;
124 si_type
= QEMU_SI_TIMER
;
127 tinfo
->_reason
._mesgq
._mqd
= info
->_reason
._mesgq
._mqd
;
128 si_type
= QEMU_SI_MESGQ
;
132 * We have to go based on the signal number now to figure out
135 if (has_trapno(sig
)) {
136 tinfo
->_reason
._fault
._trapno
= info
->_reason
._fault
._trapno
;
137 si_type
= QEMU_SI_FAULT
;
139 #ifdef TARGET_SIGPOLL
141 * FreeBSD never had SIGPOLL, but emulates it for Linux so there's
142 * a chance it may popup in the future.
144 if (sig
== TARGET_SIGPOLL
) {
145 tinfo
->_reason
._poll
._band
= info
->_reason
._poll
._band
;
146 si_type
= QEMU_SI_POLL
;
150 * Unsure that this can actually be generated, and our support for
151 * capsicum is somewhere between weak and non-existant, but if we get
152 * one, then we know what to save.
154 if (sig
== TARGET_SIGTRAP
) {
155 tinfo
->_reason
._capsicum
._syscall
=
156 info
->_reason
._capsicum
._syscall
;
157 si_type
= QEMU_SI_CAPSICUM
;
161 tinfo
->si_code
= deposit32(si_code
, 24, 8, si_type
);
165 * Queue a signal so that it will be send to the virtual CPU as soon as
168 void queue_signal(CPUArchState
*env
, int sig
, int si_type
,
169 target_siginfo_t
*info
)
171 qemu_log_mask(LOG_UNIMP
, "No signal queueing, dropping signal %d\n", sig
);
174 static int fatal_signal(int sig
)
180 case TARGET_SIGWINCH
:
182 /* Ignored by default. */
189 /* Job control signals. */
197 * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
198 * 'force' part is handled in process_pending_signals().
200 void force_sig_fault(int sig
, int code
, abi_ulong addr
)
202 CPUState
*cpu
= thread_cpu
;
203 CPUArchState
*env
= cpu
->env_ptr
;
204 target_siginfo_t info
= {};
210 queue_signal(env
, sig
, QEMU_SI_FAULT
, &info
);
213 static void host_signal_handler(int host_sig
, siginfo_t
*info
, void *puc
)
217 void signal_init(void)
219 TaskState
*ts
= (TaskState
*)thread_cpu
->opaque
;
220 struct sigaction act
;
221 struct sigaction oact
;
225 /* Set the signal mask from the host mask. */
226 sigprocmask(0, 0, &ts
->signal_mask
);
228 sigfillset(&act
.sa_mask
);
229 act
.sa_sigaction
= host_signal_handler
;
230 act
.sa_flags
= SA_SIGINFO
;
232 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
234 if (i
== TARGET_SIGPROF
) {
238 host_sig
= target_to_host_signal(i
);
239 sigaction(host_sig
, NULL
, &oact
);
240 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
241 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
242 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
243 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
246 * If there's already a handler installed then something has
247 * gone horribly wrong, so don't even try to handle that case.
248 * Install some handlers for our own use. We need at least
249 * SIGSEGV and SIGBUS, to detect exceptions. We can not just
250 * trap all signals because it affects syscall interrupt
251 * behavior. But do trap all default-fatal signals.
253 if (fatal_signal(i
)) {
254 sigaction(host_sig
, &act
, NULL
);
259 void process_pending_signals(CPUArchState
*cpu_env
)
263 void cpu_loop_exit_sigsegv(CPUState
*cpu
, target_ulong addr
,
264 MMUAccessType access_type
, bool maperr
, uintptr_t ra
)
266 const struct TCGCPUOps
*tcg_ops
= CPU_GET_CLASS(cpu
)->tcg_ops
;
268 if (tcg_ops
->record_sigsegv
) {
269 tcg_ops
->record_sigsegv(cpu
, addr
, access_type
, maperr
, ra
);
272 force_sig_fault(TARGET_SIGSEGV
,
273 maperr
? TARGET_SEGV_MAPERR
: TARGET_SEGV_ACCERR
,
275 cpu
->exception_index
= EXCP_INTERRUPT
;
276 cpu_loop_exit_restore(cpu
, ra
);
279 void cpu_loop_exit_sigbus(CPUState
*cpu
, target_ulong addr
,
280 MMUAccessType access_type
, uintptr_t ra
)
282 const struct TCGCPUOps
*tcg_ops
= CPU_GET_CLASS(cpu
)->tcg_ops
;
284 if (tcg_ops
->record_sigbus
) {
285 tcg_ops
->record_sigbus(cpu
, addr
, access_type
, ra
);
288 force_sig_fault(TARGET_SIGBUS
, TARGET_BUS_ADRALN
, addr
);
289 cpu
->exception_index
= EXCP_INTERRUPT
;
290 cpu_loop_exit_restore(cpu
, ra
);