Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 3ef693a0

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 <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, "gemu: 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_sigal: 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, "gemu: 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

    
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
#define TF_MASK TRAP_FLAG
574

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

    
581
        frame = get_sigframe(ka, env, sizeof(*frame));
582

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

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

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

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

    
619
        if (err)
620
                goto give_sigsegv;
621

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

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

    
632
        return;
633

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

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

    
647
        frame = get_sigframe(ka, env, sizeof(*frame));
648

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

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

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

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

    
691
        if (err)
692
                goto give_sigsegv;
693

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

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

    
704
        return;
705

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

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

    
717

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

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

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

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

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

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

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

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

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

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

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

    
799
badframe:
800
    force_sig(TARGET_SIGSEGV);
801
    return 0;
802
}
803

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

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

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

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

    
833
badframe:
834
        force_sig(TARGET_SIGSEGV);
835
        return 0;
836
}
837

    
838
#endif
839

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

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

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

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

    
898
        /* prepare the stack frame of the virtual CPU */
899
        if (k->sa.sa_flags & TARGET_SA_SIGINFO)
900
            setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
901
        else
902
            setup_frame(sig, k, &target_old_set, cpu_env);
903
        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
904
            k->sa._sa_handler = TARGET_SIG_DFL;
905
    }
906
    if (q != &k->info)
907
        free_sigqueue(q);
908
}
909

    
910