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, see <http://www.gnu.org/licenses/>.
25 #include <sys/ucontext.h>
35 #include "qemu-common.h"
39 #define MAX_SIGQUEUE_SIZE 1024
42 struct sigqueue
*next
;
43 target_siginfo_t info
;
46 struct emulated_sigaction
{
47 struct target_sigaction sa
;
48 int pending
; /* true if signal is pending */
49 struct sigqueue
*first
;
50 struct sigqueue info
; /* in order to always have memory for the
51 first signal, we put it here */
54 static struct sigaltstack target_sigaltstack_used
= {
58 static struct emulated_sigaction sigact_table
[NSIG
];
59 static struct sigqueue sigqueue_table
[MAX_SIGQUEUE_SIZE
]; /* siginfo queue */
60 static struct sigqueue
*first_free
; /* first free siginfo queue entry */
61 static int signal_pending
; /* non zero if a signal may be pending */
63 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
67 static inline int host_to_target_signal(int sig
)
72 static inline int target_to_host_signal(int sig
)
77 /* siginfo conversion */
81 void host_to_target_siginfo(target_siginfo_t
*tinfo
, const siginfo_t
*info
)
86 void target_to_host_siginfo(siginfo_t
*info
, const target_siginfo_t
*tinfo
)
91 void signal_init(void)
96 /* set all host signal handlers. ALL signals are blocked during
97 the handlers to serialize them. */
98 sigfillset(&act
.sa_mask
);
99 act
.sa_flags
= SA_SIGINFO
;
100 act
.sa_sigaction
= host_signal_handler
;
101 for(i
= 1; i
< NSIG
; i
++) {
102 sigaction(i
, &act
, NULL
);
105 memset(sigact_table
, 0, sizeof(sigact_table
));
107 first_free
= &sigqueue_table
[0];
108 for(i
= 0; i
< MAX_SIGQUEUE_SIZE
- 1; i
++)
109 sigqueue_table
[i
].next
= &sigqueue_table
[i
+ 1];
110 sigqueue_table
[MAX_SIGQUEUE_SIZE
- 1].next
= NULL
;
113 /* signal queue handling */
115 static inline struct sigqueue
*alloc_sigqueue(void)
117 struct sigqueue
*q
= first_free
;
120 first_free
= q
->next
;
124 static inline void free_sigqueue(struct sigqueue
*q
)
126 q
->next
= first_free
;
130 /* abort execution with signal */
131 void QEMU_NORETURN
force_sig(int sig
)
134 host_sig
= target_to_host_signal(sig
);
135 fprintf(stderr
, "qemu: uncaught target signal %d (%s) - exiting\n",
136 sig
, strsignal(host_sig
));
140 /* queue a signal so that it will be send to the virtual CPU as soon
142 int queue_signal(int sig
, target_siginfo_t
*info
)
144 struct emulated_sigaction
*k
;
145 struct sigqueue
*q
, **pq
;
146 target_ulong handler
;
148 #if defined(DEBUG_SIGNAL)
149 fprintf(stderr
, "queue_signal: sig=%d\n",
152 k
= &sigact_table
[sig
- 1];
153 handler
= (target_ulong
)k
->sa
.sa_handler
;
154 if (handler
== SIG_DFL
) {
155 /* default handler : ignore some signal. The other are fatal */
156 if (sig
!= SIGCHLD
&&
161 return 0; /* indicate ignored */
163 } else if (handler
== host_to_target_signal(SIG_IGN
)) {
166 } else if (handler
== host_to_target_signal(SIG_ERR
)) {
174 q
= alloc_sigqueue();
184 /* signal that a new signal is pending */
186 return 1; /* indicates that the signal was queued */
190 static void host_signal_handler(int host_signum
, siginfo_t
*info
,
194 target_siginfo_t tinfo
;
196 /* the CPU emulator uses some host signals to detect exceptions,
197 we we forward to it some signals */
198 if (host_signum
== SIGSEGV
|| host_signum
== SIGBUS
) {
199 if (cpu_signal_handler(host_signum
, (void*)info
, puc
))
203 /* get target signal number */
204 sig
= host_to_target_signal(host_signum
);
205 if (sig
< 1 || sig
> NSIG
)
208 #if defined(DEBUG_SIGNAL)
209 fprintf(stderr
, "qemu: got signal %d\n", sig
);
211 if (queue_signal(sig
, &tinfo
) == 1) {
212 /* interrupt the virtual CPU as soon as possible */
213 cpu_exit(global_env
);
217 int do_sigaltstack(const struct sigaltstack
*ss
, struct sigaltstack
*oss
)
219 /* XXX: test errors */
222 oss
->ss_sp
= tswap32(target_sigaltstack_used
.ss_sp
);
223 oss
->ss_size
= tswap32(target_sigaltstack_used
.ss_size
);
224 oss
->ss_flags
= tswap32(target_sigaltstack_used
.ss_flags
);
228 target_sigaltstack_used
.ss_sp
= tswap32(ss
->ss_sp
);
229 target_sigaltstack_used
.ss_size
= tswap32(ss
->ss_size
);
230 target_sigaltstack_used
.ss_flags
= tswap32(ss
->ss_flags
);
235 int do_sigaction(int sig
, const struct sigaction
*act
,
236 struct sigaction
*oact
)
238 struct emulated_sigaction
*k
;
239 struct sigaction act1
;
242 if (sig
< 1 || sig
> NSIG
)
245 k
= &sigact_table
[sig
- 1];
246 #if defined(DEBUG_SIGNAL)
247 fprintf(stderr
, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
248 sig
, (int)act
, (int)oact
);
251 #if defined(DEBUG_SIGNAL)
252 fprintf(stderr
, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
253 sig
, (int)act
, (int)oact
);
256 oact
->sa_handler
= tswapl(k
->sa
.sa_handler
);
257 oact
->sa_flags
= tswapl(k
->sa
.sa_flags
);
258 oact
->sa_mask
= tswapl(k
->sa
.sa_mask
);
261 #if defined(DEBUG_SIGNAL)
262 fprintf(stderr
, "sigaction handler 0x%x flag 0x%x mask 0x%x\n",
263 act
->sa_handler
, act
->sa_flags
, act
->sa_mask
);
266 k
->sa
.sa_handler
= tswapl(act
->sa_handler
);
267 k
->sa
.sa_flags
= tswapl(act
->sa_flags
);
268 k
->sa
.sa_mask
= tswapl(act
->sa_mask
);
269 /* we update the host signal state */
270 host_sig
= target_to_host_signal(sig
);
271 if (host_sig
!= SIGSEGV
&& host_sig
!= SIGBUS
) {
272 #if defined(DEBUG_SIGNAL)
273 fprintf(stderr
, "sigaction handler going to call sigaction\n");
276 sigfillset(&act1
.sa_mask
);
277 act1
.sa_flags
= SA_SIGINFO
;
278 if (k
->sa
.sa_flags
& SA_RESTART
)
279 act1
.sa_flags
|= SA_RESTART
;
280 /* NOTE: it is important to update the host kernel signal
281 ignore state to avoid getting unexpected interrupted
283 if (k
->sa
.sa_handler
== SIG_IGN
) {
284 act1
.sa_sigaction
= (void *)SIG_IGN
;
285 } else if (k
->sa
.sa_handler
== SIG_DFL
) {
286 act1
.sa_sigaction
= (void *)SIG_DFL
;
288 act1
.sa_sigaction
= host_signal_handler
;
290 sigaction(host_sig
, &act1
, NULL
);
300 get_sigframe(struct emulated_sigaction
*ka
, CPUX86State
*env
, size_t frame_size
)
303 if(target_sigaltstack_used
.ss_flags
& SA_DISABLE
)
306 /* Default to using normal stack */
307 esp
= env
->regs
[R_ESP
];
309 return (void *)((esp
- frame_size
) & -8ul);
313 return target_sigaltstack_used
.ss_sp
;
317 static void setup_frame(int sig
, struct emulated_sigaction
*ka
,
318 void *set
, CPUState
*env
)
322 fprintf(stderr
, "setup_frame %d\n", sig
);
323 frame
= get_sigframe(ka
, env
, sizeof(*frame
));
325 /* Set up registers for signal handler */
326 env
->regs
[R_ESP
] = (unsigned long) frame
;
327 env
->eip
= (unsigned long) ka
->sa
.sa_handler
;
329 env
->eflags
&= ~TF_MASK
;
335 ka
->sa
.sa_handler
= SIG_DFL
;
336 force_sig(SIGSEGV
/* , current */);
339 long do_sigreturn(CPUState
*env
, int num
)
342 struct target_sigcontext
*scp
= get_int_arg(&i
, env
);
343 /* XXX Get current signal number */
344 /* XXX Adjust accordin to sc_onstack, sc_mask */
345 if(tswapl(scp
->sc_onstack
) & 0x1)
346 target_sigaltstack_used
.ss_flags
|= ~SA_DISABLE
;
348 target_sigaltstack_used
.ss_flags
&= SA_DISABLE
;
349 int set
= tswapl(scp
->sc_eax
);
350 sigprocmask(SIG_SETMASK
, &set
, NULL
);
352 fprintf(stderr
, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp
->sc_mask
, tswapl(scp
->sc_eax
), tswapl(scp
->sc_ebx
));
353 fprintf(stderr
, "ECX:%x EDX:%x EDI:%x\n", scp
->sc_ecx
, tswapl(scp
->sc_edx
), tswapl(scp
->sc_edi
));
354 fprintf(stderr
, "EIP:%x\n", tswapl(scp
->sc_eip
));
356 env
->regs
[R_EAX
] = tswapl(scp
->sc_eax
);
357 env
->regs
[R_EBX
] = tswapl(scp
->sc_ebx
);
358 env
->regs
[R_ECX
] = tswapl(scp
->sc_ecx
);
359 env
->regs
[R_EDX
] = tswapl(scp
->sc_edx
);
360 env
->regs
[R_EDI
] = tswapl(scp
->sc_edi
);
361 env
->regs
[R_ESI
] = tswapl(scp
->sc_esi
);
362 env
->regs
[R_EBP
] = tswapl(scp
->sc_ebp
);
363 env
->regs
[R_ESP
] = tswapl(scp
->sc_esp
);
364 env
->segs
[R_SS
].selector
= (void*)tswapl(scp
->sc_ss
);
365 env
->eflags
= tswapl(scp
->sc_eflags
);
366 env
->eip
= tswapl(scp
->sc_eip
);
367 env
->segs
[R_CS
].selector
= (void*)tswapl(scp
->sc_cs
);
368 env
->segs
[R_DS
].selector
= (void*)tswapl(scp
->sc_ds
);
369 env
->segs
[R_ES
].selector
= (void*)tswapl(scp
->sc_es
);
370 env
->segs
[R_FS
].selector
= (void*)tswapl(scp
->sc_fs
);
371 env
->segs
[R_GS
].selector
= (void*)tswapl(scp
->sc_gs
);
373 /* Again, because our caller's caller will reset EAX */
374 return env
->regs
[R_EAX
];
379 static void setup_frame(int sig
, struct emulated_sigaction
*ka
,
380 void *set
, CPUState
*env
)
382 fprintf(stderr
, "setup_frame: not implemented\n");
385 long do_sigreturn(CPUState
*env
, int num
)
388 struct target_sigcontext
*scp
= get_int_arg(&i
, env
);
389 fprintf(stderr
, "do_sigreturn: not implemented\n");
395 void process_pending_signals(void *cpu_env
)
397 struct emulated_sigaction
*k
;
399 target_ulong handler
;
407 for(sig
= 1; sig
<= NSIG
; sig
++) {
413 /* if no signal is pending, just return */
418 fprintf(stderr
, "qemu: process signal %d\n", sig
);
426 sig
= gdb_handlesig (cpu_env
, sig
);
428 fprintf (stderr
, "Lost signal\n");
432 handler
= k
->sa
.sa_handler
;
433 if (handler
== SIG_DFL
) {
434 /* default handler : ignore some signal. The other are fatal */
435 if (sig
!= SIGCHLD
&&
440 } else if (handler
== SIG_IGN
) {
442 } else if (handler
== SIG_ERR
) {
446 setup_frame(sig
, k
, 0, cpu_env
);
447 if (k
->sa
.sa_flags
& SA_RESETHAND
)
448 k
->sa
.sa_handler
= SIG_DFL
;