Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 43fff238

History | View | Annotate | Download (35.4 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_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_interrupt(global_env, CPU_INTERRUPT_EXIT);
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
#define __put_user(x,ptr)\
368
({\
369
    int size = sizeof(*ptr);\
370
    switch(size) {\
371
    case 1:\
372
        stb(ptr, (typeof(*ptr))(x));\
373
        break;\
374
    case 2:\
375
        stw(ptr, (typeof(*ptr))(x));\
376
        break;\
377
    case 4:\
378
        stl(ptr, (typeof(*ptr))(x));\
379
        break;\
380
    case 8:\
381
        stq(ptr, (typeof(*ptr))(x));\
382
        break;\
383
    default:\
384
        abort();\
385
    }\
386
    0;\
387
})
388

    
389
#define __get_user(x, ptr) \
390
({\
391
    int size = sizeof(*ptr);\
392
    switch(size) {\
393
    case 1:\
394
        x = (typeof(*ptr))ldub(ptr);\
395
        break;\
396
    case 2:\
397
        x = (typeof(*ptr))lduw(ptr);\
398
        break;\
399
    case 4:\
400
        x = (typeof(*ptr))ldl(ptr);\
401
        break;\
402
    case 8:\
403
        x = (typeof(*ptr))ldq(ptr);\
404
        break;\
405
    default:\
406
        abort();\
407
    }\
408
    0;\
409
})
410

    
411

    
412
#define __copy_to_user(dst, src, size)\
413
({\
414
    memcpy(dst, src, size);\
415
    0;\
416
})
417

    
418
#define __copy_from_user(dst, src, size)\
419
({\
420
    memcpy(dst, src, size);\
421
    0;\
422
})
423

    
424
#define __clear_user(dst, size)\
425
({\
426
    memset(dst, 0, size);\
427
    0;\
428
})
429

    
430
#ifndef offsetof
431
#define offsetof(type, field) ((size_t) &((type *)0)->field)
432
#endif
433

    
434
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, 
435
                                       const target_siginfo_t *info)
436
{
437
    tswap_siginfo(tinfo, info);
438
    return 0;
439
}
440

    
441
#ifdef TARGET_I386
442

    
443
/* from the Linux kernel */
444

    
445
struct target_fpreg {
446
        uint16_t significand[4];
447
        uint16_t exponent;
448
};
449

    
450
struct target_fpxreg {
451
        uint16_t significand[4];
452
        uint16_t exponent;
453
        uint16_t padding[3];
454
};
455

    
456
struct target_xmmreg {
457
        target_ulong element[4];
458
};
459

    
460
struct target_fpstate {
461
        /* Regular FPU environment */
462
        target_ulong         cw;
463
        target_ulong        sw;
464
        target_ulong        tag;
465
        target_ulong        ipoff;
466
        target_ulong        cssel;
467
        target_ulong        dataoff;
468
        target_ulong        datasel;
469
        struct target_fpreg        _st[8];
470
        uint16_t        status;
471
        uint16_t        magic;                /* 0xffff = regular FPU data only */
472

    
473
        /* FXSR FPU environment */
474
        target_ulong        _fxsr_env[6];        /* FXSR FPU env is ignored */
475
        target_ulong        mxcsr;
476
        target_ulong        reserved;
477
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
478
        struct target_xmmreg        _xmm[8];
479
        target_ulong        padding[56];
480
};
481

    
482
#define X86_FXSR_MAGIC                0x0000
483

    
484
struct target_sigcontext {
485
        uint16_t gs, __gsh;
486
        uint16_t fs, __fsh;
487
        uint16_t es, __esh;
488
        uint16_t ds, __dsh;
489
        target_ulong edi;
490
        target_ulong esi;
491
        target_ulong ebp;
492
        target_ulong esp;
493
        target_ulong ebx;
494
        target_ulong edx;
495
        target_ulong ecx;
496
        target_ulong eax;
497
        target_ulong trapno;
498
        target_ulong err;
499
        target_ulong eip;
500
        uint16_t cs, __csh;
501
        target_ulong eflags;
502
        target_ulong esp_at_signal;
503
        uint16_t ss, __ssh;
504
        target_ulong fpstate; /* pointer */
505
        target_ulong oldmask;
506
        target_ulong cr2;
507
};
508

    
509
typedef struct target_sigaltstack {
510
        target_ulong ss_sp;
511
        int ss_flags;
512
        target_ulong ss_size;
513
} target_stack_t;
514

    
515
struct target_ucontext {
516
        target_ulong          uc_flags;
517
        target_ulong      uc_link;
518
        target_stack_t          uc_stack;
519
        struct target_sigcontext uc_mcontext;
520
        target_sigset_t          uc_sigmask;        /* mask last for extensibility */
521
};
522

    
523
struct sigframe
524
{
525
    target_ulong pretcode;
526
    int sig;
527
    struct target_sigcontext sc;
528
    struct target_fpstate fpstate;
529
    target_ulong extramask[TARGET_NSIG_WORDS-1];
530
    char retcode[8];
531
};
532

    
533
struct rt_sigframe
534
{
535
    target_ulong pretcode;
536
    int sig;
537
    target_ulong pinfo;
538
    target_ulong puc;
539
    struct target_siginfo info;
540
    struct target_ucontext uc;
541
    struct target_fpstate fpstate;
542
    char retcode[8];
543
};
544

    
545
/*
546
 * Set up a signal frame.
547
 */
548

    
549
/* XXX: save x87 state */
550
static int
551
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
552
                 CPUX86State *env, unsigned long mask)
553
{
554
        int err = 0;
555

    
556
        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
557
        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
558
        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
559
        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
560
        err |= __put_user(env->regs[R_EDI], &sc->edi);
561
        err |= __put_user(env->regs[R_ESI], &sc->esi);
562
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
563
        err |= __put_user(env->regs[R_ESP], &sc->esp);
564
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
565
        err |= __put_user(env->regs[R_EDX], &sc->edx);
566
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
567
        err |= __put_user(env->regs[R_EAX], &sc->eax);
568
        err |= __put_user(env->exception_index, &sc->trapno);
569
        err |= __put_user(env->error_code, &sc->err);
570
        err |= __put_user(env->eip, &sc->eip);
571
        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
572
        err |= __put_user(env->eflags, &sc->eflags);
573
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
574
        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
575

    
576
        cpu_x86_fsave(env, (void *)fpstate, 1);
577
        fpstate->status = fpstate->sw;
578
        err |= __put_user(0xffff, &fpstate->magic);
579
        err |= __put_user(fpstate, &sc->fpstate);
580

    
581
        /* non-iBCS2 extensions.. */
582
        err |= __put_user(mask, &sc->oldmask);
583
        err |= __put_user(env->cr[2], &sc->cr2);
584
        return err;
585
}
586

    
587
/*
588
 * Determine which stack to use..
589
 */
590

    
591
static inline void *
592
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
593
{
594
        unsigned long esp;
595

    
596
        /* Default to using normal stack */
597
        esp = env->regs[R_ESP];
598
#if 0
599
        /* This is the X/Open sanctioned signal stack switching.  */
600
        if (ka->sa.sa_flags & SA_ONSTACK) {
601
                if (sas_ss_flags(esp) == 0)
602
                        esp = current->sas_ss_sp + current->sas_ss_size;
603
        }
604

605
        /* This is the legacy signal stack switching. */
606
        else 
607
#endif
608
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
609
            !(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
610
            ka->sa.sa_restorer) {
611
            esp = (unsigned long) ka->sa.sa_restorer;
612
        }
613
        return (void *)((esp - frame_size) & -8ul);
614
}
615

    
616
static void setup_frame(int sig, struct emulated_sigaction *ka,
617
                        target_sigset_t *set, CPUX86State *env)
618
{
619
        struct sigframe *frame;
620
        int err = 0;
621

    
622
        frame = get_sigframe(ka, env, sizeof(*frame));
623

    
624
#if 0
625
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
626
                goto give_sigsegv;
627
#endif
628
        err |= __put_user((/*current->exec_domain
629
                           && current->exec_domain->signal_invmap
630
                           && sig < 32
631
                           ? current->exec_domain->signal_invmap[sig]
632
                           : */ sig),
633
                          &frame->sig);
634
        if (err)
635
                goto give_sigsegv;
636

    
637
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
638
        if (err)
639
                goto give_sigsegv;
640

    
641
        if (TARGET_NSIG_WORDS > 1) {
642
                err |= __copy_to_user(frame->extramask, &set->sig[1],
643
                                      sizeof(frame->extramask));
644
        }
645
        if (err)
646
                goto give_sigsegv;
647

    
648
        /* Set up to return from userspace.  If provided, use a stub
649
           already in userspace.  */
650
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
651
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
652
        } else {
653
                err |= __put_user(frame->retcode, &frame->pretcode);
654
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
655
                err |= __put_user(0xb858, (short *)(frame->retcode+0));
656
                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
657
                err |= __put_user(0x80cd, (short *)(frame->retcode+6));
658
        }
659

    
660
        if (err)
661
                goto give_sigsegv;
662

    
663
        /* Set up registers for signal handler */
664
        env->regs[R_ESP] = (unsigned long) frame;
665
        env->eip = (unsigned long) ka->sa._sa_handler;
666

    
667
        cpu_x86_load_seg(env, R_DS, __USER_DS);
668
        cpu_x86_load_seg(env, R_ES, __USER_DS);
669
        cpu_x86_load_seg(env, R_SS, __USER_DS);
670
        cpu_x86_load_seg(env, R_CS, __USER_CS);
671
        env->eflags &= ~TF_MASK;
672

    
673
        return;
674

    
675
give_sigsegv:
676
        if (sig == TARGET_SIGSEGV)
677
                ka->sa._sa_handler = TARGET_SIG_DFL;
678
        force_sig(TARGET_SIGSEGV /* , current */);
679
}
680

    
681
static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
682
                           target_siginfo_t *info,
683
                           target_sigset_t *set, CPUX86State *env)
684
{
685
        struct rt_sigframe *frame;
686
        int err = 0;
687

    
688
        frame = get_sigframe(ka, env, sizeof(*frame));
689

    
690
#if 0
691
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
692
                goto give_sigsegv;
693
#endif
694

    
695
        err |= __put_user((/*current->exec_domain
696
                               && current->exec_domain->signal_invmap
697
                               && sig < 32
698
                               ? current->exec_domain->signal_invmap[sig]
699
                           : */sig),
700
                          &frame->sig);
701
        err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
702
        err |= __put_user((target_ulong)&frame->uc, &frame->puc);
703
        err |= copy_siginfo_to_user(&frame->info, info);
704
        if (err)
705
                goto give_sigsegv;
706

    
707
        /* Create the ucontext.  */
708
        err |= __put_user(0, &frame->uc.uc_flags);
709
        err |= __put_user(0, &frame->uc.uc_link);
710
        err |= __put_user(/*current->sas_ss_sp*/ 0, &frame->uc.uc_stack.ss_sp);
711
        err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
712
                          &frame->uc.uc_stack.ss_flags);
713
        err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size);
714
        err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
715
                                env, set->sig[0]);
716
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
717
        if (err)
718
                goto give_sigsegv;
719

    
720
        /* Set up to return from userspace.  If provided, use a stub
721
           already in userspace.  */
722
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
723
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
724
        } else {
725
                err |= __put_user(frame->retcode, &frame->pretcode);
726
                /* This is movl $,%eax ; int $0x80 */
727
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
728
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
729
                err |= __put_user(0x80cd, (short *)(frame->retcode+5));
730
        }
731

    
732
        if (err)
733
                goto give_sigsegv;
734

    
735
        /* Set up registers for signal handler */
736
        env->regs[R_ESP] = (unsigned long) frame;
737
        env->eip = (unsigned long) ka->sa._sa_handler;
738

    
739
        cpu_x86_load_seg(env, R_DS, __USER_DS);
740
        cpu_x86_load_seg(env, R_ES, __USER_DS);
741
        cpu_x86_load_seg(env, R_SS, __USER_DS);
742
        cpu_x86_load_seg(env, R_CS, __USER_CS);
743
        env->eflags &= ~TF_MASK;
744

    
745
        return;
746

    
747
give_sigsegv:
748
        if (sig == TARGET_SIGSEGV)
749
                ka->sa._sa_handler = TARGET_SIG_DFL;
750
        force_sig(TARGET_SIGSEGV /* , current */);
751
}
752

    
753
static int
754
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
755
{
756
        unsigned int err = 0;
757

    
758
        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
759
        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
760
        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
761
        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
762

    
763
        env->regs[R_EDI] = ldl(&sc->edi);
764
        env->regs[R_ESI] = ldl(&sc->esi);
765
        env->regs[R_EBP] = ldl(&sc->ebp);
766
        env->regs[R_ESP] = ldl(&sc->esp);
767
        env->regs[R_EBX] = ldl(&sc->ebx);
768
        env->regs[R_EDX] = ldl(&sc->edx);
769
        env->regs[R_ECX] = ldl(&sc->ecx);
770
        env->eip = ldl(&sc->eip);
771

    
772
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
773
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
774
        
775
        {
776
                unsigned int tmpflags;
777
                tmpflags = ldl(&sc->eflags);
778
                env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
779
                //                regs->orig_eax = -1;                /* disable syscall checks */
780
        }
781

    
782
        {
783
                struct _fpstate * buf;
784
                buf = (void *)ldl(&sc->fpstate);
785
                if (buf) {
786
#if 0
787
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
788
                                goto badframe;
789
#endif
790
                        cpu_x86_frstor(env, (void *)buf, 1);
791
                }
792
        }
793

    
794
        *peax = ldl(&sc->eax);
795
        return err;
796
#if 0
797
badframe:
798
        return 1;
799
#endif
800
}
801

    
802
long do_sigreturn(CPUX86State *env)
803
{
804
    struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
805
    target_sigset_t target_set;
806
    sigset_t set;
807
    int eax, i;
808

    
809
#if defined(DEBUG_SIGNAL)
810
    fprintf(stderr, "do_sigreturn\n");
811
#endif
812
    /* set blocked signals */
813
    target_set.sig[0] = frame->sc.oldmask;
814
    for(i = 1; i < TARGET_NSIG_WORDS; i++)
815
        target_set.sig[i] = frame->extramask[i - 1];
816

    
817
    target_to_host_sigset(&set, &target_set);
818
    sigprocmask(SIG_SETMASK, &set, NULL);
819
    
820
    /* restore registers */
821
    if (restore_sigcontext(env, &frame->sc, &eax))
822
        goto badframe;
823
    return eax;
824

    
825
badframe:
826
    force_sig(TARGET_SIGSEGV);
827
    return 0;
828
}
829

    
830
long do_rt_sigreturn(CPUX86State *env)
831
{
832
        struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
833
        target_sigset_t target_set;
834
        sigset_t set;
835
        //        stack_t st;
836
        int eax;
837

    
838
#if 0
839
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
840
                goto badframe;
841
#endif
842
        memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
843

    
844
        target_to_host_sigset(&set, &target_set);
845
        sigprocmask(SIG_SETMASK, &set, NULL);
846
        
847
        if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
848
                goto badframe;
849

    
850
#if 0
851
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
852
                goto badframe;
853
        /* It is more difficult to avoid calling this function than to
854
           call it and ignore errors.  */
855
        do_sigaltstack(&st, NULL, regs->esp);
856
#endif
857
        return eax;
858

    
859
badframe:
860
        force_sig(TARGET_SIGSEGV);
861
        return 0;
862
}
863

    
864
#elif defined(TARGET_ARM)
865

    
866
struct target_sigcontext {
867
        target_ulong trap_no;
868
        target_ulong error_code;
869
        target_ulong oldmask;
870
        target_ulong arm_r0;
871
        target_ulong arm_r1;
872
        target_ulong arm_r2;
873
        target_ulong arm_r3;
874
        target_ulong arm_r4;
875
        target_ulong arm_r5;
876
        target_ulong arm_r6;
877
        target_ulong arm_r7;
878
        target_ulong arm_r8;
879
        target_ulong arm_r9;
880
        target_ulong arm_r10;
881
        target_ulong arm_fp;
882
        target_ulong arm_ip;
883
        target_ulong arm_sp;
884
        target_ulong arm_lr;
885
        target_ulong arm_pc;
886
        target_ulong arm_cpsr;
887
        target_ulong fault_address;
888
};
889

    
890
typedef struct target_sigaltstack {
891
        target_ulong ss_sp;
892
        int ss_flags;
893
        target_ulong ss_size;
894
} target_stack_t;
895

    
896
struct target_ucontext {
897
    target_ulong uc_flags;
898
    target_ulong uc_link;
899
    target_stack_t uc_stack;
900
    struct target_sigcontext uc_mcontext;
901
    target_sigset_t  uc_sigmask;        /* mask last for extensibility */
902
};
903

    
904
struct sigframe
905
{
906
    struct target_sigcontext sc;
907
    target_ulong extramask[TARGET_NSIG_WORDS-1];
908
    target_ulong retcode;
909
};
910

    
911
struct rt_sigframe
912
{
913
    struct target_siginfo *pinfo;
914
    void *puc;
915
    struct target_siginfo info;
916
    struct target_ucontext uc;
917
    target_ulong retcode;
918
};
919

    
920
#define TARGET_CONFIG_CPU_32 1
921

    
922
/*
923
 * For ARM syscalls, we encode the syscall number into the instruction.
924
 */
925
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
926
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
927

    
928
/*
929
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
930
 * need two 16-bit instructions.
931
 */
932
#define SWI_THUMB_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
933
#define SWI_THUMB_RT_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
934

    
935
static const target_ulong retcodes[4] = {
936
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
937
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
938
};
939

    
940

    
941
#define __put_user_error(x,p,e) __put_user(x, p)
942
#define __get_user_error(x,p,e) __get_user(x, p)
943

    
944
static inline int valid_user_regs(CPUState *regs)
945
{
946
    return 1;
947
}
948

    
949
static int
950
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
951
                 CPUState *env, unsigned long mask)
952
{
953
        int err = 0;
954

    
955
        __put_user_error(env->regs[0], &sc->arm_r0, err);
956
        __put_user_error(env->regs[1], &sc->arm_r1, err);
957
        __put_user_error(env->regs[2], &sc->arm_r2, err);
958
        __put_user_error(env->regs[3], &sc->arm_r3, err);
959
        __put_user_error(env->regs[4], &sc->arm_r4, err);
960
        __put_user_error(env->regs[5], &sc->arm_r5, err);
961
        __put_user_error(env->regs[6], &sc->arm_r6, err);
962
        __put_user_error(env->regs[7], &sc->arm_r7, err);
963
        __put_user_error(env->regs[8], &sc->arm_r8, err);
964
        __put_user_error(env->regs[9], &sc->arm_r9, err);
965
        __put_user_error(env->regs[10], &sc->arm_r10, err);
966
        __put_user_error(env->regs[11], &sc->arm_fp, err);
967
        __put_user_error(env->regs[12], &sc->arm_ip, err);
968
        __put_user_error(env->regs[13], &sc->arm_sp, err);
969
        __put_user_error(env->regs[14], &sc->arm_lr, err);
970
        __put_user_error(env->regs[15], &sc->arm_pc, err);
971
#ifdef TARGET_CONFIG_CPU_32
972
        __put_user_error(env->cpsr, &sc->arm_cpsr, err);
973
#endif
974

    
975
        __put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err);
976
        __put_user_error(/* current->thread.error_code */ 0, &sc->error_code, err);
977
        __put_user_error(/* current->thread.address */ 0, &sc->fault_address, err);
978
        __put_user_error(mask, &sc->oldmask, err);
979

    
980
        return err;
981
}
982

    
983
static inline void *
984
get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
985
{
986
        unsigned long sp = regs->regs[13];
987

    
988
#if 0
989
        /*
990
         * This is the X/Open sanctioned signal stack switching.
991
         */
992
        if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
993
                sp = current->sas_ss_sp + current->sas_ss_size;
994
#endif
995
        /*
996
         * ATPCS B01 mandates 8-byte alignment
997
         */
998
        return (void *)((sp - framesize) & ~7);
999
}
1000

    
1001
static int
1002
setup_return(CPUState *env, struct emulated_sigaction *ka,
1003
             target_ulong *rc, void *frame, int usig)
1004
{
1005
        target_ulong handler = (target_ulong)ka->sa._sa_handler;
1006
        target_ulong retcode;
1007
        int thumb = 0;
1008
#if defined(TARGET_CONFIG_CPU_32)
1009
        target_ulong cpsr = env->cpsr;
1010

    
1011
#if 0
1012
        /*
1013
         * Maybe we need to deliver a 32-bit signal to a 26-bit task.
1014
         */
1015
        if (ka->sa.sa_flags & SA_THIRTYTWO)
1016
                cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
1017

1018
#ifdef CONFIG_ARM_THUMB
1019
        if (elf_hwcap & HWCAP_THUMB) {
1020
                /*
1021
                 * The LSB of the handler determines if we're going to
1022
                 * be using THUMB or ARM mode for this signal handler.
1023
                 */
1024
                thumb = handler & 1;
1025

1026
                if (thumb)
1027
                        cpsr |= T_BIT;
1028
                else
1029
                        cpsr &= ~T_BIT;
1030
        }
1031
#endif
1032
#endif
1033
#endif /* TARGET_CONFIG_CPU_32 */
1034

    
1035
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
1036
                retcode = (target_ulong)ka->sa.sa_restorer;
1037
        } else {
1038
                unsigned int idx = thumb;
1039

    
1040
                if (ka->sa.sa_flags & TARGET_SA_SIGINFO)
1041
                        idx += 2;
1042

    
1043
                if (__put_user(retcodes[idx], rc))
1044
                        return 1;
1045
#if 0
1046
                flush_icache_range((target_ulong)rc,
1047
                                   (target_ulong)(rc + 1));
1048
#endif
1049
                retcode = ((target_ulong)rc) + thumb;
1050
        }
1051

    
1052
        env->regs[0] = usig;
1053
        env->regs[13] = (target_ulong)frame;
1054
        env->regs[14] = retcode;
1055
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1056

    
1057
#ifdef TARGET_CONFIG_CPU_32
1058
        env->cpsr = cpsr;
1059
#endif
1060

    
1061
        return 0;
1062
}
1063

    
1064
static void setup_frame(int usig, struct emulated_sigaction *ka,
1065
                        target_sigset_t *set, CPUState *regs)
1066
{
1067
        struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
1068
        int err = 0;
1069

    
1070
        err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
1071

    
1072
        if (TARGET_NSIG_WORDS > 1) {
1073
                err |= __copy_to_user(frame->extramask, &set->sig[1],
1074
                                      sizeof(frame->extramask));
1075
        }
1076

    
1077
        if (err == 0)
1078
            err = setup_return(regs, ka, &frame->retcode, frame, usig);
1079
        //        return err;
1080
}
1081

    
1082
static void setup_rt_frame(int usig, struct emulated_sigaction *ka, 
1083
                           target_siginfo_t *info,
1084
                           target_sigset_t *set, CPUState *env)
1085
{
1086
        struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
1087
        int err = 0;
1088

    
1089
#if 0
1090
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
1091
            return 1;
1092
#endif
1093
        __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
1094
        __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
1095
        err |= copy_siginfo_to_user(&frame->info, info);
1096

    
1097
        /* Clear all the bits of the ucontext we don't use.  */
1098
        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
1099

    
1100
        err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
1101
                                env, set->sig[0]);
1102
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
1103

    
1104
        if (err == 0)
1105
                err = setup_return(env, ka, &frame->retcode, frame, usig);
1106

    
1107
        if (err == 0) {
1108
                /*
1109
                 * For realtime signals we must also set the second and third
1110
                 * arguments for the signal handler.
1111
                 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
1112
                 */
1113
            env->regs[1] = (target_ulong)frame->pinfo;
1114
            env->regs[2] = (target_ulong)frame->puc;
1115
        }
1116

    
1117
        //        return err;
1118
}
1119

    
1120
static int
1121
restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1122
{
1123
        int err = 0;
1124

    
1125
        __get_user_error(env->regs[0], &sc->arm_r0, err);
1126
        __get_user_error(env->regs[1], &sc->arm_r1, err);
1127
        __get_user_error(env->regs[2], &sc->arm_r2, err);
1128
        __get_user_error(env->regs[3], &sc->arm_r3, err);
1129
        __get_user_error(env->regs[4], &sc->arm_r4, err);
1130
        __get_user_error(env->regs[5], &sc->arm_r5, err);
1131
        __get_user_error(env->regs[6], &sc->arm_r6, err);
1132
        __get_user_error(env->regs[7], &sc->arm_r7, err);
1133
        __get_user_error(env->regs[8], &sc->arm_r8, err);
1134
        __get_user_error(env->regs[9], &sc->arm_r9, err);
1135
        __get_user_error(env->regs[10], &sc->arm_r10, err);
1136
        __get_user_error(env->regs[11], &sc->arm_fp, err);
1137
        __get_user_error(env->regs[12], &sc->arm_ip, err);
1138
        __get_user_error(env->regs[13], &sc->arm_sp, err);
1139
        __get_user_error(env->regs[14], &sc->arm_lr, err);
1140
        __get_user_error(env->regs[15], &sc->arm_pc, err);
1141
#ifdef TARGET_CONFIG_CPU_32
1142
        __get_user_error(env->cpsr, &sc->arm_cpsr, err);
1143
#endif
1144

    
1145
        err |= !valid_user_regs(env);
1146

    
1147
        return err;
1148
}
1149

    
1150
long do_sigreturn(CPUState *env)
1151
{
1152
        struct sigframe *frame;
1153
        target_sigset_t set;
1154
        sigset_t host_set;
1155

    
1156
        /*
1157
         * Since we stacked the signal on a 64-bit boundary,
1158
         * then 'sp' should be word aligned here.  If it's
1159
         * not, then the user is trying to mess with us.
1160
         */
1161
        if (env->regs[13] & 7)
1162
                goto badframe;
1163

    
1164
        frame = (struct sigframe *)env->regs[13];
1165

    
1166
#if 0
1167
        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
1168
                goto badframe;
1169
#endif
1170
        if (__get_user(set.sig[0], &frame->sc.oldmask)
1171
            || (TARGET_NSIG_WORDS > 1
1172
                && __copy_from_user(&set.sig[1], &frame->extramask,
1173
                                    sizeof(frame->extramask))))
1174
                goto badframe;
1175

    
1176
        target_to_host_sigset(&host_set, &set);
1177
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1178

    
1179
        if (restore_sigcontext(env, &frame->sc))
1180
                goto badframe;
1181

    
1182
#if 0
1183
        /* Send SIGTRAP if we're single-stepping */
1184
        if (ptrace_cancel_bpt(current))
1185
                send_sig(SIGTRAP, current, 1);
1186
#endif
1187
        return env->regs[0];
1188

    
1189
badframe:
1190
        force_sig(SIGSEGV /* , current */);
1191
        return 0;
1192
}
1193

    
1194
long do_rt_sigreturn(CPUState *env)
1195
{
1196
        struct rt_sigframe *frame;
1197
        target_sigset_t set;
1198
        sigset_t host_set;
1199

    
1200
        /*
1201
         * Since we stacked the signal on a 64-bit boundary,
1202
         * then 'sp' should be word aligned here.  If it's
1203
         * not, then the user is trying to mess with us.
1204
         */
1205
        if (env->regs[13] & 7)
1206
                goto badframe;
1207

    
1208
        frame = (struct rt_sigframe *)env->regs[13];
1209

    
1210
#if 0
1211
        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
1212
                goto badframe;
1213
#endif
1214
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
1215
                goto badframe;
1216

    
1217
        target_to_host_sigset(&host_set, &set);
1218
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1219

    
1220
        if (restore_sigcontext(env, &frame->uc.uc_mcontext))
1221
                goto badframe;
1222

    
1223
#if 0
1224
        /* Send SIGTRAP if we're single-stepping */
1225
        if (ptrace_cancel_bpt(current))
1226
                send_sig(SIGTRAP, current, 1);
1227
#endif
1228
        return env->regs[0];
1229

    
1230
badframe:
1231
        force_sig(SIGSEGV /* , current */);
1232
        return 0;
1233
}
1234

    
1235
#else
1236

    
1237
static void setup_frame(int sig, struct emulated_sigaction *ka,
1238
                        target_sigset_t *set, CPUState *env)
1239
{
1240
    fprintf(stderr, "setup_frame: not implemented\n");
1241
}
1242

    
1243
static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
1244
                           target_siginfo_t *info,
1245
                           target_sigset_t *set, CPUState *env)
1246
{
1247
    fprintf(stderr, "setup_rt_frame: not implemented\n");
1248
}
1249

    
1250
long do_sigreturn(CPUState *env)
1251
{
1252
    fprintf(stderr, "do_sigreturn: not implemented\n");
1253
    return -ENOSYS;
1254
}
1255

    
1256
long do_rt_sigreturn(CPUState *env)
1257
{
1258
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1259
    return -ENOSYS;
1260
}
1261

    
1262
#endif
1263

    
1264
void process_pending_signals(void *cpu_env)
1265
{
1266
    int sig;
1267
    target_ulong handler;
1268
    sigset_t set, old_set;
1269
    target_sigset_t target_old_set;
1270
    struct emulated_sigaction *k;
1271
    struct sigqueue *q;
1272
    
1273
    if (!signal_pending)
1274
        return;
1275

    
1276
    k = sigact_table;
1277
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
1278
        if (k->pending)
1279
            goto handle_signal;
1280
        k++;
1281
    }
1282
    /* if no signal is pending, just return */
1283
    signal_pending = 0;
1284
    return;
1285

    
1286
 handle_signal:
1287
#ifdef DEBUG_SIGNAL
1288
    fprintf(stderr, "qemu: process signal %d\n", sig);
1289
#endif
1290
    /* dequeue signal */
1291
    q = k->first;
1292
    k->first = q->next;
1293
    if (!k->first)
1294
        k->pending = 0;
1295

    
1296
    handler = k->sa._sa_handler;
1297
    if (handler == TARGET_SIG_DFL) {
1298
        /* default handler : ignore some signal. The other are fatal */
1299
        if (sig != TARGET_SIGCHLD && 
1300
            sig != TARGET_SIGURG && 
1301
            sig != TARGET_SIGWINCH) {
1302
            force_sig(sig);
1303
        }
1304
    } else if (handler == TARGET_SIG_IGN) {
1305
        /* ignore sig */
1306
    } else if (handler == TARGET_SIG_ERR) {
1307
        force_sig(sig);
1308
    } else {
1309
        /* compute the blocked signals during the handler execution */
1310
        target_to_host_sigset(&set, &k->sa.sa_mask);
1311
        /* SA_NODEFER indicates that the current signal should not be
1312
           blocked during the handler */
1313
        if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
1314
            sigaddset(&set, target_to_host_signal(sig));
1315
        
1316
        /* block signals in the handler using Linux */
1317
        sigprocmask(SIG_BLOCK, &set, &old_set);
1318
        /* save the previous blocked signal state to restore it at the
1319
           end of the signal execution (see do_sigreturn) */
1320
        host_to_target_sigset(&target_old_set, &old_set);
1321

    
1322
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
1323
#ifdef TARGET_I386
1324
        {
1325
            CPUX86State *env = cpu_env;
1326
            if (env->eflags & VM_MASK)
1327
                save_v86_state(env);
1328
        }
1329
#endif
1330
        /* prepare the stack frame of the virtual CPU */
1331
        if (k->sa.sa_flags & TARGET_SA_SIGINFO)
1332
            setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
1333
        else
1334
            setup_frame(sig, k, &target_old_set, cpu_env);
1335
        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
1336
            k->sa._sa_handler = TARGET_SIG_DFL;
1337
    }
1338
    if (q != &k->info)
1339
        free_sigqueue(q);
1340
}
1341

    
1342