xref: /qemu/bsd-user/signal.c (revision cfdee273c4e41d0b485bc82966a82d6ab6f37a1d)
1 /*
2  *  Emulation of BSD signals
3  *
4  *  Copyright (c) 2003 - 2008 Fabrice Bellard
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "qemu.h"
22 #include "signal-common.h"
23 #include "hw/core/tcg-cpu-ops.h"
24 
25 /*
26  * Stubbed out routines until we merge signal support from bsd-user
27  * fork.
28  */
29 
30 /*
31  * Queue a signal so that it will be send to the virtual CPU as soon as
32  * possible.
33  */
34 void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
35 {
36     qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig);
37 }
38 
39 /*
40  * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
41  * 'force' part is handled in process_pending_signals().
42  */
43 void force_sig_fault(int sig, int code, abi_ulong addr)
44 {
45     CPUState *cpu = thread_cpu;
46     CPUArchState *env = cpu->env_ptr;
47     target_siginfo_t info = {};
48 
49     info.si_signo = sig;
50     info.si_errno = 0;
51     info.si_code = code;
52     info.si_addr = addr;
53     queue_signal(env, sig, &info);
54 }
55 
56 void signal_init(void)
57 {
58 }
59 
60 void process_pending_signals(CPUArchState *cpu_env)
61 {
62 }
63 
64 void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
65                            MMUAccessType access_type, bool maperr, uintptr_t ra)
66 {
67     const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
68 
69     if (tcg_ops->record_sigsegv) {
70         tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
71     }
72 
73     force_sig_fault(TARGET_SIGSEGV,
74                     maperr ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR,
75                     addr);
76     cpu->exception_index = EXCP_INTERRUPT;
77     cpu_loop_exit_restore(cpu, ra);
78 }
79 
80 void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
81                           MMUAccessType access_type, uintptr_t ra)
82 {
83     const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
84 
85     if (tcg_ops->record_sigbus) {
86         tcg_ops->record_sigbus(cpu, addr, access_type, ra);
87     }
88 
89     force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, addr);
90     cpu->exception_index = EXCP_INTERRUPT;
91     cpu_loop_exit_restore(cpu, ra);
92 }
93