Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 78c34e98

History | View | Annotate | Download (24.9 kB)

1
/*
2
 *  Emulation of Linux signals
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>
22
#include <string.h>
23
#include <stdarg.h>
24
#include <unistd.h>
25
#include <signal.h>
26
#include <errno.h>
27
#include <sys/ucontext.h>
28

    
29
#ifdef __ia64__
30
#undef uc_mcontext
31
#undef uc_sigmask
32
#undef uc_stack
33
#undef uc_link
34
#endif 
35

    
36
#include "qemu.h"
37

    
38
//#define DEBUG_SIGNAL
39

    
40
#define MAX_SIGQUEUE_SIZE 1024
41

    
42
struct sigqueue {
43
    struct sigqueue *next;
44
    target_siginfo_t info;
45
};
46

    
47
struct emulated_sigaction {
48
    struct target_sigaction sa;
49
    int pending; /* true if signal is pending */
50
    struct sigqueue *first;
51
    struct sigqueue info; /* in order to always have memory for the
52
                             first signal, we put it here */
53
};
54

    
55
static struct emulated_sigaction sigact_table[TARGET_NSIG];
56
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
57
static struct sigqueue *first_free; /* first free siginfo queue entry */
58
static int signal_pending; /* non zero if a signal may be pending */
59

    
60
static void host_signal_handler(int host_signum, siginfo_t *info, 
61
                                void *puc);
62

    
63
/* XXX: do it properly */
64
static inline int host_to_target_signal(int sig)
65
{
66
    return sig;
67
}
68

    
69
static inline int target_to_host_signal(int sig)
70
{
71
    return sig;
72
}
73

    
74
void host_to_target_sigset(target_sigset_t *d, sigset_t *s)
75
{
76
    int i;
77
    for(i = 0;i < TARGET_NSIG_WORDS; i++) {
78
        d->sig[i] = tswapl(((unsigned long *)s)[i]);
79
    }
80
}
81

    
82
void target_to_host_sigset(sigset_t *d, target_sigset_t *s)
83
{
84
    int i;
85
    for(i = 0;i < TARGET_NSIG_WORDS; i++) {
86
        ((unsigned long *)d)[i] = tswapl(s->sig[i]);
87
    }
88
}
89

    
90
void host_to_target_old_sigset(target_ulong *old_sigset, 
91
                               const sigset_t *sigset)
92
{
93
    *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
94
}
95

    
96
void target_to_host_old_sigset(sigset_t *sigset, 
97
                               const target_ulong *old_sigset)
98
{
99
    sigemptyset(sigset);
100
    *(unsigned long *)sigset = tswapl(*old_sigset);
101
}
102

    
103
/* siginfo conversion */
104

    
105
static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, 
106
                                                 const siginfo_t *info)
107
{
108
    int sig;
109
    sig = host_to_target_signal(info->si_signo);
110
    tinfo->si_signo = sig;
111
    tinfo->si_errno = 0;
112
    tinfo->si_code = 0;
113
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || 
114
        sig == SIGBUS || sig == SIGTRAP) {
115
        /* should never come here, but who knows. The information for
116
           the target is irrelevant */
117
        tinfo->_sifields._sigfault._addr = 0;
118
    } else if (sig >= TARGET_SIGRTMIN) {
119
        tinfo->_sifields._rt._pid = info->si_pid;
120
        tinfo->_sifields._rt._uid = info->si_uid;
121
        /* XXX: potential problem if 64 bit */
122
        tinfo->_sifields._rt._sigval.sival_ptr = 
123
            (target_ulong)info->si_value.sival_ptr;
124
    }
125
}
126

    
127
static void tswap_siginfo(target_siginfo_t *tinfo, 
128
                          const target_siginfo_t *info)
129
{
130
    int sig;
131
    sig = info->si_signo;
132
    tinfo->si_signo = tswap32(sig);
133
    tinfo->si_errno = tswap32(info->si_errno);
134
    tinfo->si_code = tswap32(info->si_code);
135
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || 
136
        sig == SIGBUS || sig == SIGTRAP) {
137
        tinfo->_sifields._sigfault._addr = 
138
            tswapl(info->_sifields._sigfault._addr);
139
    } else if (sig >= TARGET_SIGRTMIN) {
140
        tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
141
        tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
142
        tinfo->_sifields._rt._sigval.sival_ptr = 
143
            tswapl(info->_sifields._rt._sigval.sival_ptr);
144
    }
145
}
146

    
147

    
148
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
149
{
150
    host_to_target_siginfo_noswap(tinfo, info);
151
    tswap_siginfo(tinfo, tinfo);
152
}
153

    
154
/* XXX: we support only POSIX RT signals are used. */
155
/* XXX: find a solution for 64 bit (additionnal malloced data is needed) */
156
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
157
{
158
    info->si_signo = tswap32(tinfo->si_signo);
159
    info->si_errno = tswap32(tinfo->si_errno);
160
    info->si_code = tswap32(tinfo->si_code);
161
    info->si_pid = tswap32(tinfo->_sifields._rt._pid);
162
    info->si_uid = tswap32(tinfo->_sifields._rt._uid);
163
    info->si_value.sival_ptr = 
164
        (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
165
}
166

    
167
void signal_init(void)
168
{
169
    struct sigaction act;
170
    int i;
171

    
172
    /* set all host signal handlers. ALL signals are blocked during
173
       the handlers to serialize them. */
174
    sigfillset(&act.sa_mask);
175
    act.sa_flags = SA_SIGINFO;
176
    act.sa_sigaction = host_signal_handler;
177
    for(i = 1; i < NSIG; i++) {
178
        sigaction(i, &act, NULL);
179
    }
180
    
181
    memset(sigact_table, 0, sizeof(sigact_table));
182

    
183
    first_free = &sigqueue_table[0];
184
    for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) 
185
        sigqueue_table[i].next = &sigqueue_table[i + 1];
186
    sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
187
}
188

    
189
/* signal queue handling */
190

    
191
static inline struct sigqueue *alloc_sigqueue(void)
192
{
193
    struct sigqueue *q = first_free;
194
    if (!q)
195
        return NULL;
196
    first_free = q->next;
197
    return q;
198
}
199

    
200
static inline void free_sigqueue(struct sigqueue *q)
201
{
202
    q->next = first_free;
203
    first_free = q;
204
}
205

    
206
/* abort execution with signal */
207
void __attribute((noreturn)) force_sig(int sig)
208
{
209
    int host_sig;
210
    host_sig = target_to_host_signal(sig);
211
    fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n", 
212
            sig, strsignal(host_sig));
213
#if 1
214
    _exit(-host_sig);
215
#else
216
    {
217
        struct sigaction act;
218
        sigemptyset(&act.sa_mask);
219
        act.sa_flags = SA_SIGINFO;
220
        act.sa_sigaction = SIG_DFL;
221
        sigaction(SIGABRT, &act, NULL);
222
        abort();
223
    }
224
#endif
225
}
226

    
227
/* queue a signal so that it will be send to the virtual CPU as soon
228
   as possible */
229
int queue_signal(int sig, target_siginfo_t *info)
230
{
231
    struct emulated_sigaction *k;
232
    struct sigqueue *q, **pq;
233
    target_ulong handler;
234

    
235
#if defined(DEBUG_SIGNAL)
236
    fprintf(stderr, "queue_signal: sig=%d\n", 
237
            sig);
238
#endif
239
    k = &sigact_table[sig - 1];
240
    handler = k->sa._sa_handler;
241
    if (handler == TARGET_SIG_DFL) {
242
        /* default handler : ignore some signal. The other are fatal */
243
        if (sig != TARGET_SIGCHLD && 
244
            sig != TARGET_SIGURG && 
245
            sig != TARGET_SIGWINCH) {
246
            force_sig(sig);
247
        } else {
248
            return 0; /* indicate ignored */
249
        }
250
    } else if (handler == TARGET_SIG_IGN) {
251
        /* ignore signal */
252
        return 0;
253
    } else if (handler == TARGET_SIG_ERR) {
254
        force_sig(sig);
255
    } else {
256
        pq = &k->first;
257
        if (sig < TARGET_SIGRTMIN) {
258
            /* if non real time signal, we queue exactly one signal */
259
            if (!k->pending)
260
                q = &k->info;
261
            else
262
                return 0;
263
        } else {
264
            if (!k->pending) {
265
                /* first signal */
266
                q = &k->info;
267
            } else {
268
                q = alloc_sigqueue();
269
                if (!q)
270
                    return -EAGAIN;
271
                while (*pq != NULL)
272
                    pq = &(*pq)->next;
273
            }
274
        }
275
        *pq = q;
276
        q->info = *info;
277
        q->next = NULL;
278
        k->pending = 1;
279
        /* signal that a new signal is pending */
280
        signal_pending = 1;
281
        return 1; /* indicates that the signal was queued */
282
    }
283
}
284

    
285
#if defined(DEBUG_SIGNAL)
286
#ifdef __i386__
287
static void dump_regs(struct ucontext *uc)
288
{
289
    fprintf(stderr, 
290
            "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
291
            "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
292
            "EFL=%08x EIP=%08x\n",
293
            uc->uc_mcontext.gregs[EAX],
294
            uc->uc_mcontext.gregs[EBX],
295
            uc->uc_mcontext.gregs[ECX],
296
            uc->uc_mcontext.gregs[EDX],
297
            uc->uc_mcontext.gregs[ESI],
298
            uc->uc_mcontext.gregs[EDI],
299
            uc->uc_mcontext.gregs[EBP],
300
            uc->uc_mcontext.gregs[ESP],
301
            uc->uc_mcontext.gregs[EFL],
302
            uc->uc_mcontext.gregs[EIP]);
303
}
304
#else
305
static void dump_regs(struct ucontext *uc)
306
{
307
}
308
#endif
309

    
310
#endif
311

    
312
static void host_signal_handler(int host_signum, siginfo_t *info, 
313
                                void *puc)
314
{
315
    int sig;
316
    target_siginfo_t tinfo;
317

    
318
    /* the CPU emulator uses some host signals to detect exceptions,
319
       we we forward to it some signals */
320
    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
321
        if (cpu_x86_signal_handler(host_signum, info, puc))
322
            return;
323
    }
324

    
325
    /* get target signal number */
326
    sig = host_to_target_signal(host_signum);
327
    if (sig < 1 || sig > TARGET_NSIG)
328
        return;
329
#if defined(DEBUG_SIGNAL)
330
    fprintf(stderr, "qemu: got signal %d\n", sig);
331
    dump_regs(puc);
332
#endif
333
    host_to_target_siginfo_noswap(&tinfo, info);
334
    if (queue_signal(sig, &tinfo) == 1) {
335
        /* interrupt the virtual CPU as soon as possible */
336
        cpu_x86_interrupt(global_env);
337
    }
338
}
339

    
340
int do_sigaction(int sig, const struct target_sigaction *act,
341
                 struct target_sigaction *oact)
342
{
343
    struct emulated_sigaction *k;
344

    
345
    if (sig < 1 || sig > TARGET_NSIG)
346
        return -EINVAL;
347
    k = &sigact_table[sig - 1];
348
#if defined(DEBUG_SIGNAL) && 0
349
    fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", 
350
            sig, (int)act, (int)oact);
351
#endif
352
    if (oact) {
353
        oact->_sa_handler = tswapl(k->sa._sa_handler);
354
        oact->sa_flags = tswapl(k->sa.sa_flags);
355
        oact->sa_restorer = tswapl(k->sa.sa_restorer);
356
        oact->sa_mask = k->sa.sa_mask;
357
    }
358
    if (act) {
359
        k->sa._sa_handler = tswapl(act->_sa_handler);
360
        k->sa.sa_flags = tswapl(act->sa_flags);
361
        k->sa.sa_restorer = tswapl(act->sa_restorer);
362
        k->sa.sa_mask = act->sa_mask;
363
    }
364
    return 0;
365
}
366

    
367
#ifdef TARGET_I386
368

    
369
/* from the Linux kernel */
370

    
371
struct target_fpreg {
372
        uint16_t significand[4];
373
        uint16_t exponent;
374
};
375

    
376
struct target_fpxreg {
377
        uint16_t significand[4];
378
        uint16_t exponent;
379
        uint16_t padding[3];
380
};
381

    
382
struct target_xmmreg {
383
        target_ulong element[4];
384
};
385

    
386
struct target_fpstate {
387
        /* Regular FPU environment */
388
        target_ulong         cw;
389
        target_ulong        sw;
390
        target_ulong        tag;
391
        target_ulong        ipoff;
392
        target_ulong        cssel;
393
        target_ulong        dataoff;
394
        target_ulong        datasel;
395
        struct target_fpreg        _st[8];
396
        uint16_t        status;
397
        uint16_t        magic;                /* 0xffff = regular FPU data only */
398

    
399
        /* FXSR FPU environment */
400
        target_ulong        _fxsr_env[6];        /* FXSR FPU env is ignored */
401
        target_ulong        mxcsr;
402
        target_ulong        reserved;
403
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
404
        struct target_xmmreg        _xmm[8];
405
        target_ulong        padding[56];
406
};
407

    
408
#define X86_FXSR_MAGIC                0x0000
409

    
410
struct target_sigcontext {
411
        uint16_t gs, __gsh;
412
        uint16_t fs, __fsh;
413
        uint16_t es, __esh;
414
        uint16_t ds, __dsh;
415
        target_ulong edi;
416
        target_ulong esi;
417
        target_ulong ebp;
418
        target_ulong esp;
419
        target_ulong ebx;
420
        target_ulong edx;
421
        target_ulong ecx;
422
        target_ulong eax;
423
        target_ulong trapno;
424
        target_ulong err;
425
        target_ulong eip;
426
        uint16_t cs, __csh;
427
        target_ulong eflags;
428
        target_ulong esp_at_signal;
429
        uint16_t ss, __ssh;
430
        target_ulong fpstate; /* pointer */
431
        target_ulong oldmask;
432
        target_ulong cr2;
433
};
434

    
435
typedef struct target_sigaltstack {
436
        target_ulong ss_sp;
437
        int ss_flags;
438
        target_ulong ss_size;
439
} target_stack_t;
440

    
441
struct target_ucontext {
442
        target_ulong          uc_flags;
443
        target_ulong      uc_link;
444
        target_stack_t          uc_stack;
445
        struct target_sigcontext uc_mcontext;
446
        target_sigset_t          uc_sigmask;        /* mask last for extensibility */
447
};
448

    
449
struct sigframe
450
{
451
    target_ulong pretcode;
452
    int sig;
453
    struct target_sigcontext sc;
454
    struct target_fpstate fpstate;
455
    target_ulong extramask[TARGET_NSIG_WORDS-1];
456
    char retcode[8];
457
};
458

    
459
struct rt_sigframe
460
{
461
    target_ulong pretcode;
462
    int sig;
463
    target_ulong pinfo;
464
    target_ulong puc;
465
    struct target_siginfo info;
466
    struct target_ucontext uc;
467
    struct target_fpstate fpstate;
468
    char retcode[8];
469
};
470

    
471
/*
472
 * Set up a signal frame.
473
 */
474

    
475
#define __put_user(x,ptr)\
476
({\
477
    int size = sizeof(*ptr);\
478
    switch(size) {\
479
    case 1:\
480
        stb(ptr, (typeof(*ptr))(x));\
481
        break;\
482
    case 2:\
483
        stw(ptr, (typeof(*ptr))(x));\
484
        break;\
485
    case 4:\
486
        stl(ptr, (typeof(*ptr))(x));\
487
        break;\
488
    case 8:\
489
        stq(ptr, (typeof(*ptr))(x));\
490
        break;\
491
    default:\
492
        abort();\
493
    }\
494
    0;\
495
})
496

    
497
#define get_user(val, ptr) (typeof(*ptr))(*(ptr))
498

    
499

    
500
#define __copy_to_user(dst, src, size)\
501
({\
502
    memcpy(dst, src, size);\
503
    0;\
504
})
505

    
506
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, 
507
                                       const target_siginfo_t *info)
508
{
509
    tswap_siginfo(tinfo, info);
510
    return 0;
511
}
512

    
513
/* XXX: save x87 state */
514
static int
515
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
516
                 CPUX86State *env, unsigned long mask)
517
{
518
        int err = 0;
519

    
520
        err |= __put_user(env->segs[R_GS], (unsigned int *)&sc->gs);
521
        err |= __put_user(env->segs[R_FS], (unsigned int *)&sc->fs);
522
        err |= __put_user(env->segs[R_ES], (unsigned int *)&sc->es);
523
        err |= __put_user(env->segs[R_DS], (unsigned int *)&sc->ds);
524
        err |= __put_user(env->regs[R_EDI], &sc->edi);
525
        err |= __put_user(env->regs[R_ESI], &sc->esi);
526
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
527
        err |= __put_user(env->regs[R_ESP], &sc->esp);
528
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
529
        err |= __put_user(env->regs[R_EDX], &sc->edx);
530
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
531
        err |= __put_user(env->regs[R_EAX], &sc->eax);
532
        err |= __put_user(env->exception_index, &sc->trapno);
533
        err |= __put_user(env->error_code, &sc->err);
534
        err |= __put_user(env->eip, &sc->eip);
535
        err |= __put_user(env->segs[R_CS], (unsigned int *)&sc->cs);
536
        err |= __put_user(env->eflags, &sc->eflags);
537
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
538
        err |= __put_user(env->segs[R_SS], (unsigned int *)&sc->ss);
539
#if 0
540
        tmp = save_i387(fpstate);
541
        if (tmp < 0)
542
          err = 1;
543
        else
544
          err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
545
#else
546
        err |= __put_user(0, &sc->fpstate);
547
#endif
548
        /* non-iBCS2 extensions.. */
549
        err |= __put_user(mask, &sc->oldmask);
550
        err |= __put_user(/*current->thread.cr2*/ 0, &sc->cr2);
551
        return err;
552
}
553

    
554
/*
555
 * Determine which stack to use..
556
 */
557

    
558
static inline void *
559
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
560
{
561
        unsigned long esp;
562

    
563
        /* Default to using normal stack */
564
        esp = env->regs[R_ESP];
565
#if 0
566
        /* This is the X/Open sanctioned signal stack switching.  */
567
        if (ka->sa.sa_flags & SA_ONSTACK) {
568
                if (sas_ss_flags(esp) == 0)
569
                        esp = current->sas_ss_sp + current->sas_ss_size;
570
        }
571

572
        /* This is the legacy signal stack switching. */
573
        else if ((regs->xss & 0xffff) != __USER_DS &&
574
                 !(ka->sa.sa_flags & SA_RESTORER) &&
575
                 ka->sa.sa_restorer) {
576
                esp = (unsigned long) ka->sa.sa_restorer;
577
        }
578
#endif
579
        return (void *)((esp - frame_size) & -8ul);
580
}
581

    
582
static void setup_frame(int sig, struct emulated_sigaction *ka,
583
                        target_sigset_t *set, CPUX86State *env)
584
{
585
        struct sigframe *frame;
586
        int err = 0;
587

    
588
        frame = get_sigframe(ka, env, sizeof(*frame));
589

    
590
#if 0
591
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
592
                goto give_sigsegv;
593
#endif
594
        err |= __put_user((/*current->exec_domain
595
                           && current->exec_domain->signal_invmap
596
                           && sig < 32
597
                           ? current->exec_domain->signal_invmap[sig]
598
                           : */ sig),
599
                          &frame->sig);
600
        if (err)
601
                goto give_sigsegv;
602

    
603
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
604
        if (err)
605
                goto give_sigsegv;
606

    
607
        if (TARGET_NSIG_WORDS > 1) {
608
                err |= __copy_to_user(frame->extramask, &set->sig[1],
609
                                      sizeof(frame->extramask));
610
        }
611
        if (err)
612
                goto give_sigsegv;
613

    
614
        /* Set up to return from userspace.  If provided, use a stub
615
           already in userspace.  */
616
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
617
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
618
        } else {
619
                err |= __put_user(frame->retcode, &frame->pretcode);
620
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
621
                err |= __put_user(0xb858, (short *)(frame->retcode+0));
622
                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
623
                err |= __put_user(0x80cd, (short *)(frame->retcode+6));
624
        }
625

    
626
        if (err)
627
                goto give_sigsegv;
628

    
629
        /* Set up registers for signal handler */
630
        env->regs[R_ESP] = (unsigned long) frame;
631
        env->eip = (unsigned long) ka->sa._sa_handler;
632

    
633
        cpu_x86_load_seg(env, R_DS, __USER_DS);
634
        cpu_x86_load_seg(env, R_ES, __USER_DS);
635
        cpu_x86_load_seg(env, R_SS, __USER_DS);
636
        cpu_x86_load_seg(env, R_CS, __USER_CS);
637
        env->eflags &= ~TF_MASK;
638

    
639
        return;
640

    
641
give_sigsegv:
642
        if (sig == TARGET_SIGSEGV)
643
                ka->sa._sa_handler = TARGET_SIG_DFL;
644
        force_sig(TARGET_SIGSEGV /* , current */);
645
}
646

    
647
static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
648
                           target_siginfo_t *info,
649
                           target_sigset_t *set, CPUX86State *env)
650
{
651
        struct rt_sigframe *frame;
652
        int err = 0;
653

    
654
        frame = get_sigframe(ka, env, sizeof(*frame));
655

    
656
#if 0
657
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
658
                goto give_sigsegv;
659
#endif
660

    
661
        err |= __put_user((/*current->exec_domain
662
                               && current->exec_domain->signal_invmap
663
                               && sig < 32
664
                               ? current->exec_domain->signal_invmap[sig]
665
                           : */sig),
666
                          &frame->sig);
667
        err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
668
        err |= __put_user((target_ulong)&frame->uc, &frame->puc);
669
        err |= copy_siginfo_to_user(&frame->info, info);
670
        if (err)
671
                goto give_sigsegv;
672

    
673
        /* Create the ucontext.  */
674
        err |= __put_user(0, &frame->uc.uc_flags);
675
        err |= __put_user(0, &frame->uc.uc_link);
676
        err |= __put_user(/*current->sas_ss_sp*/ 0, &frame->uc.uc_stack.ss_sp);
677
        err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
678
                          &frame->uc.uc_stack.ss_flags);
679
        err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size);
680
        err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
681
                                env, set->sig[0]);
682
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
683
        if (err)
684
                goto give_sigsegv;
685

    
686
        /* Set up to return from userspace.  If provided, use a stub
687
           already in userspace.  */
688
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
689
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
690
        } else {
691
                err |= __put_user(frame->retcode, &frame->pretcode);
692
                /* This is movl $,%eax ; int $0x80 */
693
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
694
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
695
                err |= __put_user(0x80cd, (short *)(frame->retcode+5));
696
        }
697

    
698
        if (err)
699
                goto give_sigsegv;
700

    
701
        /* Set up registers for signal handler */
702
        env->regs[R_ESP] = (unsigned long) frame;
703
        env->eip = (unsigned long) ka->sa._sa_handler;
704

    
705
        cpu_x86_load_seg(env, R_DS, __USER_DS);
706
        cpu_x86_load_seg(env, R_ES, __USER_DS);
707
        cpu_x86_load_seg(env, R_SS, __USER_DS);
708
        cpu_x86_load_seg(env, R_CS, __USER_CS);
709
        env->eflags &= ~TF_MASK;
710

    
711
        return;
712

    
713
give_sigsegv:
714
        if (sig == TARGET_SIGSEGV)
715
                ka->sa._sa_handler = TARGET_SIG_DFL;
716
        force_sig(TARGET_SIGSEGV /* , current */);
717
}
718

    
719
static int
720
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
721
{
722
        unsigned int err = 0;
723

    
724

    
725
        
726
#define COPY(x)                err |= __get_user(regs->x, &sc->x)
727

    
728
#define COPY_SEG(seg)                                                        \
729
        { unsigned short tmp;                                                \
730
          err |= __get_user(tmp, &sc->seg);                                \
731
          regs->x##seg = tmp; }
732

    
733
#define COPY_SEG_STRICT(seg)                                                \
734
        { unsigned short tmp;                                                \
735
          err |= __get_user(tmp, &sc->seg);                                \
736
          regs->x##seg = tmp|3; }
737

    
738
#define GET_SEG(seg)                                                        \
739
        { unsigned short tmp;                                                \
740
          err |= __get_user(tmp, &sc->seg);                                \
741
          loadsegment(seg,tmp); }
742

    
743
        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
744
        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
745
        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
746
        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
747

    
748
        env->regs[R_EDI] = ldl(&sc->edi);
749
        env->regs[R_ESI] = ldl(&sc->esi);
750
        env->regs[R_EBP] = ldl(&sc->ebp);
751
        env->regs[R_ESP] = ldl(&sc->esp);
752
        env->regs[R_EBX] = ldl(&sc->ebx);
753
        env->regs[R_EDX] = ldl(&sc->edx);
754
        env->regs[R_ECX] = ldl(&sc->ecx);
755
        env->eip = ldl(&sc->eip);
756

    
757
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
758
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
759
        
760
        {
761
                unsigned int tmpflags;
762
                tmpflags = ldl(&sc->eflags);
763
                env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
764
                //                regs->orig_eax = -1;                /* disable syscall checks */
765
        }
766

    
767
#if 0
768
        {
769
                struct _fpstate * buf;
770
                err |= __get_user(buf, &sc->fpstate);
771
                if (buf) {
772
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
773
                                goto badframe;
774
                        err |= restore_i387(buf);
775
                }
776
        }
777
#endif
778
        *peax = ldl(&sc->eax);
779
        return err;
780
#if 0
781
badframe:
782
        return 1;
783
#endif
784
}
785

    
786
long do_sigreturn(CPUX86State *env)
787
{
788
    struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
789
    target_sigset_t target_set;
790
    sigset_t set;
791
    int eax, i;
792

    
793
#if defined(DEBUG_SIGNAL)
794
    fprintf(stderr, "do_sigreturn\n");
795
#endif
796
    /* set blocked signals */
797
    target_set.sig[0] = frame->sc.oldmask;
798
    for(i = 1; i < TARGET_NSIG_WORDS; i++)
799
        target_set.sig[i] = frame->extramask[i - 1];
800

    
801
    target_to_host_sigset(&set, &target_set);
802
    sigprocmask(SIG_SETMASK, &set, NULL);
803
    
804
    /* restore registers */
805
    if (restore_sigcontext(env, &frame->sc, &eax))
806
        goto badframe;
807
    return eax;
808

    
809
badframe:
810
    force_sig(TARGET_SIGSEGV);
811
    return 0;
812
}
813

    
814
long do_rt_sigreturn(CPUX86State *env)
815
{
816
        struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
817
        target_sigset_t target_set;
818
        sigset_t set;
819
        //        stack_t st;
820
        int eax;
821

    
822
#if 0
823
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
824
                goto badframe;
825
#endif
826
        memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
827

    
828
        target_to_host_sigset(&set, &target_set);
829
        sigprocmask(SIG_SETMASK, &set, NULL);
830
        
831
        if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
832
                goto badframe;
833

    
834
#if 0
835
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
836
                goto badframe;
837
        /* It is more difficult to avoid calling this function than to
838
           call it and ignore errors.  */
839
        do_sigaltstack(&st, NULL, regs->esp);
840
#endif
841
        return eax;
842

    
843
badframe:
844
        force_sig(TARGET_SIGSEGV);
845
        return 0;
846
}
847

    
848
#endif
849

    
850
void process_pending_signals(void *cpu_env)
851
{
852
    int sig;
853
    target_ulong handler;
854
    sigset_t set, old_set;
855
    target_sigset_t target_old_set;
856
    struct emulated_sigaction *k;
857
    struct sigqueue *q;
858
    
859
    if (!signal_pending)
860
        return;
861

    
862
    k = sigact_table;
863
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
864
        if (k->pending)
865
            goto handle_signal;
866
        k++;
867
    }
868
    /* if no signal is pending, just return */
869
    signal_pending = 0;
870
    return;
871

    
872
 handle_signal:
873
#ifdef DEBUG_SIGNAL
874
    fprintf(stderr, "qemu: process signal %d\n", sig);
875
#endif
876
    /* dequeue signal */
877
    q = k->first;
878
    k->first = q->next;
879
    if (!k->first)
880
        k->pending = 0;
881

    
882
    handler = k->sa._sa_handler;
883
    if (handler == TARGET_SIG_DFL) {
884
        /* default handler : ignore some signal. The other are fatal */
885
        if (sig != TARGET_SIGCHLD && 
886
            sig != TARGET_SIGURG && 
887
            sig != TARGET_SIGWINCH) {
888
            force_sig(sig);
889
        }
890
    } else if (handler == TARGET_SIG_IGN) {
891
        /* ignore sig */
892
    } else if (handler == TARGET_SIG_ERR) {
893
        force_sig(sig);
894
    } else {
895
        /* compute the blocked signals during the handler execution */
896
        target_to_host_sigset(&set, &k->sa.sa_mask);
897
        /* SA_NODEFER indicates that the current signal should not be
898
           blocked during the handler */
899
        if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
900
            sigaddset(&set, target_to_host_signal(sig));
901
        
902
        /* block signals in the handler using Linux */
903
        sigprocmask(SIG_BLOCK, &set, &old_set);
904
        /* save the previous blocked signal state to restore it at the
905
           end of the signal execution (see do_sigreturn) */
906
        host_to_target_sigset(&target_old_set, &old_set);
907

    
908
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
909
#ifdef TARGET_I386
910
        {
911
            CPUX86State *env = cpu_env;
912
            if (env->eflags & VM_MASK)
913
                save_v86_state(env);
914
        }
915
#endif
916
        /* prepare the stack frame of the virtual CPU */
917
        if (k->sa.sa_flags & TARGET_SA_SIGINFO)
918
            setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
919
        else
920
            setup_frame(sig, k, &target_old_set, cpu_env);
921
        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
922
            k->sa._sa_handler = TARGET_SIG_DFL;
923
    }
924
    if (q != &k->info)
925
        free_sigqueue(q);
926
}
927

    
928