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
)
52 * Queue a signal so that it will be send to the virtual CPU as soon as
55 void queue_signal(CPUArchState
*env
, int sig
, int si_type
,
56 target_siginfo_t
*info
)
58 qemu_log_mask(LOG_UNIMP
, "No signal queueing, dropping signal %d\n", sig
);
61 static int fatal_signal(int sig
)
69 /* Ignored by default. */
76 /* Job control signals. */
84 * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
85 * 'force' part is handled in process_pending_signals().
87 void force_sig_fault(int sig
, int code
, abi_ulong addr
)
89 CPUState
*cpu
= thread_cpu
;
90 CPUArchState
*env
= cpu
->env_ptr
;
91 target_siginfo_t info
= {};
97 queue_signal(env
, sig
, QEMU_SI_FAULT
, &info
);
100 static void host_signal_handler(int host_sig
, siginfo_t
*info
, void *puc
)
104 void signal_init(void)
106 TaskState
*ts
= (TaskState
*)thread_cpu
->opaque
;
107 struct sigaction act
;
108 struct sigaction oact
;
112 /* Set the signal mask from the host mask. */
113 sigprocmask(0, 0, &ts
->signal_mask
);
115 sigfillset(&act
.sa_mask
);
116 act
.sa_sigaction
= host_signal_handler
;
117 act
.sa_flags
= SA_SIGINFO
;
119 for (i
= 1; i
<= TARGET_NSIG
; i
++) {
121 if (i
== TARGET_SIGPROF
) {
125 host_sig
= target_to_host_signal(i
);
126 sigaction(host_sig
, NULL
, &oact
);
127 if (oact
.sa_sigaction
== (void *)SIG_IGN
) {
128 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_IGN
;
129 } else if (oact
.sa_sigaction
== (void *)SIG_DFL
) {
130 sigact_table
[i
- 1]._sa_handler
= TARGET_SIG_DFL
;
133 * If there's already a handler installed then something has
134 * gone horribly wrong, so don't even try to handle that case.
135 * Install some handlers for our own use. We need at least
136 * SIGSEGV and SIGBUS, to detect exceptions. We can not just
137 * trap all signals because it affects syscall interrupt
138 * behavior. But do trap all default-fatal signals.
140 if (fatal_signal(i
)) {
141 sigaction(host_sig
, &act
, NULL
);
146 void process_pending_signals(CPUArchState
*cpu_env
)
150 void cpu_loop_exit_sigsegv(CPUState
*cpu
, target_ulong addr
,
151 MMUAccessType access_type
, bool maperr
, uintptr_t ra
)
153 const struct TCGCPUOps
*tcg_ops
= CPU_GET_CLASS(cpu
)->tcg_ops
;
155 if (tcg_ops
->record_sigsegv
) {
156 tcg_ops
->record_sigsegv(cpu
, addr
, access_type
, maperr
, ra
);
159 force_sig_fault(TARGET_SIGSEGV
,
160 maperr
? TARGET_SEGV_MAPERR
: TARGET_SEGV_ACCERR
,
162 cpu
->exception_index
= EXCP_INTERRUPT
;
163 cpu_loop_exit_restore(cpu
, ra
);
166 void cpu_loop_exit_sigbus(CPUState
*cpu
, target_ulong addr
,
167 MMUAccessType access_type
, uintptr_t ra
)
169 const struct TCGCPUOps
*tcg_ops
= CPU_GET_CLASS(cpu
)->tcg_ops
;
171 if (tcg_ops
->record_sigbus
) {
172 tcg_ops
->record_sigbus(cpu
, addr
, access_type
, ra
);
175 force_sig_fault(TARGET_SIGBUS
, TARGET_BUS_ADRALN
, addr
);
176 cpu
->exception_index
= EXCP_INTERRUPT
;
177 cpu_loop_exit_restore(cpu
, ra
);