2
* Emulation of Linux signals
4
* Copyright (c) 2003 Fabrice Bellard
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.
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.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#include <sys/ucontext.h>
42
#define MAX_SIGQUEUE_SIZE 1024
45
struct sigqueue *next;
46
target_siginfo_t info;
49
struct emulated_sigaction {
50
struct target_sigaction sa;
51
int pending; /* true if signal is pending */
52
struct sigqueue *first;
53
struct sigqueue info; /* in order to always have memory for the
54
first signal, we put it here */
57
struct sigaltstack target_sigaltstack_used = {
61
static struct emulated_sigaction sigact_table[NSIG];
62
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
63
static struct sigqueue *first_free; /* first free siginfo queue entry */
64
static int signal_pending; /* non zero if a signal may be pending */
66
static void host_signal_handler(int host_signum, siginfo_t *info,
70
static inline int host_to_target_signal(int sig)
75
static inline int target_to_host_signal(int sig)
80
/* siginfo conversion */
84
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
89
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
94
void signal_init(void)
99
/* set all host signal handlers. ALL signals are blocked during
100
the handlers to serialize them. */
101
sigfillset(&act.sa_mask);
102
act.sa_flags = SA_SIGINFO;
103
act.sa_sigaction = host_signal_handler;
104
for(i = 1; i < NSIG; i++) {
105
sigaction(i, &act, NULL);
108
memset(sigact_table, 0, sizeof(sigact_table));
110
first_free = &sigqueue_table[0];
111
for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
112
sigqueue_table[i].next = &sigqueue_table[i + 1];
113
sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
116
/* signal queue handling */
118
static inline struct sigqueue *alloc_sigqueue(void)
120
struct sigqueue *q = first_free;
123
first_free = q->next;
127
static inline void free_sigqueue(struct sigqueue *q)
129
q->next = first_free;
133
/* abort execution with signal */
134
void __attribute((noreturn)) force_sig(int sig)
137
host_sig = target_to_host_signal(sig);
138
fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
139
sig, strsignal(host_sig));
143
/* queue a signal so that it will be send to the virtual CPU as soon
145
int queue_signal(int sig, target_siginfo_t *info)
147
struct emulated_sigaction *k;
148
struct sigqueue *q, **pq;
149
target_ulong handler;
151
#if defined(DEBUG_SIGNAL)
152
fprintf(stderr, "queue_signal: sig=%d\n",
155
k = &sigact_table[sig - 1];
156
handler = (target_ulong)k->sa.sa_handler;
157
if (handler == SIG_DFL) {
158
/* default handler : ignore some signal. The other are fatal */
159
if (sig != SIGCHLD &&
164
return 0; /* indicate ignored */
166
} else if (handler == host_to_target_signal(SIG_IGN)) {
169
} else if (handler == host_to_target_signal(SIG_ERR)) {
177
q = alloc_sigqueue();
187
/* signal that a new signal is pending */
189
return 1; /* indicates that the signal was queued */
193
static void host_signal_handler(int host_signum, siginfo_t *info,
197
target_siginfo_t tinfo;
199
/* the CPU emulator uses some host signals to detect exceptions,
200
we we forward to it some signals */
201
if (host_signum == SIGSEGV || host_signum == SIGBUS
202
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
203
|| host_signum == SIGFPE
206
if (cpu_signal_handler(host_signum, (void*)info, puc))
210
/* get target signal number */
211
sig = host_to_target_signal(host_signum);
212
if (sig < 1 || sig > NSIG)
215
#if defined(DEBUG_SIGNAL)
216
fprintf(stderr, "qemu: got signal %d\n", sig);
218
if (queue_signal(sig, &tinfo) == 1) {
219
/* interrupt the virtual CPU as soon as possible */
220
cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
224
int do_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss)
226
/* XXX: test errors */
229
oss->ss_sp = tswap32(target_sigaltstack_used.ss_sp);
230
oss->ss_size = tswap32(target_sigaltstack_used.ss_size);
231
oss->ss_flags = tswap32(target_sigaltstack_used.ss_flags);
235
target_sigaltstack_used.ss_sp = tswap32(ss->ss_sp);
236
target_sigaltstack_used.ss_size = tswap32(ss->ss_size);
237
target_sigaltstack_used.ss_flags = tswap32(ss->ss_flags);
242
int do_sigaction(int sig, const struct sigaction *act,
243
struct sigaction *oact)
245
struct emulated_sigaction *k;
246
struct sigaction act1;
249
if (sig < 1 || sig > NSIG)
252
k = &sigact_table[sig - 1];
253
#if defined(DEBUG_SIGNAL)
254
fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
255
sig, (int)act, (int)oact);
258
#if defined(DEBUG_SIGNAL)
259
fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
260
sig, (int)act, (int)oact);
263
oact->sa_handler = tswapl(k->sa.sa_handler);
264
oact->sa_flags = tswapl(k->sa.sa_flags);
265
oact->sa_mask = tswapl(k->sa.sa_mask);
268
#if defined(DEBUG_SIGNAL)
269
fprintf(stderr, "sigaction handler 0x%x flag 0x%x mask 0x%x\n",
270
act->sa_handler, act->sa_flags, act->sa_mask);
273
k->sa.sa_handler = tswapl(act->sa_handler);
274
k->sa.sa_flags = tswapl(act->sa_flags);
275
k->sa.sa_mask = tswapl(act->sa_mask);
276
/* we update the host signal state */
277
host_sig = target_to_host_signal(sig);
278
if (host_sig != SIGSEGV && host_sig != SIGBUS) {
279
#if defined(DEBUG_SIGNAL)
280
fprintf(stderr, "sigaction handler going to call sigaction\n",
281
act->sa_handler, act->sa_flags, act->sa_mask);
284
sigfillset(&act1.sa_mask);
285
act1.sa_flags = SA_SIGINFO;
286
if (k->sa.sa_flags & SA_RESTART)
287
act1.sa_flags |= SA_RESTART;
288
/* NOTE: it is important to update the host kernel signal
289
ignore state to avoid getting unexpected interrupted
291
if (k->sa.sa_handler == SIG_IGN) {
292
act1.sa_sigaction = (void *)SIG_IGN;
293
} else if (k->sa.sa_handler == SIG_DFL) {
294
act1.sa_sigaction = (void *)SIG_DFL;
296
act1.sa_sigaction = host_signal_handler;
298
sigaction(host_sig, &act1, NULL);
308
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
311
if(target_sigaltstack_used.ss_flags & SA_DISABLE)
314
/* Default to using normal stack */
315
esp = env->regs[R_ESP];
317
return (void *)((esp - frame_size) & -8ul);
321
return target_sigaltstack_used.ss_sp;
325
static void setup_frame(int sig, struct emulated_sigaction *ka,
326
void *set, CPUState *env)
331
fprintf(stderr, "setup_frame %d\n", sig);
332
frame = get_sigframe(ka, env, sizeof(*frame));
334
/* Set up registers for signal handler */
335
env->regs[R_ESP] = (unsigned long) frame;
336
env->eip = (unsigned long) ka->sa.sa_handler;
338
env->eflags &= ~TF_MASK;
344
ka->sa.sa_handler = SIG_DFL;
345
force_sig(SIGSEGV /* , current */);
348
long do_sigreturn(CPUState *env, int num)
351
struct target_sigcontext *scp = get_int_arg(&i, env);
352
/* XXX Get current signal number */
353
/* XXX Adjust accordin to sc_onstack, sc_mask */
354
if(tswapl(scp->sc_onstack) & 0x1)
355
target_sigaltstack_used.ss_flags |= ~SA_DISABLE;
357
target_sigaltstack_used.ss_flags &= SA_DISABLE;
358
int set = tswapl(scp->sc_eax);
359
sigprocmask(SIG_SETMASK, &set, NULL);
361
fprintf(stderr, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp->sc_mask, tswapl(scp->sc_eax), tswapl(scp->sc_ebx));
362
fprintf(stderr, "ECX:%x EDX:%x EDI:%x\n", scp->sc_ecx, tswapl(scp->sc_edx), tswapl(scp->sc_edi));
363
fprintf(stderr, "EIP:%x\n", tswapl(scp->sc_eip));
365
env->regs[R_EAX] = tswapl(scp->sc_eax);
366
env->regs[R_EBX] = tswapl(scp->sc_ebx);
367
env->regs[R_ECX] = tswapl(scp->sc_ecx);
368
env->regs[R_EDX] = tswapl(scp->sc_edx);
369
env->regs[R_EDI] = tswapl(scp->sc_edi);
370
env->regs[R_ESI] = tswapl(scp->sc_esi);
371
env->regs[R_EBP] = tswapl(scp->sc_ebp);
372
env->regs[R_ESP] = tswapl(scp->sc_esp);
373
env->segs[R_SS].selector = (void*)tswapl(scp->sc_ss);
374
env->eflags = tswapl(scp->sc_eflags);
375
env->eip = tswapl(scp->sc_eip);
376
env->segs[R_CS].selector = (void*)tswapl(scp->sc_cs);
377
env->segs[R_DS].selector = (void*)tswapl(scp->sc_ds);
378
env->segs[R_ES].selector = (void*)tswapl(scp->sc_es);
379
env->segs[R_FS].selector = (void*)tswapl(scp->sc_fs);
380
env->segs[R_GS].selector = (void*)tswapl(scp->sc_gs);
382
/* Again, because our caller's caller will reset EAX */
383
return env->regs[R_EAX];
388
static void setup_frame(int sig, struct emulated_sigaction *ka,
389
void *set, CPUState *env)
391
fprintf(stderr, "setup_frame: not implemented\n");
394
long do_sigreturn(CPUState *env, int num)
397
struct target_sigcontext *scp = get_int_arg(&i, env);
398
fprintf(stderr, "do_sigreturn: not implemented\n");
404
void process_pending_signals(void *cpu_env)
406
struct emulated_sigaction *k;
408
target_ulong handler;
416
for(sig = 1; sig <= NSIG; sig++) {
422
/* if no signal is pending, just return */
427
fprintf(stderr, "qemu: process signal %d\n", sig);
435
sig = gdb_handlesig (cpu_env, sig);
437
fprintf (stderr, "Lost signal\n");
441
handler = k->sa.sa_handler;
442
if (handler == SIG_DFL) {
443
/* default handler : ignore some signal. The other are fatal */
444
if (sig != SIGCHLD &&
449
} else if (handler == SIG_IGN) {
451
} else if (handler == SIG_ERR) {
455
setup_frame(sig, k, 0, cpu_env);
456
if (k->sa.sa_flags & SA_RESETHAND)
457
k->sa.sa_handler = SIG_DFL;