Statistics
| Branch: | Revision:

root / linux-user / signal.c @ bc8a22cc

History | View | Annotate | Download (24.7 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 <signal.h>
25
#include <errno.h>
26
#include <sys/ucontext.h>
27

    
28
#include "qemu.h"
29

    
30
//#define DEBUG_SIGNAL
31

    
32
#define MAX_SIGQUEUE_SIZE 1024
33

    
34
struct sigqueue {
35
    struct sigqueue *next;
36
    target_siginfo_t info;
37
};
38

    
39
struct emulated_sigaction {
40
    struct target_sigaction sa;
41
    int pending; /* true if signal is pending */
42
    struct sigqueue *first;
43
    struct sigqueue info; /* in order to always have memory for the
44
                             first signal, we put it here */
45
};
46

    
47
static struct emulated_sigaction sigact_table[TARGET_NSIG];
48
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
49
static struct sigqueue *first_free; /* first free siginfo queue entry */
50
static int signal_pending; /* non zero if a signal may be pending */
51

    
52
static void host_signal_handler(int host_signum, siginfo_t *info, 
53
                                void *puc);
54

    
55
/* XXX: do it properly */
56
static inline int host_to_target_signal(int sig)
57
{
58
    return sig;
59
}
60

    
61
static inline int target_to_host_signal(int sig)
62
{
63
    return sig;
64
}
65

    
66
void host_to_target_sigset(target_sigset_t *d, sigset_t *s)
67
{
68
    int i;
69
    for(i = 0;i < TARGET_NSIG_WORDS; i++) {
70
        d->sig[i] = tswapl(((unsigned long *)s)[i]);
71
    }
72
}
73

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

    
82
void host_to_target_old_sigset(target_ulong *old_sigset, 
83
                               const sigset_t *sigset)
84
{
85
    *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
86
}
87

    
88
void target_to_host_old_sigset(sigset_t *sigset, 
89
                               const target_ulong *old_sigset)
90
{
91
    sigemptyset(sigset);
92
    *(unsigned long *)sigset = tswapl(*old_sigset);
93
}
94

    
95
/* siginfo conversion */
96

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

    
118
static void tswap_siginfo(target_siginfo_t *tinfo, 
119
                          const target_siginfo_t *info)
120
{
121
    int sig;
122
    sig = info->si_signo;
123
    tinfo->si_signo = tswap32(sig);
124
    tinfo->si_errno = tswap32(info->si_errno);
125
    tinfo->si_code = tswap32(info->si_code);
126
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) {
127
        tinfo->_sifields._sigfault._addr = 
128
            tswapl(info->_sifields._sigfault._addr);
129
    } else if (sig >= TARGET_SIGRTMIN) {
130
        tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
131
        tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
132
        tinfo->_sifields._rt._sigval.sival_ptr = 
133
            tswapl(info->_sifields._rt._sigval.sival_ptr);
134
    }
135
}
136

    
137

    
138
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
139
{
140
    host_to_target_siginfo_noswap(tinfo, info);
141
    tswap_siginfo(tinfo, tinfo);
142
}
143

    
144
/* XXX: we support only POSIX RT signals are used. */
145
/* XXX: find a solution for 64 bit (additionnal malloced data is needed) */
146
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
147
{
148
    info->si_signo = tswap32(tinfo->si_signo);
149
    info->si_errno = tswap32(tinfo->si_errno);
150
    info->si_code = tswap32(tinfo->si_code);
151
    info->si_pid = tswap32(tinfo->_sifields._rt._pid);
152
    info->si_uid = tswap32(tinfo->_sifields._rt._uid);
153
    info->si_value.sival_ptr = 
154
        (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
155
}
156

    
157
void signal_init(void)
158
{
159
    struct sigaction act;
160
    int i;
161

    
162
    /* set all host signal handlers. ALL signals are blocked during
163
       the handlers to serialize them. */
164
    sigfillset(&act.sa_mask);
165
    act.sa_flags = SA_SIGINFO;
166
    act.sa_sigaction = host_signal_handler;
167
    for(i = 1; i < NSIG; i++) {
168
        sigaction(i, &act, NULL);
169
    }
170
    
171
    memset(sigact_table, 0, sizeof(sigact_table));
172

    
173
    first_free = &sigqueue_table[0];
174
    for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) 
175
        sigqueue_table[i].next = &sigqueue_table[i + 1];
176
    sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
177
}
178

    
179
/* signal queue handling */
180

    
181
static inline struct sigqueue *alloc_sigqueue(void)
182
{
183
    struct sigqueue *q = first_free;
184
    if (!q)
185
        return NULL;
186
    first_free = q->next;
187
    return q;
188
}
189

    
190
static inline void free_sigqueue(struct sigqueue *q)
191
{
192
    q->next = first_free;
193
    first_free = q;
194
}
195

    
196
/* abort execution with signal */
197
void __attribute((noreturn)) force_sig(int sig)
198
{
199
    int host_sig;
200
    host_sig = target_to_host_signal(sig);
201
    fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n", 
202
            sig, strsignal(host_sig));
203
#if 1
204
    _exit(-host_sig);
205
#else
206
    {
207
        struct sigaction act;
208
        sigemptyset(&act.sa_mask);
209
        act.sa_flags = SA_SIGINFO;
210
        act.sa_sigaction = SIG_DFL;
211
        sigaction(SIGABRT, &act, NULL);
212
        abort();
213
    }
214
#endif
215
}
216

    
217
/* queue a signal so that it will be send to the virtual CPU as soon
218
   as possible */
219
int queue_signal(int sig, target_siginfo_t *info)
220
{
221
    struct emulated_sigaction *k;
222
    struct sigqueue *q, **pq;
223
    target_ulong handler;
224

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

    
275
#if defined(DEBUG_SIGNAL)
276
#ifdef __i386__
277
static void dump_regs(struct ucontext *uc)
278
{
279
    fprintf(stderr, 
280
            "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
281
            "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
282
            "EFL=%08x EIP=%08x\n",
283
            uc->uc_mcontext.gregs[EAX],
284
            uc->uc_mcontext.gregs[EBX],
285
            uc->uc_mcontext.gregs[ECX],
286
            uc->uc_mcontext.gregs[EDX],
287
            uc->uc_mcontext.gregs[ESI],
288
            uc->uc_mcontext.gregs[EDI],
289
            uc->uc_mcontext.gregs[EBP],
290
            uc->uc_mcontext.gregs[ESP],
291
            uc->uc_mcontext.gregs[EFL],
292
            uc->uc_mcontext.gregs[EIP]);
293
}
294
#else
295
static void dump_regs(struct ucontext *uc)
296
{
297
}
298
#endif
299

    
300
#endif
301

    
302
static void host_signal_handler(int host_signum, siginfo_t *info, 
303
                                void *puc)
304
{
305
    int sig;
306
    target_siginfo_t tinfo;
307

    
308
    /* the CPU emulator uses some host signals to detect exceptions,
309
       we we forward to it some signals */
310
    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
311
        if (cpu_x86_signal_handler(host_signum, info, puc))
312
            return;
313
    }
314

    
315
    /* get target signal number */
316
    sig = host_to_target_signal(host_signum);
317
    if (sig < 1 || sig > TARGET_NSIG)
318
        return;
319
#if defined(DEBUG_SIGNAL)
320
    fprintf(stderr, "qemu: got signal %d\n", sig);
321
    dump_regs(puc);
322
#endif
323
    host_to_target_siginfo_noswap(&tinfo, info);
324
    if (queue_signal(sig, &tinfo) == 1) {
325
        /* interrupt the virtual CPU as soon as possible */
326
        cpu_x86_interrupt(global_env);
327
    }
328
}
329

    
330
int do_sigaction(int sig, const struct target_sigaction *act,
331
                 struct target_sigaction *oact)
332
{
333
    struct emulated_sigaction *k;
334

    
335
    if (sig < 1 || sig > TARGET_NSIG)
336
        return -EINVAL;
337
    k = &sigact_table[sig - 1];
338
#if defined(DEBUG_SIGNAL) && 0
339
    fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", 
340
            sig, (int)act, (int)oact);
341
#endif
342
    if (oact) {
343
        oact->_sa_handler = tswapl(k->sa._sa_handler);
344
        oact->sa_flags = tswapl(k->sa.sa_flags);
345
        oact->sa_restorer = tswapl(k->sa.sa_restorer);
346
        oact->sa_mask = k->sa.sa_mask;
347
    }
348
    if (act) {
349
        k->sa._sa_handler = tswapl(act->_sa_handler);
350
        k->sa.sa_flags = tswapl(act->sa_flags);
351
        k->sa.sa_restorer = tswapl(act->sa_restorer);
352
        k->sa.sa_mask = act->sa_mask;
353
    }
354
    return 0;
355
}
356

    
357
#ifdef TARGET_I386
358

    
359
/* from the Linux kernel */
360

    
361
struct target_fpreg {
362
        uint16_t significand[4];
363
        uint16_t exponent;
364
};
365

    
366
struct target_fpxreg {
367
        uint16_t significand[4];
368
        uint16_t exponent;
369
        uint16_t padding[3];
370
};
371

    
372
struct target_xmmreg {
373
        target_ulong element[4];
374
};
375

    
376
struct target_fpstate {
377
        /* Regular FPU environment */
378
        target_ulong         cw;
379
        target_ulong        sw;
380
        target_ulong        tag;
381
        target_ulong        ipoff;
382
        target_ulong        cssel;
383
        target_ulong        dataoff;
384
        target_ulong        datasel;
385
        struct target_fpreg        _st[8];
386
        uint16_t        status;
387
        uint16_t        magic;                /* 0xffff = regular FPU data only */
388

    
389
        /* FXSR FPU environment */
390
        target_ulong        _fxsr_env[6];        /* FXSR FPU env is ignored */
391
        target_ulong        mxcsr;
392
        target_ulong        reserved;
393
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
394
        struct target_xmmreg        _xmm[8];
395
        target_ulong        padding[56];
396
};
397

    
398
#define X86_FXSR_MAGIC                0x0000
399

    
400
struct target_sigcontext {
401
        uint16_t gs, __gsh;
402
        uint16_t fs, __fsh;
403
        uint16_t es, __esh;
404
        uint16_t ds, __dsh;
405
        target_ulong edi;
406
        target_ulong esi;
407
        target_ulong ebp;
408
        target_ulong esp;
409
        target_ulong ebx;
410
        target_ulong edx;
411
        target_ulong ecx;
412
        target_ulong eax;
413
        target_ulong trapno;
414
        target_ulong err;
415
        target_ulong eip;
416
        uint16_t cs, __csh;
417
        target_ulong eflags;
418
        target_ulong esp_at_signal;
419
        uint16_t ss, __ssh;
420
        target_ulong fpstate; /* pointer */
421
        target_ulong oldmask;
422
        target_ulong cr2;
423
};
424

    
425
typedef struct target_sigaltstack {
426
        target_ulong ss_sp;
427
        int ss_flags;
428
        target_ulong ss_size;
429
} target_stack_t;
430

    
431
struct target_ucontext {
432
        target_ulong          uc_flags;
433
        target_ulong      uc_link;
434
        target_stack_t          uc_stack;
435
        struct target_sigcontext uc_mcontext;
436
        target_sigset_t          uc_sigmask;        /* mask last for extensibility */
437
};
438

    
439
struct sigframe
440
{
441
    target_ulong pretcode;
442
    int sig;
443
    struct target_sigcontext sc;
444
    struct target_fpstate fpstate;
445
    target_ulong extramask[TARGET_NSIG_WORDS-1];
446
    char retcode[8];
447
};
448

    
449
struct rt_sigframe
450
{
451
    target_ulong pretcode;
452
    int sig;
453
    target_ulong pinfo;
454
    target_ulong puc;
455
    struct target_siginfo info;
456
    struct target_ucontext uc;
457
    struct target_fpstate fpstate;
458
    char retcode[8];
459
};
460

    
461
/*
462
 * Set up a signal frame.
463
 */
464

    
465
#define __put_user(x,ptr)\
466
({\
467
    int size = sizeof(*ptr);\
468
    switch(size) {\
469
    case 1:\
470
        stb(ptr, (typeof(*ptr))(x));\
471
        break;\
472
    case 2:\
473
        stw(ptr, (typeof(*ptr))(x));\
474
        break;\
475
    case 4:\
476
        stl(ptr, (typeof(*ptr))(x));\
477
        break;\
478
    case 8:\
479
        stq(ptr, (typeof(*ptr))(x));\
480
        break;\
481
    default:\
482
        abort();\
483
    }\
484
    0;\
485
})
486

    
487
#define get_user(val, ptr) (typeof(*ptr))(*(ptr))
488

    
489

    
490
#define __copy_to_user(dst, src, size)\
491
({\
492
    memcpy(dst, src, size);\
493
    0;\
494
})
495

    
496
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, 
497
                                       const target_siginfo_t *info)
498
{
499
    tswap_siginfo(tinfo, info);
500
    return 0;
501
}
502

    
503
/* XXX: save x87 state */
504
static int
505
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
506
                 CPUX86State *env, unsigned long mask)
507
{
508
        int err = 0;
509

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

    
544
/*
545
 * Determine which stack to use..
546
 */
547

    
548
static inline void *
549
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
550
{
551
        unsigned long esp;
552

    
553
        /* Default to using normal stack */
554
        esp = env->regs[R_ESP];
555
#if 0
556
        /* This is the X/Open sanctioned signal stack switching.  */
557
        if (ka->sa.sa_flags & SA_ONSTACK) {
558
                if (sas_ss_flags(esp) == 0)
559
                        esp = current->sas_ss_sp + current->sas_ss_size;
560
        }
561

562
        /* This is the legacy signal stack switching. */
563
        else if ((regs->xss & 0xffff) != __USER_DS &&
564
                 !(ka->sa.sa_flags & SA_RESTORER) &&
565
                 ka->sa.sa_restorer) {
566
                esp = (unsigned long) ka->sa.sa_restorer;
567
        }
568
#endif
569
        return (void *)((esp - frame_size) & -8ul);
570
}
571

    
572
static void setup_frame(int sig, struct emulated_sigaction *ka,
573
                        target_sigset_t *set, CPUX86State *env)
574
{
575
        struct sigframe *frame;
576
        int err = 0;
577

    
578
        frame = get_sigframe(ka, env, sizeof(*frame));
579

    
580
#if 0
581
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
582
                goto give_sigsegv;
583
#endif
584
        err |= __put_user((/*current->exec_domain
585
                           && current->exec_domain->signal_invmap
586
                           && sig < 32
587
                           ? current->exec_domain->signal_invmap[sig]
588
                           : */ sig),
589
                          &frame->sig);
590
        if (err)
591
                goto give_sigsegv;
592

    
593
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
594
        if (err)
595
                goto give_sigsegv;
596

    
597
        if (TARGET_NSIG_WORDS > 1) {
598
                err |= __copy_to_user(frame->extramask, &set->sig[1],
599
                                      sizeof(frame->extramask));
600
        }
601
        if (err)
602
                goto give_sigsegv;
603

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

    
616
        if (err)
617
                goto give_sigsegv;
618

    
619
        /* Set up registers for signal handler */
620
        env->regs[R_ESP] = (unsigned long) frame;
621
        env->eip = (unsigned long) ka->sa._sa_handler;
622

    
623
        cpu_x86_load_seg(env, R_DS, __USER_DS);
624
        cpu_x86_load_seg(env, R_ES, __USER_DS);
625
        cpu_x86_load_seg(env, R_SS, __USER_DS);
626
        cpu_x86_load_seg(env, R_CS, __USER_CS);
627
        env->eflags &= ~TF_MASK;
628

    
629
        return;
630

    
631
give_sigsegv:
632
        if (sig == TARGET_SIGSEGV)
633
                ka->sa._sa_handler = TARGET_SIG_DFL;
634
        force_sig(TARGET_SIGSEGV /* , current */);
635
}
636

    
637
static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
638
                           target_siginfo_t *info,
639
                           target_sigset_t *set, CPUX86State *env)
640
{
641
        struct rt_sigframe *frame;
642
        int err = 0;
643

    
644
        frame = get_sigframe(ka, env, sizeof(*frame));
645

    
646
#if 0
647
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
648
                goto give_sigsegv;
649
#endif
650

    
651
        err |= __put_user((/*current->exec_domain
652
                               && current->exec_domain->signal_invmap
653
                               && sig < 32
654
                               ? current->exec_domain->signal_invmap[sig]
655
                           : */sig),
656
                          &frame->sig);
657
        err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
658
        err |= __put_user((target_ulong)&frame->uc, &frame->puc);
659
        err |= copy_siginfo_to_user(&frame->info, info);
660
        if (err)
661
                goto give_sigsegv;
662

    
663
        /* Create the ucontext.  */
664
        err |= __put_user(0, &frame->uc.uc_flags);
665
        err |= __put_user(0, &frame->uc.uc_link);
666
        err |= __put_user(/*current->sas_ss_sp*/ 0, &frame->uc.uc_stack.ss_sp);
667
        err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
668
                          &frame->uc.uc_stack.ss_flags);
669
        err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size);
670
        err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
671
                                env, set->sig[0]);
672
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
673
        if (err)
674
                goto give_sigsegv;
675

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

    
688
        if (err)
689
                goto give_sigsegv;
690

    
691
        /* Set up registers for signal handler */
692
        env->regs[R_ESP] = (unsigned long) frame;
693
        env->eip = (unsigned long) ka->sa._sa_handler;
694

    
695
        cpu_x86_load_seg(env, R_DS, __USER_DS);
696
        cpu_x86_load_seg(env, R_ES, __USER_DS);
697
        cpu_x86_load_seg(env, R_SS, __USER_DS);
698
        cpu_x86_load_seg(env, R_CS, __USER_CS);
699
        env->eflags &= ~TF_MASK;
700

    
701
        return;
702

    
703
give_sigsegv:
704
        if (sig == TARGET_SIGSEGV)
705
                ka->sa._sa_handler = TARGET_SIG_DFL;
706
        force_sig(TARGET_SIGSEGV /* , current */);
707
}
708

    
709
static int
710
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
711
{
712
        unsigned int err = 0;
713

    
714

    
715
        
716
#define COPY(x)                err |= __get_user(regs->x, &sc->x)
717

    
718
#define COPY_SEG(seg)                                                        \
719
        { unsigned short tmp;                                                \
720
          err |= __get_user(tmp, &sc->seg);                                \
721
          regs->x##seg = tmp; }
722

    
723
#define COPY_SEG_STRICT(seg)                                                \
724
        { unsigned short tmp;                                                \
725
          err |= __get_user(tmp, &sc->seg);                                \
726
          regs->x##seg = tmp|3; }
727

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

    
733
        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
734
        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
735
        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
736
        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
737

    
738
        env->regs[R_EDI] = ldl(&sc->edi);
739
        env->regs[R_ESI] = ldl(&sc->esi);
740
        env->regs[R_EBP] = ldl(&sc->ebp);
741
        env->regs[R_ESP] = ldl(&sc->esp);
742
        env->regs[R_EBX] = ldl(&sc->ebx);
743
        env->regs[R_EDX] = ldl(&sc->edx);
744
        env->regs[R_ECX] = ldl(&sc->ecx);
745
        env->eip = ldl(&sc->eip);
746

    
747
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
748
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
749
        
750
        {
751
                unsigned int tmpflags;
752
                tmpflags = ldl(&sc->eflags);
753
                env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
754
                //                regs->orig_eax = -1;                /* disable syscall checks */
755
        }
756

    
757
#if 0
758
        {
759
                struct _fpstate * buf;
760
                err |= __get_user(buf, &sc->fpstate);
761
                if (buf) {
762
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
763
                                goto badframe;
764
                        err |= restore_i387(buf);
765
                }
766
        }
767
#endif
768
        *peax = ldl(&sc->eax);
769
        return err;
770
#if 0
771
badframe:
772
        return 1;
773
#endif
774
}
775

    
776
long do_sigreturn(CPUX86State *env)
777
{
778
    struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
779
    target_sigset_t target_set;
780
    sigset_t set;
781
    int eax, i;
782

    
783
    /* set blocked signals */
784
    target_set.sig[0] = frame->sc.oldmask;
785
    for(i = 1; i < TARGET_NSIG_WORDS; i++)
786
        target_set.sig[i] = frame->extramask[i - 1];
787

    
788
    target_to_host_sigset(&set, &target_set);
789
    sigprocmask(SIG_SETMASK, &set, NULL);
790
    
791
    /* restore registers */
792
    if (restore_sigcontext(env, &frame->sc, &eax))
793
        goto badframe;
794
    return eax;
795

    
796
badframe:
797
    force_sig(TARGET_SIGSEGV);
798
    return 0;
799
}
800

    
801
long do_rt_sigreturn(CPUX86State *env)
802
{
803
        struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
804
        target_sigset_t target_set;
805
        sigset_t set;
806
        //        stack_t st;
807
        int eax;
808

    
809
#if 0
810
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
811
                goto badframe;
812
#endif
813
        memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
814

    
815
        target_to_host_sigset(&set, &target_set);
816
        sigprocmask(SIG_SETMASK, &set, NULL);
817
        
818
        if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
819
                goto badframe;
820

    
821
#if 0
822
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
823
                goto badframe;
824
        /* It is more difficult to avoid calling this function than to
825
           call it and ignore errors.  */
826
        do_sigaltstack(&st, NULL, regs->esp);
827
#endif
828
        return eax;
829

    
830
badframe:
831
        force_sig(TARGET_SIGSEGV);
832
        return 0;
833
}
834

    
835
#endif
836

    
837
void process_pending_signals(void *cpu_env)
838
{
839
    int sig;
840
    target_ulong handler;
841
    sigset_t set, old_set;
842
    target_sigset_t target_old_set;
843
    struct emulated_sigaction *k;
844
    struct sigqueue *q;
845
    
846
    if (!signal_pending)
847
        return;
848

    
849
    k = sigact_table;
850
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
851
        if (k->pending)
852
            goto handle_signal;
853
        k++;
854
    }
855
    /* if no signal is pending, just return */
856
    signal_pending = 0;
857
    return;
858

    
859
 handle_signal:
860
#ifdef DEBUG_SIGNAL
861
    fprintf(stderr, "qemu: process signal %d\n", sig);
862
#endif
863
    /* dequeue signal */
864
    q = k->first;
865
    k->first = q->next;
866
    if (!k->first)
867
        k->pending = 0;
868

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

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

    
915