]> git.proxmox.com Git - mirror_qemu.git/blame - linux-user/signal.c
fcntl constants
[mirror_qemu.git] / linux-user / signal.c
CommitLineData
31e31b8a 1/*
66fb9763 2 * Emulation of Linux signals
31e31b8a
FB
3 *
4 * Copyright (c) 2003 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, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <stdlib.h>
21#include <stdio.h>
66fb9763 22#include <string.h>
31e31b8a 23#include <stdarg.h>
2677e107 24#include <unistd.h>
31e31b8a 25#include <signal.h>
66fb9763 26#include <errno.h>
31e31b8a
FB
27#include <sys/ucontext.h>
28
3ef693a0 29#include "qemu.h"
66fb9763
FB
30
31//#define DEBUG_SIGNAL
32
33#define MAX_SIGQUEUE_SIZE 1024
34
35struct sigqueue {
36 struct sigqueue *next;
9de5e440 37 target_siginfo_t info;
66fb9763 38};
31e31b8a
FB
39
40struct emulated_sigaction {
41 struct target_sigaction sa;
66fb9763
FB
42 int pending; /* true if signal is pending */
43 struct sigqueue *first;
44 struct sigqueue info; /* in order to always have memory for the
45 first signal, we put it here */
31e31b8a
FB
46};
47
66fb9763
FB
48static struct emulated_sigaction sigact_table[TARGET_NSIG];
49static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
50static struct sigqueue *first_free; /* first free siginfo queue entry */
51static int signal_pending; /* non zero if a signal may be pending */
31e31b8a 52
66fb9763
FB
53static void host_signal_handler(int host_signum, siginfo_t *info,
54 void *puc);
55
56/* XXX: do it properly */
31e31b8a
FB
57static inline int host_to_target_signal(int sig)
58{
59 return sig;
60}
61
62static inline int target_to_host_signal(int sig)
63{
64 return sig;
65}
66
66fb9763
FB
67void host_to_target_sigset(target_sigset_t *d, sigset_t *s)
68{
69 int i;
70 for(i = 0;i < TARGET_NSIG_WORDS; i++) {
71 d->sig[i] = tswapl(((unsigned long *)s)[i]);
72 }
73}
74
75void target_to_host_sigset(sigset_t *d, target_sigset_t *s)
76{
77 int i;
78 for(i = 0;i < TARGET_NSIG_WORDS; i++) {
79 ((unsigned long *)d)[i] = tswapl(s->sig[i]);
80 }
81}
82
83void host_to_target_old_sigset(target_ulong *old_sigset,
84 const sigset_t *sigset)
85{
86 *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
87}
88
89void target_to_host_old_sigset(sigset_t *sigset,
90 const target_ulong *old_sigset)
91{
92 sigemptyset(sigset);
93 *(unsigned long *)sigset = tswapl(*old_sigset);
94}
95
9de5e440
FB
96/* siginfo conversion */
97
98static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
99 const siginfo_t *info)
66fb9763 100{
9de5e440
FB
101 int sig;
102 sig = host_to_target_signal(info->si_signo);
103 tinfo->si_signo = sig;
104 tinfo->si_errno = 0;
105 tinfo->si_code = 0;
106 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) {
107 /* should never come here, but who knows. The information for
108 the target is irrelevant */
109 tinfo->_sifields._sigfault._addr = 0;
110 } else if (sig >= TARGET_SIGRTMIN) {
111 tinfo->_sifields._rt._pid = info->si_pid;
112 tinfo->_sifields._rt._uid = info->si_uid;
113 /* XXX: potential problem if 64 bit */
114 tinfo->_sifields._rt._sigval.sival_ptr =
115 (target_ulong)info->si_value.sival_ptr;
116 }
117}
118
119static void tswap_siginfo(target_siginfo_t *tinfo,
120 const target_siginfo_t *info)
121{
122 int sig;
123 sig = info->si_signo;
124 tinfo->si_signo = tswap32(sig);
66fb9763
FB
125 tinfo->si_errno = tswap32(info->si_errno);
126 tinfo->si_code = tswap32(info->si_code);
9de5e440
FB
127 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) {
128 tinfo->_sifields._sigfault._addr =
129 tswapl(info->_sifields._sigfault._addr);
130 } else if (sig >= TARGET_SIGRTMIN) {
131 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
132 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
133 tinfo->_sifields._rt._sigval.sival_ptr =
134 tswapl(info->_sifields._rt._sigval.sival_ptr);
135 }
136}
137
138
139void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
140{
141 host_to_target_siginfo_noswap(tinfo, info);
142 tswap_siginfo(tinfo, tinfo);
66fb9763
FB
143}
144
9de5e440
FB
145/* XXX: we support only POSIX RT signals are used. */
146/* XXX: find a solution for 64 bit (additionnal malloced data is needed) */
147void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
66fb9763
FB
148{
149 info->si_signo = tswap32(tinfo->si_signo);
150 info->si_errno = tswap32(tinfo->si_errno);
151 info->si_code = tswap32(tinfo->si_code);
9de5e440
FB
152 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
153 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
154 info->si_value.sival_ptr =
155 (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
66fb9763
FB
156}
157
31e31b8a
FB
158void signal_init(void)
159{
160 struct sigaction act;
161 int i;
162
9de5e440
FB
163 /* set all host signal handlers. ALL signals are blocked during
164 the handlers to serialize them. */
165 sigfillset(&act.sa_mask);
31e31b8a
FB
166 act.sa_flags = SA_SIGINFO;
167 act.sa_sigaction = host_signal_handler;
168 for(i = 1; i < NSIG; i++) {
66fb9763 169 sigaction(i, &act, NULL);
31e31b8a
FB
170 }
171
172 memset(sigact_table, 0, sizeof(sigact_table));
66fb9763
FB
173
174 first_free = &sigqueue_table[0];
175 for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
176 sigqueue_table[i].next = &sigqueue_table[i + 1];
177 sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
178}
179
180/* signal queue handling */
181
182static inline struct sigqueue *alloc_sigqueue(void)
183{
184 struct sigqueue *q = first_free;
185 if (!q)
186 return NULL;
187 first_free = q->next;
188 return q;
31e31b8a
FB
189}
190
66fb9763
FB
191static inline void free_sigqueue(struct sigqueue *q)
192{
193 q->next = first_free;
194 first_free = q;
195}
196
9de5e440
FB
197/* abort execution with signal */
198void __attribute((noreturn)) force_sig(int sig)
66fb9763
FB
199{
200 int host_sig;
66fb9763 201 host_sig = target_to_host_signal(sig);
bc8a22cc 202 fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
66fb9763 203 sig, strsignal(host_sig));
9de5e440 204#if 1
66fb9763 205 _exit(-host_sig);
9de5e440
FB
206#else
207 {
208 struct sigaction act;
209 sigemptyset(&act.sa_mask);
210 act.sa_flags = SA_SIGINFO;
211 act.sa_sigaction = SIG_DFL;
212 sigaction(SIGABRT, &act, NULL);
213 abort();
214 }
215#endif
66fb9763
FB
216}
217
9de5e440
FB
218/* queue a signal so that it will be send to the virtual CPU as soon
219 as possible */
220int queue_signal(int sig, target_siginfo_t *info)
31e31b8a 221{
66fb9763 222 struct emulated_sigaction *k;
9de5e440 223 struct sigqueue *q, **pq;
66fb9763
FB
224 target_ulong handler;
225
9de5e440 226#if defined(DEBUG_SIGNAL)
bc8a22cc 227 fprintf(stderr, "queue_signal: sig=%d\n",
9de5e440 228 sig);
66fb9763 229#endif
9de5e440 230 k = &sigact_table[sig - 1];
66fb9763
FB
231 handler = k->sa._sa_handler;
232 if (handler == TARGET_SIG_DFL) {
233 /* default handler : ignore some signal. The other are fatal */
234 if (sig != TARGET_SIGCHLD &&
235 sig != TARGET_SIGURG &&
236 sig != TARGET_SIGWINCH) {
237 force_sig(sig);
9de5e440
FB
238 } else {
239 return 0; /* indicate ignored */
66fb9763
FB
240 }
241 } else if (handler == TARGET_SIG_IGN) {
242 /* ignore signal */
9de5e440 243 return 0;
66fb9763
FB
244 } else if (handler == TARGET_SIG_ERR) {
245 force_sig(sig);
246 } else {
9de5e440
FB
247 pq = &k->first;
248 if (sig < TARGET_SIGRTMIN) {
249 /* if non real time signal, we queue exactly one signal */
250 if (!k->pending)
251 q = &k->info;
252 else
253 return 0;
254 } else {
255 if (!k->pending) {
256 /* first signal */
257 q = &k->info;
258 } else {
259 q = alloc_sigqueue();
260 if (!q)
261 return -EAGAIN;
262 while (*pq != NULL)
263 pq = &(*pq)->next;
264 }
265 }
266 *pq = q;
267 q->info = *info;
268 q->next = NULL;
269 k->pending = 1;
270 /* signal that a new signal is pending */
271 signal_pending = 1;
272 return 1; /* indicates that the signal was queued */
273 }
274}
275
276#if defined(DEBUG_SIGNAL)
277#ifdef __i386__
278static void dump_regs(struct ucontext *uc)
279{
280 fprintf(stderr,
281 "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
282 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
283 "EFL=%08x EIP=%08x\n",
284 uc->uc_mcontext.gregs[EAX],
285 uc->uc_mcontext.gregs[EBX],
286 uc->uc_mcontext.gregs[ECX],
287 uc->uc_mcontext.gregs[EDX],
288 uc->uc_mcontext.gregs[ESI],
289 uc->uc_mcontext.gregs[EDI],
290 uc->uc_mcontext.gregs[EBP],
291 uc->uc_mcontext.gregs[ESP],
292 uc->uc_mcontext.gregs[EFL],
293 uc->uc_mcontext.gregs[EIP]);
294}
295#else
296static void dump_regs(struct ucontext *uc)
297{
298}
299#endif
300
301#endif
302
303static void host_signal_handler(int host_signum, siginfo_t *info,
304 void *puc)
305{
306 int sig;
307 target_siginfo_t tinfo;
308
309 /* the CPU emulator uses some host signals to detect exceptions,
310 we we forward to it some signals */
311 if (host_signum == SIGSEGV || host_signum == SIGBUS) {
312 if (cpu_x86_signal_handler(host_signum, info, puc))
313 return;
314 }
315
316 /* get target signal number */
317 sig = host_to_target_signal(host_signum);
318 if (sig < 1 || sig > TARGET_NSIG)
319 return;
320#if defined(DEBUG_SIGNAL)
bc8a22cc 321 fprintf(stderr, "qemu: got signal %d\n", sig);
9de5e440
FB
322 dump_regs(puc);
323#endif
324 host_to_target_siginfo_noswap(&tinfo, info);
325 if (queue_signal(sig, &tinfo) == 1) {
326 /* interrupt the virtual CPU as soon as possible */
327 cpu_x86_interrupt(global_env);
66fb9763
FB
328 }
329}
330
331int do_sigaction(int sig, const struct target_sigaction *act,
332 struct target_sigaction *oact)
333{
334 struct emulated_sigaction *k;
335
336 if (sig < 1 || sig > TARGET_NSIG)
337 return -EINVAL;
338 k = &sigact_table[sig - 1];
339#if defined(DEBUG_SIGNAL) && 0
340 fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
341 sig, (int)act, (int)oact);
342#endif
343 if (oact) {
344 oact->_sa_handler = tswapl(k->sa._sa_handler);
345 oact->sa_flags = tswapl(k->sa.sa_flags);
346 oact->sa_restorer = tswapl(k->sa.sa_restorer);
347 oact->sa_mask = k->sa.sa_mask;
348 }
349 if (act) {
350 k->sa._sa_handler = tswapl(act->_sa_handler);
351 k->sa.sa_flags = tswapl(act->sa_flags);
352 k->sa.sa_restorer = tswapl(act->sa_restorer);
353 k->sa.sa_mask = act->sa_mask;
354 }
355 return 0;
356}
357
358#ifdef TARGET_I386
359
360/* from the Linux kernel */
361
362struct target_fpreg {
363 uint16_t significand[4];
364 uint16_t exponent;
365};
366
367struct target_fpxreg {
368 uint16_t significand[4];
369 uint16_t exponent;
370 uint16_t padding[3];
371};
372
373struct target_xmmreg {
374 target_ulong element[4];
375};
376
377struct target_fpstate {
378 /* Regular FPU environment */
379 target_ulong cw;
380 target_ulong sw;
381 target_ulong tag;
382 target_ulong ipoff;
383 target_ulong cssel;
384 target_ulong dataoff;
385 target_ulong datasel;
386 struct target_fpreg _st[8];
387 uint16_t status;
388 uint16_t magic; /* 0xffff = regular FPU data only */
389
390 /* FXSR FPU environment */
391 target_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
392 target_ulong mxcsr;
393 target_ulong reserved;
394 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
395 struct target_xmmreg _xmm[8];
396 target_ulong padding[56];
397};
398
399#define X86_FXSR_MAGIC 0x0000
400
401struct target_sigcontext {
402 uint16_t gs, __gsh;
403 uint16_t fs, __fsh;
404 uint16_t es, __esh;
405 uint16_t ds, __dsh;
406 target_ulong edi;
407 target_ulong esi;
408 target_ulong ebp;
409 target_ulong esp;
410 target_ulong ebx;
411 target_ulong edx;
412 target_ulong ecx;
413 target_ulong eax;
414 target_ulong trapno;
415 target_ulong err;
416 target_ulong eip;
417 uint16_t cs, __csh;
418 target_ulong eflags;
419 target_ulong esp_at_signal;
420 uint16_t ss, __ssh;
421 target_ulong fpstate; /* pointer */
422 target_ulong oldmask;
423 target_ulong cr2;
424};
425
426typedef struct target_sigaltstack {
427 target_ulong ss_sp;
428 int ss_flags;
429 target_ulong ss_size;
430} target_stack_t;
431
432struct target_ucontext {
433 target_ulong uc_flags;
434 target_ulong uc_link;
435 target_stack_t uc_stack;
436 struct target_sigcontext uc_mcontext;
437 target_sigset_t uc_sigmask; /* mask last for extensibility */
438};
439
440struct sigframe
441{
442 target_ulong pretcode;
443 int sig;
444 struct target_sigcontext sc;
445 struct target_fpstate fpstate;
446 target_ulong extramask[TARGET_NSIG_WORDS-1];
447 char retcode[8];
448};
449
450struct rt_sigframe
451{
452 target_ulong pretcode;
453 int sig;
454 target_ulong pinfo;
455 target_ulong puc;
456 struct target_siginfo info;
457 struct target_ucontext uc;
458 struct target_fpstate fpstate;
459 char retcode[8];
460};
461
462/*
463 * Set up a signal frame.
464 */
465
466#define __put_user(x,ptr)\
467({\
468 int size = sizeof(*ptr);\
469 switch(size) {\
470 case 1:\
471 stb(ptr, (typeof(*ptr))(x));\
472 break;\
473 case 2:\
474 stw(ptr, (typeof(*ptr))(x));\
475 break;\
476 case 4:\
477 stl(ptr, (typeof(*ptr))(x));\
478 break;\
479 case 8:\
480 stq(ptr, (typeof(*ptr))(x));\
481 break;\
482 default:\
483 abort();\
484 }\
485 0;\
486})
487
488#define get_user(val, ptr) (typeof(*ptr))(*(ptr))
489
490
491#define __copy_to_user(dst, src, size)\
492({\
493 memcpy(dst, src, size);\
494 0;\
495})
496
9de5e440
FB
497static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
498 const target_siginfo_t *info)
66fb9763 499{
9de5e440 500 tswap_siginfo(tinfo, info);
66fb9763
FB
501 return 0;
502}
503
504/* XXX: save x87 state */
505static int
506setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
507 CPUX86State *env, unsigned long mask)
508{
509 int err = 0;
510
511 err |= __put_user(env->segs[R_GS], (unsigned int *)&sc->gs);
512 err |= __put_user(env->segs[R_FS], (unsigned int *)&sc->fs);
513 err |= __put_user(env->segs[R_ES], (unsigned int *)&sc->es);
514 err |= __put_user(env->segs[R_DS], (unsigned int *)&sc->ds);
515 err |= __put_user(env->regs[R_EDI], &sc->edi);
516 err |= __put_user(env->regs[R_ESI], &sc->esi);
517 err |= __put_user(env->regs[R_EBP], &sc->ebp);
518 err |= __put_user(env->regs[R_ESP], &sc->esp);
519 err |= __put_user(env->regs[R_EBX], &sc->ebx);
520 err |= __put_user(env->regs[R_EDX], &sc->edx);
521 err |= __put_user(env->regs[R_ECX], &sc->ecx);
522 err |= __put_user(env->regs[R_EAX], &sc->eax);
523 err |= __put_user(/*current->thread.trap_no*/ 0, &sc->trapno);
524 err |= __put_user(/*current->thread.error_code*/ 0, &sc->err);
525 err |= __put_user(env->eip, &sc->eip);
526 err |= __put_user(env->segs[R_CS], (unsigned int *)&sc->cs);
527 err |= __put_user(env->eflags, &sc->eflags);
528 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
529 err |= __put_user(env->segs[R_SS], (unsigned int *)&sc->ss);
530#if 0
531 tmp = save_i387(fpstate);
532 if (tmp < 0)
533 err = 1;
534 else
535 err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
536#else
537 err |= __put_user(0, &sc->fpstate);
538#endif
539 /* non-iBCS2 extensions.. */
540 err |= __put_user(mask, &sc->oldmask);
541 err |= __put_user(/*current->thread.cr2*/ 0, &sc->cr2);
66fb9763 542 return err;
31e31b8a
FB
543}
544
66fb9763
FB
545/*
546 * Determine which stack to use..
547 */
31e31b8a 548
66fb9763
FB
549static inline void *
550get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
31e31b8a 551{
66fb9763
FB
552 unsigned long esp;
553
554 /* Default to using normal stack */
555 esp = env->regs[R_ESP];
556#if 0
557 /* This is the X/Open sanctioned signal stack switching. */
558 if (ka->sa.sa_flags & SA_ONSTACK) {
559 if (sas_ss_flags(esp) == 0)
560 esp = current->sas_ss_sp + current->sas_ss_size;
561 }
562
563 /* This is the legacy signal stack switching. */
564 else if ((regs->xss & 0xffff) != __USER_DS &&
565 !(ka->sa.sa_flags & SA_RESTORER) &&
566 ka->sa.sa_restorer) {
567 esp = (unsigned long) ka->sa.sa_restorer;
568 }
569#endif
570 return (void *)((esp - frame_size) & -8ul);
571}
572
66fb9763
FB
573static void setup_frame(int sig, struct emulated_sigaction *ka,
574 target_sigset_t *set, CPUX86State *env)
575{
576 struct sigframe *frame;
577 int err = 0;
578
579 frame = get_sigframe(ka, env, sizeof(*frame));
580
581#if 0
582 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
583 goto give_sigsegv;
584#endif
585 err |= __put_user((/*current->exec_domain
586 && current->exec_domain->signal_invmap
587 && sig < 32
588 ? current->exec_domain->signal_invmap[sig]
589 : */ sig),
590 &frame->sig);
591 if (err)
592 goto give_sigsegv;
593
594 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
595 if (err)
596 goto give_sigsegv;
597
598 if (TARGET_NSIG_WORDS > 1) {
599 err |= __copy_to_user(frame->extramask, &set->sig[1],
600 sizeof(frame->extramask));
601 }
602 if (err)
603 goto give_sigsegv;
604
605 /* Set up to return from userspace. If provided, use a stub
606 already in userspace. */
607 if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
608 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
609 } else {
610 err |= __put_user(frame->retcode, &frame->pretcode);
611 /* This is popl %eax ; movl $,%eax ; int $0x80 */
612 err |= __put_user(0xb858, (short *)(frame->retcode+0));
613 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
614 err |= __put_user(0x80cd, (short *)(frame->retcode+6));
615 }
616
617 if (err)
618 goto give_sigsegv;
619
620 /* Set up registers for signal handler */
621 env->regs[R_ESP] = (unsigned long) frame;
622 env->eip = (unsigned long) ka->sa._sa_handler;
623
624 cpu_x86_load_seg(env, R_DS, __USER_DS);
625 cpu_x86_load_seg(env, R_ES, __USER_DS);
626 cpu_x86_load_seg(env, R_SS, __USER_DS);
627 cpu_x86_load_seg(env, R_CS, __USER_CS);
628 env->eflags &= ~TF_MASK;
629
630 return;
631
632give_sigsegv:
633 if (sig == TARGET_SIGSEGV)
634 ka->sa._sa_handler = TARGET_SIG_DFL;
635 force_sig(TARGET_SIGSEGV /* , current */);
636}
637
9de5e440
FB
638static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
639 target_siginfo_t *info,
66fb9763
FB
640 target_sigset_t *set, CPUX86State *env)
641{
642 struct rt_sigframe *frame;
643 int err = 0;
644
645 frame = get_sigframe(ka, env, sizeof(*frame));
646
647#if 0
648 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
649 goto give_sigsegv;
650#endif
651
652 err |= __put_user((/*current->exec_domain
653 && current->exec_domain->signal_invmap
654 && sig < 32
655 ? current->exec_domain->signal_invmap[sig]
656 : */sig),
657 &frame->sig);
658 err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
659 err |= __put_user((target_ulong)&frame->uc, &frame->puc);
660 err |= copy_siginfo_to_user(&frame->info, info);
661 if (err)
662 goto give_sigsegv;
31e31b8a 663
66fb9763
FB
664 /* Create the ucontext. */
665 err |= __put_user(0, &frame->uc.uc_flags);
666 err |= __put_user(0, &frame->uc.uc_link);
667 err |= __put_user(/*current->sas_ss_sp*/ 0, &frame->uc.uc_stack.ss_sp);
668 err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
669 &frame->uc.uc_stack.ss_flags);
670 err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size);
671 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
672 env, set->sig[0]);
673 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
674 if (err)
675 goto give_sigsegv;
31e31b8a 676
66fb9763
FB
677 /* Set up to return from userspace. If provided, use a stub
678 already in userspace. */
679 if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
680 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
681 } else {
682 err |= __put_user(frame->retcode, &frame->pretcode);
683 /* This is movl $,%eax ; int $0x80 */
684 err |= __put_user(0xb8, (char *)(frame->retcode+0));
685 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
686 err |= __put_user(0x80cd, (short *)(frame->retcode+5));
687 }
688
689 if (err)
690 goto give_sigsegv;
691
692 /* Set up registers for signal handler */
693 env->regs[R_ESP] = (unsigned long) frame;
694 env->eip = (unsigned long) ka->sa._sa_handler;
695
696 cpu_x86_load_seg(env, R_DS, __USER_DS);
697 cpu_x86_load_seg(env, R_ES, __USER_DS);
698 cpu_x86_load_seg(env, R_SS, __USER_DS);
699 cpu_x86_load_seg(env, R_CS, __USER_CS);
700 env->eflags &= ~TF_MASK;
701
702 return;
703
704give_sigsegv:
705 if (sig == TARGET_SIGSEGV)
706 ka->sa._sa_handler = TARGET_SIG_DFL;
707 force_sig(TARGET_SIGSEGV /* , current */);
708}
709
710static int
711restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
712{
713 unsigned int err = 0;
714
715
716
717#define COPY(x) err |= __get_user(regs->x, &sc->x)
718
719#define COPY_SEG(seg) \
720 { unsigned short tmp; \
721 err |= __get_user(tmp, &sc->seg); \
722 regs->x##seg = tmp; }
723
724#define COPY_SEG_STRICT(seg) \
725 { unsigned short tmp; \
726 err |= __get_user(tmp, &sc->seg); \
727 regs->x##seg = tmp|3; }
728
729#define GET_SEG(seg) \
730 { unsigned short tmp; \
731 err |= __get_user(tmp, &sc->seg); \
732 loadsegment(seg,tmp); }
733
734 cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
735 cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
736 cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
737 cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
738
739 env->regs[R_EDI] = ldl(&sc->edi);
740 env->regs[R_ESI] = ldl(&sc->esi);
741 env->regs[R_EBP] = ldl(&sc->ebp);
742 env->regs[R_ESP] = ldl(&sc->esp);
743 env->regs[R_EBX] = ldl(&sc->ebx);
744 env->regs[R_EDX] = ldl(&sc->edx);
745 env->regs[R_ECX] = ldl(&sc->ecx);
746 env->eip = ldl(&sc->eip);
747
748 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
749 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
750
751 {
752 unsigned int tmpflags;
753 tmpflags = ldl(&sc->eflags);
754 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
755 // regs->orig_eax = -1; /* disable syscall checks */
756 }
757
758#if 0
759 {
760 struct _fpstate * buf;
761 err |= __get_user(buf, &sc->fpstate);
762 if (buf) {
763 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
764 goto badframe;
765 err |= restore_i387(buf);
766 }
767 }
768#endif
769 *peax = ldl(&sc->eax);
770 return err;
771#if 0
772badframe:
773 return 1;
774#endif
775}
776
777long do_sigreturn(CPUX86State *env)
778{
779 struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
780 target_sigset_t target_set;
781 sigset_t set;
782 int eax, i;
783
784 /* set blocked signals */
785 target_set.sig[0] = frame->sc.oldmask;
786 for(i = 1; i < TARGET_NSIG_WORDS; i++)
787 target_set.sig[i] = frame->extramask[i - 1];
788
789 target_to_host_sigset(&set, &target_set);
790 sigprocmask(SIG_SETMASK, &set, NULL);
791
792 /* restore registers */
793 if (restore_sigcontext(env, &frame->sc, &eax))
794 goto badframe;
795 return eax;
796
797badframe:
798 force_sig(TARGET_SIGSEGV);
799 return 0;
800}
801
802long do_rt_sigreturn(CPUX86State *env)
803{
804 struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
805 target_sigset_t target_set;
806 sigset_t set;
807 // stack_t st;
808 int eax;
809
810#if 0
811 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
812 goto badframe;
813#endif
814 memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
815
816 target_to_host_sigset(&set, &target_set);
817 sigprocmask(SIG_SETMASK, &set, NULL);
818
819 if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
820 goto badframe;
821
822#if 0
823 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
824 goto badframe;
825 /* It is more difficult to avoid calling this function than to
826 call it and ignore errors. */
827 do_sigaltstack(&st, NULL, regs->esp);
828#endif
829 return eax;
830
831badframe:
832 force_sig(TARGET_SIGSEGV);
833 return 0;
834}
835
836#endif
837
838void process_pending_signals(void *cpu_env)
839{
840 int sig;
841 target_ulong handler;
9de5e440
FB
842 sigset_t set, old_set;
843 target_sigset_t target_old_set;
66fb9763
FB
844 struct emulated_sigaction *k;
845 struct sigqueue *q;
846
31e31b8a
FB
847 if (!signal_pending)
848 return;
849
66fb9763
FB
850 k = sigact_table;
851 for(sig = 1; sig <= TARGET_NSIG; sig++) {
852 if (k->pending)
31e31b8a 853 goto handle_signal;
66fb9763 854 k++;
31e31b8a
FB
855 }
856 /* if no signal is pending, just return */
857 signal_pending = 0;
858 return;
66fb9763 859
31e31b8a 860 handle_signal:
66fb9763 861#ifdef DEBUG_SIGNAL
bc8a22cc 862 fprintf(stderr, "qemu: process signal %d\n", sig);
66fb9763
FB
863#endif
864 /* dequeue signal */
865 q = k->first;
866 k->first = q->next;
867 if (!k->first)
868 k->pending = 0;
869
870 handler = k->sa._sa_handler;
871 if (handler == TARGET_SIG_DFL) {
872 /* default handler : ignore some signal. The other are fatal */
873 if (sig != TARGET_SIGCHLD &&
874 sig != TARGET_SIGURG &&
875 sig != TARGET_SIGWINCH) {
876 force_sig(sig);
877 }
878 } else if (handler == TARGET_SIG_IGN) {
879 /* ignore sig */
880 } else if (handler == TARGET_SIG_ERR) {
881 force_sig(sig);
882 } else {
9de5e440
FB
883 /* compute the blocked signals during the handler execution */
884 target_to_host_sigset(&set, &k->sa.sa_mask);
885 /* SA_NODEFER indicates that the current signal should not be
886 blocked during the handler */
887 if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
888 sigaddset(&set, target_to_host_signal(sig));
889
890 /* block signals in the handler using Linux */
891 sigprocmask(SIG_BLOCK, &set, &old_set);
892 /* save the previous blocked signal state to restore it at the
893 end of the signal execution (see do_sigreturn) */
894 host_to_target_sigset(&target_old_set, &old_set);
895
bc8a22cc
FB
896 /* if the CPU is in VM86 mode, we restore the 32 bit values */
897#ifdef TARGET_I386
898 {
899 CPUX86State *env = cpu_env;
900 if (env->eflags & VM_MASK)
901 save_v86_state(env);
902 }
903#endif
9de5e440 904 /* prepare the stack frame of the virtual CPU */
66fb9763 905 if (k->sa.sa_flags & TARGET_SA_SIGINFO)
9de5e440 906 setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
66fb9763 907 else
9de5e440 908 setup_frame(sig, k, &target_old_set, cpu_env);
66fb9763
FB
909 if (k->sa.sa_flags & TARGET_SA_RESETHAND)
910 k->sa._sa_handler = TARGET_SIG_DFL;
31e31b8a 911 }
66fb9763
FB
912 if (q != &k->info)
913 free_sigqueue(q);
914}
31e31b8a
FB
915
916