Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 9de5e440

History | View | Annotate | Download (24.6 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 "gemu.h"
29

    
30
/* signal handling inspired from em86. */
31

    
32
//#define DEBUG_SIGNAL
33

    
34
#define MAX_SIGQUEUE_SIZE 1024
35

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

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

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

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

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

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

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

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

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

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

    
97
/* siginfo conversion */
98

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

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

    
139

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

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

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

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

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

    
181
/* signal queue handling */
182

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

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

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

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

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

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

    
302
#endif
303

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

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

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

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

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

    
359
#ifdef TARGET_I386
360

    
361
/* from the Linux kernel */
362

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

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

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

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

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

    
400
#define X86_FXSR_MAGIC                0x0000
401

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

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

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

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

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

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

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

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

    
491

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

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

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

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

    
544
        return err;
545
}
546

    
547
/*
548
 * Determine which stack to use..
549
 */
550

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

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

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

    
575
#define TF_MASK TRAP_FLAG
576

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

    
583
        frame = get_sigframe(ka, env, sizeof(*frame));
584

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

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

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

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

    
621
        if (err)
622
                goto give_sigsegv;
623

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

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

    
634
        return;
635

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

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

    
649
        frame = get_sigframe(ka, env, sizeof(*frame));
650

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

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

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

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

    
693
        if (err)
694
                goto give_sigsegv;
695

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

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

    
706
        return;
707

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

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

    
719

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

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

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

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

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

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

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

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

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

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

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

    
801
badframe:
802
    force_sig(TARGET_SIGSEGV);
803
    return 0;
804
}
805

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

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

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

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

    
835
badframe:
836
        force_sig(TARGET_SIGSEGV);
837
        return 0;
838
}
839

    
840
#endif
841

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

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

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

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

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

    
912