Statistics
| Branch: | Revision:

root / linux-user / signal.c @ ed2dcdf6

History | View | Annotate | Download (24.5 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

    
540
        cpu_x86_fsave(env, (void *)fpstate, 1);
541
        fpstate->status = fpstate->sw;
542
        err |= __put_user(0xffff, &fpstate->magic);
543
        err |= __put_user(fpstate, &sc->fpstate);
544

    
545
        /* non-iBCS2 extensions.. */
546
        err |= __put_user(mask, &sc->oldmask);
547
        err |= __put_user(env->cr2, &sc->cr2);
548
        return err;
549
}
550

    
551
/*
552
 * Determine which stack to use..
553
 */
554

    
555
static inline void *
556
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
557
{
558
        unsigned long esp;
559

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

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

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

    
585
        frame = get_sigframe(ka, env, sizeof(*frame));
586

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

    
600
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
601
        if (err)
602
                goto give_sigsegv;
603

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

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

    
623
        if (err)
624
                goto give_sigsegv;
625

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

    
630
        cpu_x86_load_seg(env, R_DS, __USER_DS);
631
        cpu_x86_load_seg(env, R_ES, __USER_DS);
632
        cpu_x86_load_seg(env, R_SS, __USER_DS);
633
        cpu_x86_load_seg(env, R_CS, __USER_CS);
634
        env->eflags &= ~TF_MASK;
635

    
636
        return;
637

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

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

    
651
        frame = get_sigframe(ka, env, sizeof(*frame));
652

    
653
#if 0
654
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
655
                goto give_sigsegv;
656
#endif
657

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

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

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

    
695
        if (err)
696
                goto give_sigsegv;
697

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

    
702
        cpu_x86_load_seg(env, R_DS, __USER_DS);
703
        cpu_x86_load_seg(env, R_ES, __USER_DS);
704
        cpu_x86_load_seg(env, R_SS, __USER_DS);
705
        cpu_x86_load_seg(env, R_CS, __USER_CS);
706
        env->eflags &= ~TF_MASK;
707

    
708
        return;
709

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

    
716
static int
717
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
718
{
719
        unsigned int err = 0;
720

    
721
        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
722
        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
723
        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
724
        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
725

    
726
        env->regs[R_EDI] = ldl(&sc->edi);
727
        env->regs[R_ESI] = ldl(&sc->esi);
728
        env->regs[R_EBP] = ldl(&sc->ebp);
729
        env->regs[R_ESP] = ldl(&sc->esp);
730
        env->regs[R_EBX] = ldl(&sc->ebx);
731
        env->regs[R_EDX] = ldl(&sc->edx);
732
        env->regs[R_ECX] = ldl(&sc->ecx);
733
        env->eip = ldl(&sc->eip);
734

    
735
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
736
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
737
        
738
        {
739
                unsigned int tmpflags;
740
                tmpflags = ldl(&sc->eflags);
741
                env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
742
                //                regs->orig_eax = -1;                /* disable syscall checks */
743
        }
744

    
745
        {
746
                struct _fpstate * buf;
747
                buf = (void *)ldl(&sc->fpstate);
748
                if (buf) {
749
#if 0
750
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
751
                                goto badframe;
752
#endif
753
                        cpu_x86_frstor(env, (void *)buf, 1);
754
                }
755
        }
756

    
757
        *peax = ldl(&sc->eax);
758
        return err;
759
#if 0
760
badframe:
761
        return 1;
762
#endif
763
}
764

    
765
long do_sigreturn(CPUX86State *env)
766
{
767
    struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
768
    target_sigset_t target_set;
769
    sigset_t set;
770
    int eax, i;
771

    
772
#if defined(DEBUG_SIGNAL)
773
    fprintf(stderr, "do_sigreturn\n");
774
#endif
775
    /* set blocked signals */
776
    target_set.sig[0] = frame->sc.oldmask;
777
    for(i = 1; i < TARGET_NSIG_WORDS; i++)
778
        target_set.sig[i] = frame->extramask[i - 1];
779

    
780
    target_to_host_sigset(&set, &target_set);
781
    sigprocmask(SIG_SETMASK, &set, NULL);
782
    
783
    /* restore registers */
784
    if (restore_sigcontext(env, &frame->sc, &eax))
785
        goto badframe;
786
    return eax;
787

    
788
badframe:
789
    force_sig(TARGET_SIGSEGV);
790
    return 0;
791
}
792

    
793
long do_rt_sigreturn(CPUX86State *env)
794
{
795
        struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
796
        target_sigset_t target_set;
797
        sigset_t set;
798
        //        stack_t st;
799
        int eax;
800

    
801
#if 0
802
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
803
                goto badframe;
804
#endif
805
        memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
806

    
807
        target_to_host_sigset(&set, &target_set);
808
        sigprocmask(SIG_SETMASK, &set, NULL);
809
        
810
        if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
811
                goto badframe;
812

    
813
#if 0
814
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
815
                goto badframe;
816
        /* It is more difficult to avoid calling this function than to
817
           call it and ignore errors.  */
818
        do_sigaltstack(&st, NULL, regs->esp);
819
#endif
820
        return eax;
821

    
822
badframe:
823
        force_sig(TARGET_SIGSEGV);
824
        return 0;
825
}
826

    
827
#endif
828

    
829
void process_pending_signals(void *cpu_env)
830
{
831
    int sig;
832
    target_ulong handler;
833
    sigset_t set, old_set;
834
    target_sigset_t target_old_set;
835
    struct emulated_sigaction *k;
836
    struct sigqueue *q;
837
    
838
    if (!signal_pending)
839
        return;
840

    
841
    k = sigact_table;
842
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
843
        if (k->pending)
844
            goto handle_signal;
845
        k++;
846
    }
847
    /* if no signal is pending, just return */
848
    signal_pending = 0;
849
    return;
850

    
851
 handle_signal:
852
#ifdef DEBUG_SIGNAL
853
    fprintf(stderr, "qemu: process signal %d\n", sig);
854
#endif
855
    /* dequeue signal */
856
    q = k->first;
857
    k->first = q->next;
858
    if (!k->first)
859
        k->pending = 0;
860

    
861
    handler = k->sa._sa_handler;
862
    if (handler == TARGET_SIG_DFL) {
863
        /* default handler : ignore some signal. The other are fatal */
864
        if (sig != TARGET_SIGCHLD && 
865
            sig != TARGET_SIGURG && 
866
            sig != TARGET_SIGWINCH) {
867
            force_sig(sig);
868
        }
869
    } else if (handler == TARGET_SIG_IGN) {
870
        /* ignore sig */
871
    } else if (handler == TARGET_SIG_ERR) {
872
        force_sig(sig);
873
    } else {
874
        /* compute the blocked signals during the handler execution */
875
        target_to_host_sigset(&set, &k->sa.sa_mask);
876
        /* SA_NODEFER indicates that the current signal should not be
877
           blocked during the handler */
878
        if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
879
            sigaddset(&set, target_to_host_signal(sig));
880
        
881
        /* block signals in the handler using Linux */
882
        sigprocmask(SIG_BLOCK, &set, &old_set);
883
        /* save the previous blocked signal state to restore it at the
884
           end of the signal execution (see do_sigreturn) */
885
        host_to_target_sigset(&target_old_set, &old_set);
886

    
887
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
888
#ifdef TARGET_I386
889
        {
890
            CPUX86State *env = cpu_env;
891
            if (env->eflags & VM_MASK)
892
                save_v86_state(env);
893
        }
894
#endif
895
        /* prepare the stack frame of the virtual CPU */
896
        if (k->sa.sa_flags & TARGET_SA_SIGINFO)
897
            setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
898
        else
899
            setup_frame(sig, k, &target_old_set, cpu_env);
900
        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
901
            k->sa._sa_handler = TARGET_SIG_DFL;
902
    }
903
    if (q != &k->info)
904
        free_sigqueue(q);
905
}
906

    
907