On 1/10/22 3:19 AM, Warner Losh wrote:
> Initialize the signal state for the emulator. Setup a set of sane
> default signal handlers, mirroring the host's signals. For fatal signals
> (those that exit by default), establish our own set of signal
> handlers. Stub out the actual signal handler we use for the moment.
>
> Signed-off-by: Stacey Son <sson@FreeBSD.org>
> Signed-off-by: Kyle Evans <kevans@freebsd.org>
> Signed-off-by: Warner Losh <imp@bsdimp.com>
> ---
> bsd-user/qemu.h | 1 +
> bsd-user/signal.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 69 insertions(+)
>
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 334f8b1d715..0e0b8db708b 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -97,6 +97,7 @@ typedef struct TaskState {
> struct qemu_sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
> struct qemu_sigqueue *first_free; /* first free siginfo queue entry */
> int signal_pending; /* non zero if a signal may be pending */
> + sigset_t signal_mask;
>
> uint8_t stack[];
> } __attribute__((aligned(16))) TaskState;
> diff --git a/bsd-user/signal.c b/bsd-user/signal.c
> index 7ea86149981..b2c91c39379 100644
> --- a/bsd-user/signal.c
> +++ b/bsd-user/signal.c
> @@ -28,6 +28,9 @@
> * fork.
> */
>
> +static struct target_sigaction sigact_table[TARGET_NSIG];
> +static void host_signal_handler(int host_sig, siginfo_t *info, void *puc);
> +
> int host_to_target_signal(int sig)
> {
> return sig;
> @@ -47,6 +50,28 @@ void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
> qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig);
> }
>
> +static int fatal_signal(int sig)
> +{
> +
> + switch (sig) {
> + case TARGET_SIGCHLD:
> + case TARGET_SIGURG:
> + case TARGET_SIGWINCH:
> + case TARGET_SIGINFO:
> + /* Ignored by default. */
> + return 0;
> + case TARGET_SIGCONT:
> + case TARGET_SIGSTOP:
> + case TARGET_SIGTSTP:
> + case TARGET_SIGTTIN:
> + case TARGET_SIGTTOU:
> + /* Job control signals. */
> + return 0;
> + default:
> + return 1;
> + }
> +}
> +
> /*
> * Force a synchronously taken QEMU_SI_FAULT signal. For QEMU the
> * 'force' part is handled in process_pending_signals().
> @@ -64,8 +89,51 @@ void force_sig_fault(int sig, int code, abi_ulong addr)
> queue_signal(env, sig, &info);
> }
>
> +static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
> +{
> +}
> +
> void signal_init(void)
> {
> + TaskState *ts = (TaskState *)thread_cpu->opaque;
> + struct sigaction act;
> + struct sigaction oact;
> + int i;
> + int host_sig;
> +
> + /* Set the signal mask from the host mask. */
> + sigprocmask(0, 0, &ts->signal_mask);
> +
> + /*
> + * Set all host signal handlers. ALL signals are blocked during the
> + * handlers to serialize them.
> + */
> + memset(sigact_table, 0, sizeof(sigact_table));
> +
> + sigfillset(&act.sa_mask);
> + act.sa_sigaction = host_signal_handler;
> + act.sa_flags = SA_SIGINFO;
> +
> + for (i = 1; i <= TARGET_NSIG; i++) {
> + host_sig = target_to_host_signal(i);
> + sigaction(host_sig, NULL, &oact);
Missing test for CONFIG_GPROF + SIGPROF. Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Gotcha. Will add.
Warner