Statistics
| Branch: | Revision:

root / linux-user / signal.c @ ae48a073

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 <unistd.h>
25
#include <signal.h>
26
#include <errno.h>
27
#include <sys/ucontext.h>
28

    
29
#include "qemu.h"
30

    
31
//#define DEBUG_SIGNAL
32

    
33
#define MAX_SIGQUEUE_SIZE 1024
34

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

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

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

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

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

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

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

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

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

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

    
96
/* siginfo conversion */
97

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

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

    
138

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

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

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

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

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

    
180
/* signal queue handling */
181

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

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

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

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

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

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

    
301
#endif
302

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

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

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

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

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

    
358
#ifdef TARGET_I386
359

    
360
/* from the Linux kernel */
361

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

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

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

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

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

    
399
#define X86_FXSR_MAGIC                0x0000
400

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

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

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

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

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

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

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

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

    
490

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
617
        if (err)
618
                goto give_sigsegv;
619

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

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

    
630
        return;
631

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

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

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

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

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

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

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

    
689
        if (err)
690
                goto give_sigsegv;
691

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

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

    
702
        return;
703

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

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

    
715

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
836
#endif
837

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

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

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

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

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

    
916