]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Emulation of BSD signals | |
3 | * | |
4 | * Copyright (c) 2013 Stacey Son | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0-or-later | |
7 | */ | |
8 | ||
9 | #ifndef SIGNAL_COMMON_H | |
10 | #define SIGNAL_COMMON_H | |
11 | ||
12 | /** | |
13 | * block_signals: block all signals while handling this guest syscall | |
14 | * | |
15 | * Block all signals, and arrange that the signal mask is returned to | |
16 | * its correct value for the guest before we resume execution of guest code. | |
17 | * If this function returns non-zero, then the caller should immediately | |
18 | * return -TARGET_ERESTARTSYS to the main loop, which will take the pending | |
19 | * signal and restart execution of the syscall. | |
20 | * If block_signals() returns zero, then the caller can continue with | |
21 | * emulation of the system call knowing that no signals can be taken | |
22 | * (and therefore that no race conditions will result). | |
23 | * This should only be called once, because if it is called a second time | |
24 | * it will always return non-zero. (Think of it like a mutex that can't | |
25 | * be recursively locked.) | |
26 | * Signals will be unblocked again by process_pending_signals(). | |
27 | * | |
28 | * Return value: non-zero if there was a pending signal, zero if not. | |
29 | */ | |
30 | int block_signals(void); /* Returns non zero if signal pending */ | |
31 | ||
32 | long do_rt_sigreturn(CPUArchState *env); | |
33 | int do_sigaction(int sig, const struct target_sigaction *act, | |
34 | struct target_sigaction *oact); | |
35 | abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); | |
36 | long do_sigreturn(CPUArchState *env, abi_ulong addr); | |
37 | void force_sig_fault(int sig, int code, abi_ulong addr); | |
38 | void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); | |
39 | int host_to_target_signal(int sig); | |
40 | void host_to_target_sigset(target_sigset_t *d, const sigset_t *s); | |
41 | void process_pending_signals(CPUArchState *env); | |
42 | void queue_signal(CPUArchState *env, int sig, int si_type, | |
43 | target_siginfo_t *info); | |
44 | void signal_init(void); | |
45 | int target_to_host_signal(int sig); | |
46 | void target_to_host_sigset(sigset_t *d, const target_sigset_t *s); | |
47 | ||
48 | /* | |
49 | * Within QEMU the top 8 bits of si_code indicate which of the parts of the | |
50 | * union in target_siginfo is valid. This only applies between | |
51 | * host_to_target_siginfo_noswap() and tswap_siginfo(); it does not appear | |
52 | * either within host siginfo_t or in target_siginfo structures which we get | |
53 | * from the guest userspace program. Linux kernels use this internally, but BSD | |
54 | * kernels don't do this, but its a useful abstraction. | |
55 | * | |
56 | * The linux-user version of this uses the top 16 bits, but FreeBSD's SI_USER | |
57 | * and other signal independent SI_ codes have bit 16 set, so we only use the top | |
58 | * byte instead. | |
59 | * | |
60 | * For FreeBSD, we have si_pid, si_uid, si_status, and si_addr always. Linux and | |
61 | * {Open,Net}BSD have a different approach (where their reason field is larger, | |
62 | * but whose siginfo has fewer fields always). | |
63 | * | |
64 | * QEMU_SI_CAPSICUM is currently only FreeBSD 14 current only, so only define | |
65 | * it where _capsicum is available. | |
66 | */ | |
67 | #define QEMU_SI_NOINFO 0 /* nothing other than si_signo valid */ | |
68 | #define QEMU_SI_FAULT 1 /* _fault is valid in _reason */ | |
69 | #define QEMU_SI_TIMER 2 /* _timer is valid in _reason */ | |
70 | #define QEMU_SI_MESGQ 3 /* _mesgq is valid in _reason */ | |
71 | #define QEMU_SI_POLL 4 /* _poll is valid in _reason */ | |
72 | #if defined(__FreeBSD_version) && __FreeBSD_version >= 1400026 | |
73 | #define QEMU_SI_CAPSICUM 5 /* _capsicum is valid in _reason */ | |
74 | #endif | |
75 | ||
76 | #endif |