Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 97eb5b14

History | View | Annotate | Download (37.4 kB)

1
/*
2
 *  Emulation of Linux signals
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 */
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include <stdarg.h>
24
#include <unistd.h>
25
#include <signal.h>
26
#include <errno.h>
27
#include <sys/ucontext.h>
28

    
29
#ifdef __ia64__
30
#undef uc_mcontext
31
#undef uc_sigmask
32
#undef uc_stack
33
#undef uc_link
34
#endif 
35

    
36
#include "qemu.h"
37

    
38
//#define DEBUG_SIGNAL
39

    
40
#define MAX_SIGQUEUE_SIZE 1024
41

    
42
struct sigqueue {
43
    struct sigqueue *next;
44
    target_siginfo_t info;
45
};
46

    
47
struct emulated_sigaction {
48
    struct target_sigaction sa;
49
    int pending; /* true if signal is pending */
50
    struct sigqueue *first;
51
    struct sigqueue info; /* in order to always have memory for the
52
                             first signal, we put it here */
53
};
54

    
55
static struct emulated_sigaction sigact_table[TARGET_NSIG];
56
static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
57
static struct sigqueue *first_free; /* first free siginfo queue entry */
58
static int signal_pending; /* non zero if a signal may be pending */
59

    
60
static void host_signal_handler(int host_signum, siginfo_t *info, 
61
                                void *puc);
62

    
63
static uint8_t host_to_target_signal_table[65] = {
64
    [SIGHUP] = TARGET_SIGHUP,
65
    [SIGINT] = TARGET_SIGINT,
66
    [SIGQUIT] = TARGET_SIGQUIT,
67
    [SIGILL] = TARGET_SIGILL,
68
    [SIGTRAP] = TARGET_SIGTRAP,
69
    [SIGABRT] = TARGET_SIGABRT,
70
/*    [SIGIOT] = TARGET_SIGIOT,*/
71
    [SIGBUS] = TARGET_SIGBUS,
72
    [SIGFPE] = TARGET_SIGFPE,
73
    [SIGKILL] = TARGET_SIGKILL,
74
    [SIGUSR1] = TARGET_SIGUSR1,
75
    [SIGSEGV] = TARGET_SIGSEGV,
76
    [SIGUSR2] = TARGET_SIGUSR2,
77
    [SIGPIPE] = TARGET_SIGPIPE,
78
    [SIGALRM] = TARGET_SIGALRM,
79
    [SIGTERM] = TARGET_SIGTERM,
80
#ifdef SIGSTKFLT
81
    [SIGSTKFLT] = TARGET_SIGSTKFLT,
82
#endif
83
    [SIGCHLD] = TARGET_SIGCHLD,
84
    [SIGCONT] = TARGET_SIGCONT,
85
    [SIGSTOP] = TARGET_SIGSTOP,
86
    [SIGTSTP] = TARGET_SIGTSTP,
87
    [SIGTTIN] = TARGET_SIGTTIN,
88
    [SIGTTOU] = TARGET_SIGTTOU,
89
    [SIGURG] = TARGET_SIGURG,
90
    [SIGXCPU] = TARGET_SIGXCPU,
91
    [SIGXFSZ] = TARGET_SIGXFSZ,
92
    [SIGVTALRM] = TARGET_SIGVTALRM,
93
    [SIGPROF] = TARGET_SIGPROF,
94
    [SIGWINCH] = TARGET_SIGWINCH,
95
    [SIGIO] = TARGET_SIGIO,
96
    [SIGPWR] = TARGET_SIGPWR,
97
    [SIGSYS] = TARGET_SIGSYS,
98
    /* next signals stay the same */
99
};
100
static uint8_t target_to_host_signal_table[65];
101

    
102
static inline int host_to_target_signal(int sig)
103
{
104
    return host_to_target_signal_table[sig];
105
}
106

    
107
static inline int target_to_host_signal(int sig)
108
{
109
    return target_to_host_signal_table[sig];
110
}
111

    
112
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
113
{
114
    int i;
115
    unsigned long sigmask;
116
    uint32_t target_sigmask;
117
    
118
    sigmask = ((unsigned long *)s)[0];
119
    target_sigmask = 0;
120
    for(i = 0; i < 32; i++) {
121
        if (sigmask & (1 << i)) 
122
            target_sigmask |= 1 << (host_to_target_signal(i + 1) - 1);
123
    }
124
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
125
    d->sig[0] = tswapl(target_sigmask);
126
    for(i = 1;i < TARGET_NSIG_WORDS; i++) {
127
        d->sig[i] = tswapl(((unsigned long *)s)[i]);
128
    }
129
#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
130
    d->sig[0] = tswapl(target_sigmask);
131
    d->sig[1] = tswapl(sigmask >> 32);
132
#else
133
#error host_to_target_sigset
134
#endif
135
}
136

    
137
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
138
{
139
    int i;
140
    unsigned long sigmask;
141
    target_ulong target_sigmask;
142

    
143
    target_sigmask = tswapl(s->sig[0]);
144
    sigmask = 0;
145
    for(i = 0; i < 32; i++) {
146
        if (target_sigmask & (1 << i)) 
147
            sigmask |= 1 << (target_to_host_signal(i + 1) - 1);
148
    }
149
#if TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 32
150
    ((unsigned long *)d)[0] = sigmask;
151
    for(i = 1;i < TARGET_NSIG_WORDS; i++) {
152
        ((unsigned long *)d)[i] = tswapl(s->sig[i]);
153
    }
154
#elif TARGET_LONG_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
155
    ((unsigned long *)d)[0] = sigmask | ((unsigned long)tswapl(s->sig[1]) << 32);
156
#else
157
#error target_to_host_sigset
158
#endif /* TARGET_LONG_BITS */
159
}
160

    
161
void host_to_target_old_sigset(target_ulong *old_sigset, 
162
                               const sigset_t *sigset)
163
{
164
    target_sigset_t d;
165
    host_to_target_sigset(&d, sigset);
166
    *old_sigset = d.sig[0];
167
}
168

    
169
void target_to_host_old_sigset(sigset_t *sigset, 
170
                               const target_ulong *old_sigset)
171
{
172
    target_sigset_t d;
173
    int i;
174

    
175
    d.sig[0] = *old_sigset;
176
    for(i = 1;i < TARGET_NSIG_WORDS; i++)
177
        d.sig[i] = 0;
178
    target_to_host_sigset(sigset, &d);
179
}
180

    
181
/* siginfo conversion */
182

    
183
static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, 
184
                                                 const siginfo_t *info)
185
{
186
    int sig;
187
    sig = host_to_target_signal(info->si_signo);
188
    tinfo->si_signo = sig;
189
    tinfo->si_errno = 0;
190
    tinfo->si_code = 0;
191
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || 
192
        sig == SIGBUS || sig == SIGTRAP) {
193
        /* should never come here, but who knows. The information for
194
           the target is irrelevant */
195
        tinfo->_sifields._sigfault._addr = 0;
196
    } else if (sig >= TARGET_SIGRTMIN) {
197
        tinfo->_sifields._rt._pid = info->si_pid;
198
        tinfo->_sifields._rt._uid = info->si_uid;
199
        /* XXX: potential problem if 64 bit */
200
        tinfo->_sifields._rt._sigval.sival_ptr = 
201
            (target_ulong)info->si_value.sival_ptr;
202
    }
203
}
204

    
205
static void tswap_siginfo(target_siginfo_t *tinfo, 
206
                          const target_siginfo_t *info)
207
{
208
    int sig;
209
    sig = info->si_signo;
210
    tinfo->si_signo = tswap32(sig);
211
    tinfo->si_errno = tswap32(info->si_errno);
212
    tinfo->si_code = tswap32(info->si_code);
213
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || 
214
        sig == SIGBUS || sig == SIGTRAP) {
215
        tinfo->_sifields._sigfault._addr = 
216
            tswapl(info->_sifields._sigfault._addr);
217
    } else if (sig >= TARGET_SIGRTMIN) {
218
        tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
219
        tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
220
        tinfo->_sifields._rt._sigval.sival_ptr = 
221
            tswapl(info->_sifields._rt._sigval.sival_ptr);
222
    }
223
}
224

    
225

    
226
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
227
{
228
    host_to_target_siginfo_noswap(tinfo, info);
229
    tswap_siginfo(tinfo, tinfo);
230
}
231

    
232
/* XXX: we support only POSIX RT signals are used. */
233
/* XXX: find a solution for 64 bit (additionnal malloced data is needed) */
234
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
235
{
236
    info->si_signo = tswap32(tinfo->si_signo);
237
    info->si_errno = tswap32(tinfo->si_errno);
238
    info->si_code = tswap32(tinfo->si_code);
239
    info->si_pid = tswap32(tinfo->_sifields._rt._pid);
240
    info->si_uid = tswap32(tinfo->_sifields._rt._uid);
241
    info->si_value.sival_ptr = 
242
        (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
243
}
244

    
245
void signal_init(void)
246
{
247
    struct sigaction act;
248
    int i, j;
249

    
250
    /* generate signal conversion tables */
251
    for(i = 1; i <= 64; i++) {
252
        if (host_to_target_signal_table[i] == 0)
253
            host_to_target_signal_table[i] = i;
254
    }
255
    for(i = 1; i <= 64; i++) {
256
        j = host_to_target_signal_table[i];
257
        target_to_host_signal_table[j] = i;
258
    }
259
        
260
    /* set all host signal handlers. ALL signals are blocked during
261
       the handlers to serialize them. */
262
    sigfillset(&act.sa_mask);
263
    act.sa_flags = SA_SIGINFO;
264
    act.sa_sigaction = host_signal_handler;
265
    for(i = 1; i < NSIG; i++) {
266
        sigaction(i, &act, NULL);
267
    }
268
    
269
    memset(sigact_table, 0, sizeof(sigact_table));
270

    
271
    first_free = &sigqueue_table[0];
272
    for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) 
273
        sigqueue_table[i].next = &sigqueue_table[i + 1];
274
    sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
275
}
276

    
277
/* signal queue handling */
278

    
279
static inline struct sigqueue *alloc_sigqueue(void)
280
{
281
    struct sigqueue *q = first_free;
282
    if (!q)
283
        return NULL;
284
    first_free = q->next;
285
    return q;
286
}
287

    
288
static inline void free_sigqueue(struct sigqueue *q)
289
{
290
    q->next = first_free;
291
    first_free = q;
292
}
293

    
294
/* abort execution with signal */
295
void __attribute((noreturn)) force_sig(int sig)
296
{
297
    int host_sig;
298
    host_sig = target_to_host_signal(sig);
299
    fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n", 
300
            sig, strsignal(host_sig));
301
#if 1
302
    _exit(-host_sig);
303
#else
304
    {
305
        struct sigaction act;
306
        sigemptyset(&act.sa_mask);
307
        act.sa_flags = SA_SIGINFO;
308
        act.sa_sigaction = SIG_DFL;
309
        sigaction(SIGABRT, &act, NULL);
310
        abort();
311
    }
312
#endif
313
}
314

    
315
/* queue a signal so that it will be send to the virtual CPU as soon
316
   as possible */
317
int queue_signal(int sig, target_siginfo_t *info)
318
{
319
    struct emulated_sigaction *k;
320
    struct sigqueue *q, **pq;
321
    target_ulong handler;
322

    
323
#if defined(DEBUG_SIGNAL)
324
    fprintf(stderr, "queue_signal: sig=%d\n", 
325
            sig);
326
#endif
327
    k = &sigact_table[sig - 1];
328
    handler = k->sa._sa_handler;
329
    if (handler == TARGET_SIG_DFL) {
330
        /* default handler : ignore some signal. The other are fatal */
331
        if (sig != TARGET_SIGCHLD && 
332
            sig != TARGET_SIGURG && 
333
            sig != TARGET_SIGWINCH) {
334
            force_sig(sig);
335
        } else {
336
            return 0; /* indicate ignored */
337
        }
338
    } else if (handler == TARGET_SIG_IGN) {
339
        /* ignore signal */
340
        return 0;
341
    } else if (handler == TARGET_SIG_ERR) {
342
        force_sig(sig);
343
    } else {
344
        pq = &k->first;
345
        if (sig < TARGET_SIGRTMIN) {
346
            /* if non real time signal, we queue exactly one signal */
347
            if (!k->pending)
348
                q = &k->info;
349
            else
350
                return 0;
351
        } else {
352
            if (!k->pending) {
353
                /* first signal */
354
                q = &k->info;
355
            } else {
356
                q = alloc_sigqueue();
357
                if (!q)
358
                    return -EAGAIN;
359
                while (*pq != NULL)
360
                    pq = &(*pq)->next;
361
            }
362
        }
363
        *pq = q;
364
        q->info = *info;
365
        q->next = NULL;
366
        k->pending = 1;
367
        /* signal that a new signal is pending */
368
        signal_pending = 1;
369
        return 1; /* indicates that the signal was queued */
370
    }
371
}
372

    
373
static void host_signal_handler(int host_signum, siginfo_t *info, 
374
                                void *puc)
375
{
376
    int sig;
377
    target_siginfo_t tinfo;
378

    
379
    /* the CPU emulator uses some host signals to detect exceptions,
380
       we we forward to it some signals */
381
    if (host_signum == SIGSEGV || host_signum == SIGBUS 
382
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
383
        || host_signum == SIGFPE
384
#endif
385
        ) {
386
        if (cpu_signal_handler(host_signum, info, puc))
387
            return;
388
    }
389

    
390
    /* get target signal number */
391
    sig = host_to_target_signal(host_signum);
392
    if (sig < 1 || sig > TARGET_NSIG)
393
        return;
394
#if defined(DEBUG_SIGNAL)
395
    fprintf(stderr, "qemu: got signal %d\n", sig);
396
#endif
397
    host_to_target_siginfo_noswap(&tinfo, info);
398
    if (queue_signal(sig, &tinfo) == 1) {
399
        /* interrupt the virtual CPU as soon as possible */
400
        cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
401
    }
402
}
403

    
404
int do_sigaction(int sig, const struct target_sigaction *act,
405
                 struct target_sigaction *oact)
406
{
407
    struct emulated_sigaction *k;
408
    struct sigaction act1;
409
    int host_sig;
410

    
411
    if (sig < 1 || sig > TARGET_NSIG)
412
        return -EINVAL;
413
    k = &sigact_table[sig - 1];
414
#if defined(DEBUG_SIGNAL)
415
    fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", 
416
            sig, (int)act, (int)oact);
417
#endif
418
    if (oact) {
419
        oact->_sa_handler = tswapl(k->sa._sa_handler);
420
        oact->sa_flags = tswapl(k->sa.sa_flags);
421
        oact->sa_restorer = tswapl(k->sa.sa_restorer);
422
        oact->sa_mask = k->sa.sa_mask;
423
    }
424
    if (act) {
425
        k->sa._sa_handler = tswapl(act->_sa_handler);
426
        k->sa.sa_flags = tswapl(act->sa_flags);
427
        k->sa.sa_restorer = tswapl(act->sa_restorer);
428
        k->sa.sa_mask = act->sa_mask;
429

    
430
        /* we update the host linux signal state */
431
        host_sig = target_to_host_signal(sig);
432
        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
433
            sigfillset(&act1.sa_mask);
434
            act1.sa_flags = SA_SIGINFO;
435
            if (k->sa.sa_flags & TARGET_SA_RESTART)
436
                act1.sa_flags |= SA_RESTART;
437
            /* NOTE: it is important to update the host kernel signal
438
               ignore state to avoid getting unexpected interrupted
439
               syscalls */
440
            if (k->sa._sa_handler == TARGET_SIG_IGN) {
441
                act1.sa_sigaction = (void *)SIG_IGN;
442
            } else if (k->sa._sa_handler == TARGET_SIG_DFL) {
443
                act1.sa_sigaction = (void *)SIG_DFL;
444
            } else {
445
                act1.sa_sigaction = host_signal_handler;
446
            }
447
            sigaction(host_sig, &act1, NULL);
448
        }
449
    }
450
    return 0;
451
}
452

    
453
#ifndef offsetof
454
#define offsetof(type, field) ((size_t) &((type *)0)->field)
455
#endif
456

    
457
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, 
458
                                       const target_siginfo_t *info)
459
{
460
    tswap_siginfo(tinfo, info);
461
    return 0;
462
}
463

    
464
#ifdef TARGET_I386
465

    
466
/* from the Linux kernel */
467

    
468
struct target_fpreg {
469
        uint16_t significand[4];
470
        uint16_t exponent;
471
};
472

    
473
struct target_fpxreg {
474
        uint16_t significand[4];
475
        uint16_t exponent;
476
        uint16_t padding[3];
477
};
478

    
479
struct target_xmmreg {
480
        target_ulong element[4];
481
};
482

    
483
struct target_fpstate {
484
        /* Regular FPU environment */
485
        target_ulong         cw;
486
        target_ulong        sw;
487
        target_ulong        tag;
488
        target_ulong        ipoff;
489
        target_ulong        cssel;
490
        target_ulong        dataoff;
491
        target_ulong        datasel;
492
        struct target_fpreg        _st[8];
493
        uint16_t        status;
494
        uint16_t        magic;                /* 0xffff = regular FPU data only */
495

    
496
        /* FXSR FPU environment */
497
        target_ulong        _fxsr_env[6];        /* FXSR FPU env is ignored */
498
        target_ulong        mxcsr;
499
        target_ulong        reserved;
500
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
501
        struct target_xmmreg        _xmm[8];
502
        target_ulong        padding[56];
503
};
504

    
505
#define X86_FXSR_MAGIC                0x0000
506

    
507
struct target_sigcontext {
508
        uint16_t gs, __gsh;
509
        uint16_t fs, __fsh;
510
        uint16_t es, __esh;
511
        uint16_t ds, __dsh;
512
        target_ulong edi;
513
        target_ulong esi;
514
        target_ulong ebp;
515
        target_ulong esp;
516
        target_ulong ebx;
517
        target_ulong edx;
518
        target_ulong ecx;
519
        target_ulong eax;
520
        target_ulong trapno;
521
        target_ulong err;
522
        target_ulong eip;
523
        uint16_t cs, __csh;
524
        target_ulong eflags;
525
        target_ulong esp_at_signal;
526
        uint16_t ss, __ssh;
527
        target_ulong fpstate; /* pointer */
528
        target_ulong oldmask;
529
        target_ulong cr2;
530
};
531

    
532
typedef struct target_sigaltstack {
533
        target_ulong ss_sp;
534
        int ss_flags;
535
        target_ulong ss_size;
536
} target_stack_t;
537

    
538
struct target_ucontext {
539
        target_ulong          uc_flags;
540
        target_ulong      uc_link;
541
        target_stack_t          uc_stack;
542
        struct target_sigcontext uc_mcontext;
543
        target_sigset_t          uc_sigmask;        /* mask last for extensibility */
544
};
545

    
546
struct sigframe
547
{
548
    target_ulong pretcode;
549
    int sig;
550
    struct target_sigcontext sc;
551
    struct target_fpstate fpstate;
552
    target_ulong extramask[TARGET_NSIG_WORDS-1];
553
    char retcode[8];
554
};
555

    
556
struct rt_sigframe
557
{
558
    target_ulong pretcode;
559
    int sig;
560
    target_ulong pinfo;
561
    target_ulong puc;
562
    struct target_siginfo info;
563
    struct target_ucontext uc;
564
    struct target_fpstate fpstate;
565
    char retcode[8];
566
};
567

    
568
/*
569
 * Set up a signal frame.
570
 */
571

    
572
/* XXX: save x87 state */
573
static int
574
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
575
                 CPUX86State *env, unsigned long mask)
576
{
577
        int err = 0;
578

    
579
        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
580
        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
581
        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
582
        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
583
        err |= __put_user(env->regs[R_EDI], &sc->edi);
584
        err |= __put_user(env->regs[R_ESI], &sc->esi);
585
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
586
        err |= __put_user(env->regs[R_ESP], &sc->esp);
587
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
588
        err |= __put_user(env->regs[R_EDX], &sc->edx);
589
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
590
        err |= __put_user(env->regs[R_EAX], &sc->eax);
591
        err |= __put_user(env->exception_index, &sc->trapno);
592
        err |= __put_user(env->error_code, &sc->err);
593
        err |= __put_user(env->eip, &sc->eip);
594
        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
595
        err |= __put_user(env->eflags, &sc->eflags);
596
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
597
        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
598

    
599
        cpu_x86_fsave(env, (void *)fpstate, 1);
600
        fpstate->status = fpstate->sw;
601
        err |= __put_user(0xffff, &fpstate->magic);
602
        err |= __put_user(fpstate, &sc->fpstate);
603

    
604
        /* non-iBCS2 extensions.. */
605
        err |= __put_user(mask, &sc->oldmask);
606
        err |= __put_user(env->cr[2], &sc->cr2);
607
        return err;
608
}
609

    
610
/*
611
 * Determine which stack to use..
612
 */
613

    
614
static inline void *
615
get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
616
{
617
        unsigned long esp;
618

    
619
        /* Default to using normal stack */
620
        esp = env->regs[R_ESP];
621
#if 0
622
        /* This is the X/Open sanctioned signal stack switching.  */
623
        if (ka->sa.sa_flags & SA_ONSTACK) {
624
                if (sas_ss_flags(esp) == 0)
625
                        esp = current->sas_ss_sp + current->sas_ss_size;
626
        }
627

628
        /* This is the legacy signal stack switching. */
629
        else 
630
#endif
631
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
632
            !(ka->sa.sa_flags & TARGET_SA_RESTORER) &&
633
            ka->sa.sa_restorer) {
634
            esp = (unsigned long) ka->sa.sa_restorer;
635
        }
636
        return (void *)((esp - frame_size) & -8ul);
637
}
638

    
639
static void setup_frame(int sig, struct emulated_sigaction *ka,
640
                        target_sigset_t *set, CPUX86State *env)
641
{
642
        struct sigframe *frame;
643
        int err = 0;
644

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

    
647
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
648
                goto give_sigsegv;
649
        err |= __put_user((/*current->exec_domain
650
                           && current->exec_domain->signal_invmap
651
                           && sig < 32
652
                           ? current->exec_domain->signal_invmap[sig]
653
                           : */ sig),
654
                          &frame->sig);
655
        if (err)
656
                goto give_sigsegv;
657

    
658
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);
659
        if (err)
660
                goto give_sigsegv;
661

    
662
        if (TARGET_NSIG_WORDS > 1) {
663
                err |= __copy_to_user(frame->extramask, &set->sig[1],
664
                                      sizeof(frame->extramask));
665
        }
666
        if (err)
667
                goto give_sigsegv;
668

    
669
        /* Set up to return from userspace.  If provided, use a stub
670
           already in userspace.  */
671
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
672
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
673
        } else {
674
                err |= __put_user(frame->retcode, &frame->pretcode);
675
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
676
                err |= __put_user(0xb858, (short *)(frame->retcode+0));
677
                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
678
                err |= __put_user(0x80cd, (short *)(frame->retcode+6));
679
        }
680

    
681
        if (err)
682
                goto give_sigsegv;
683

    
684
        /* Set up registers for signal handler */
685
        env->regs[R_ESP] = (unsigned long) frame;
686
        env->eip = (unsigned long) ka->sa._sa_handler;
687

    
688
        cpu_x86_load_seg(env, R_DS, __USER_DS);
689
        cpu_x86_load_seg(env, R_ES, __USER_DS);
690
        cpu_x86_load_seg(env, R_SS, __USER_DS);
691
        cpu_x86_load_seg(env, R_CS, __USER_CS);
692
        env->eflags &= ~TF_MASK;
693

    
694
        return;
695

    
696
give_sigsegv:
697
        if (sig == TARGET_SIGSEGV)
698
                ka->sa._sa_handler = TARGET_SIG_DFL;
699
        force_sig(TARGET_SIGSEGV /* , current */);
700
}
701

    
702
static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
703
                           target_siginfo_t *info,
704
                           target_sigset_t *set, CPUX86State *env)
705
{
706
        struct rt_sigframe *frame;
707
        int err = 0;
708

    
709
        frame = get_sigframe(ka, env, sizeof(*frame));
710

    
711
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
712
                goto give_sigsegv;
713

    
714
        err |= __put_user((/*current->exec_domain
715
                               && current->exec_domain->signal_invmap
716
                               && sig < 32
717
                               ? current->exec_domain->signal_invmap[sig]
718
                           : */sig),
719
                          &frame->sig);
720
        err |= __put_user((target_ulong)&frame->info, &frame->pinfo);
721
        err |= __put_user((target_ulong)&frame->uc, &frame->puc);
722
        err |= copy_siginfo_to_user(&frame->info, info);
723
        if (err)
724
                goto give_sigsegv;
725

    
726
        /* Create the ucontext.  */
727
        err |= __put_user(0, &frame->uc.uc_flags);
728
        err |= __put_user(0, &frame->uc.uc_link);
729
        err |= __put_user(/*current->sas_ss_sp*/ 0, &frame->uc.uc_stack.ss_sp);
730
        err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,
731
                          &frame->uc.uc_stack.ss_flags);
732
        err |= __put_user(/* current->sas_ss_size */ 0, &frame->uc.uc_stack.ss_size);
733
        err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
734
                                env, set->sig[0]);
735
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
736
        if (err)
737
                goto give_sigsegv;
738

    
739
        /* Set up to return from userspace.  If provided, use a stub
740
           already in userspace.  */
741
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
742
                err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
743
        } else {
744
                err |= __put_user(frame->retcode, &frame->pretcode);
745
                /* This is movl $,%eax ; int $0x80 */
746
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
747
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
748
                err |= __put_user(0x80cd, (short *)(frame->retcode+5));
749
        }
750

    
751
        if (err)
752
                goto give_sigsegv;
753

    
754
        /* Set up registers for signal handler */
755
        env->regs[R_ESP] = (unsigned long) frame;
756
        env->eip = (unsigned long) ka->sa._sa_handler;
757

    
758
        cpu_x86_load_seg(env, R_DS, __USER_DS);
759
        cpu_x86_load_seg(env, R_ES, __USER_DS);
760
        cpu_x86_load_seg(env, R_SS, __USER_DS);
761
        cpu_x86_load_seg(env, R_CS, __USER_CS);
762
        env->eflags &= ~TF_MASK;
763

    
764
        return;
765

    
766
give_sigsegv:
767
        if (sig == TARGET_SIGSEGV)
768
                ka->sa._sa_handler = TARGET_SIG_DFL;
769
        force_sig(TARGET_SIGSEGV /* , current */);
770
}
771

    
772
static int
773
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
774
{
775
        unsigned int err = 0;
776

    
777
        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));
778
        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));
779
        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));
780
        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));
781

    
782
        env->regs[R_EDI] = ldl(&sc->edi);
783
        env->regs[R_ESI] = ldl(&sc->esi);
784
        env->regs[R_EBP] = ldl(&sc->ebp);
785
        env->regs[R_ESP] = ldl(&sc->esp);
786
        env->regs[R_EBX] = ldl(&sc->ebx);
787
        env->regs[R_EDX] = ldl(&sc->edx);
788
        env->regs[R_ECX] = ldl(&sc->ecx);
789
        env->eip = ldl(&sc->eip);
790

    
791
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
792
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
793
        
794
        {
795
                unsigned int tmpflags;
796
                tmpflags = ldl(&sc->eflags);
797
                env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
798
                //                regs->orig_eax = -1;                /* disable syscall checks */
799
        }
800

    
801
        {
802
                struct _fpstate * buf;
803
                buf = (void *)ldl(&sc->fpstate);
804
                if (buf) {
805
#if 0
806
                        if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
807
                                goto badframe;
808
#endif
809
                        cpu_x86_frstor(env, (void *)buf, 1);
810
                }
811
        }
812

    
813
        *peax = ldl(&sc->eax);
814
        return err;
815
#if 0
816
badframe:
817
        return 1;
818
#endif
819
}
820

    
821
long do_sigreturn(CPUX86State *env)
822
{
823
    struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
824
    target_sigset_t target_set;
825
    sigset_t set;
826
    int eax, i;
827

    
828
#if defined(DEBUG_SIGNAL)
829
    fprintf(stderr, "do_sigreturn\n");
830
#endif
831
    /* set blocked signals */
832
    target_set.sig[0] = frame->sc.oldmask;
833
    for(i = 1; i < TARGET_NSIG_WORDS; i++)
834
        target_set.sig[i] = frame->extramask[i - 1];
835

    
836
    target_to_host_sigset(&set, &target_set);
837
    sigprocmask(SIG_SETMASK, &set, NULL);
838
    
839
    /* restore registers */
840
    if (restore_sigcontext(env, &frame->sc, &eax))
841
        goto badframe;
842
    return eax;
843

    
844
badframe:
845
    force_sig(TARGET_SIGSEGV);
846
    return 0;
847
}
848

    
849
long do_rt_sigreturn(CPUX86State *env)
850
{
851
        struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
852
        target_sigset_t target_set;
853
        sigset_t set;
854
        //        stack_t st;
855
        int eax;
856

    
857
#if 0
858
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
859
                goto badframe;
860
#endif
861
        memcpy(&target_set, &frame->uc.uc_sigmask, sizeof(target_sigset_t));
862

    
863
        target_to_host_sigset(&set, &target_set);
864
        sigprocmask(SIG_SETMASK, &set, NULL);
865
        
866
        if (restore_sigcontext(env, &frame->uc.uc_mcontext, &eax))
867
                goto badframe;
868

    
869
#if 0
870
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
871
                goto badframe;
872
        /* It is more difficult to avoid calling this function than to
873
           call it and ignore errors.  */
874
        do_sigaltstack(&st, NULL, regs->esp);
875
#endif
876
        return eax;
877

    
878
badframe:
879
        force_sig(TARGET_SIGSEGV);
880
        return 0;
881
}
882

    
883
#elif defined(TARGET_ARM)
884

    
885
struct target_sigcontext {
886
        target_ulong trap_no;
887
        target_ulong error_code;
888
        target_ulong oldmask;
889
        target_ulong arm_r0;
890
        target_ulong arm_r1;
891
        target_ulong arm_r2;
892
        target_ulong arm_r3;
893
        target_ulong arm_r4;
894
        target_ulong arm_r5;
895
        target_ulong arm_r6;
896
        target_ulong arm_r7;
897
        target_ulong arm_r8;
898
        target_ulong arm_r9;
899
        target_ulong arm_r10;
900
        target_ulong arm_fp;
901
        target_ulong arm_ip;
902
        target_ulong arm_sp;
903
        target_ulong arm_lr;
904
        target_ulong arm_pc;
905
        target_ulong arm_cpsr;
906
        target_ulong fault_address;
907
};
908

    
909
typedef struct target_sigaltstack {
910
        target_ulong ss_sp;
911
        int ss_flags;
912
        target_ulong ss_size;
913
} target_stack_t;
914

    
915
struct target_ucontext {
916
    target_ulong uc_flags;
917
    target_ulong uc_link;
918
    target_stack_t uc_stack;
919
    struct target_sigcontext uc_mcontext;
920
    target_sigset_t  uc_sigmask;        /* mask last for extensibility */
921
};
922

    
923
struct sigframe
924
{
925
    struct target_sigcontext sc;
926
    target_ulong extramask[TARGET_NSIG_WORDS-1];
927
    target_ulong retcode;
928
};
929

    
930
struct rt_sigframe
931
{
932
    struct target_siginfo *pinfo;
933
    void *puc;
934
    struct target_siginfo info;
935
    struct target_ucontext uc;
936
    target_ulong retcode;
937
};
938

    
939
#define TARGET_CONFIG_CPU_32 1
940

    
941
/*
942
 * For ARM syscalls, we encode the syscall number into the instruction.
943
 */
944
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
945
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
946

    
947
/*
948
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
949
 * need two 16-bit instructions.
950
 */
951
#define SWI_THUMB_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
952
#define SWI_THUMB_RT_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
953

    
954
static const target_ulong retcodes[4] = {
955
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
956
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
957
};
958

    
959

    
960
#define __put_user_error(x,p,e) __put_user(x, p)
961
#define __get_user_error(x,p,e) __get_user(x, p)
962

    
963
static inline int valid_user_regs(CPUState *regs)
964
{
965
    return 1;
966
}
967

    
968
static int
969
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
970
                 CPUState *env, unsigned long mask)
971
{
972
        int err = 0;
973

    
974
        __put_user_error(env->regs[0], &sc->arm_r0, err);
975
        __put_user_error(env->regs[1], &sc->arm_r1, err);
976
        __put_user_error(env->regs[2], &sc->arm_r2, err);
977
        __put_user_error(env->regs[3], &sc->arm_r3, err);
978
        __put_user_error(env->regs[4], &sc->arm_r4, err);
979
        __put_user_error(env->regs[5], &sc->arm_r5, err);
980
        __put_user_error(env->regs[6], &sc->arm_r6, err);
981
        __put_user_error(env->regs[7], &sc->arm_r7, err);
982
        __put_user_error(env->regs[8], &sc->arm_r8, err);
983
        __put_user_error(env->regs[9], &sc->arm_r9, err);
984
        __put_user_error(env->regs[10], &sc->arm_r10, err);
985
        __put_user_error(env->regs[11], &sc->arm_fp, err);
986
        __put_user_error(env->regs[12], &sc->arm_ip, err);
987
        __put_user_error(env->regs[13], &sc->arm_sp, err);
988
        __put_user_error(env->regs[14], &sc->arm_lr, err);
989
        __put_user_error(env->regs[15], &sc->arm_pc, err);
990
#ifdef TARGET_CONFIG_CPU_32
991
        __put_user_error(env->cpsr, &sc->arm_cpsr, err);
992
#endif
993

    
994
        __put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err);
995
        __put_user_error(/* current->thread.error_code */ 0, &sc->error_code, err);
996
        __put_user_error(/* current->thread.address */ 0, &sc->fault_address, err);
997
        __put_user_error(mask, &sc->oldmask, err);
998

    
999
        return err;
1000
}
1001

    
1002
static inline void *
1003
get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1004
{
1005
        unsigned long sp = regs->regs[13];
1006

    
1007
#if 0
1008
        /*
1009
         * This is the X/Open sanctioned signal stack switching.
1010
         */
1011
        if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
1012
                sp = current->sas_ss_sp + current->sas_ss_size;
1013
#endif
1014
        /*
1015
         * ATPCS B01 mandates 8-byte alignment
1016
         */
1017
        return (void *)((sp - framesize) & ~7);
1018
}
1019

    
1020
static int
1021
setup_return(CPUState *env, struct emulated_sigaction *ka,
1022
             target_ulong *rc, void *frame, int usig)
1023
{
1024
        target_ulong handler = (target_ulong)ka->sa._sa_handler;
1025
        target_ulong retcode;
1026
        int thumb = 0;
1027
#if defined(TARGET_CONFIG_CPU_32)
1028
        target_ulong cpsr = env->cpsr;
1029

    
1030
#if 0
1031
        /*
1032
         * Maybe we need to deliver a 32-bit signal to a 26-bit task.
1033
         */
1034
        if (ka->sa.sa_flags & SA_THIRTYTWO)
1035
                cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
1036

1037
#ifdef CONFIG_ARM_THUMB
1038
        if (elf_hwcap & HWCAP_THUMB) {
1039
                /*
1040
                 * The LSB of the handler determines if we're going to
1041
                 * be using THUMB or ARM mode for this signal handler.
1042
                 */
1043
                thumb = handler & 1;
1044

1045
                if (thumb)
1046
                        cpsr |= T_BIT;
1047
                else
1048
                        cpsr &= ~T_BIT;
1049
        }
1050
#endif
1051
#endif
1052
#endif /* TARGET_CONFIG_CPU_32 */
1053

    
1054
        if (ka->sa.sa_flags & TARGET_SA_RESTORER) {
1055
                retcode = (target_ulong)ka->sa.sa_restorer;
1056
        } else {
1057
                unsigned int idx = thumb;
1058

    
1059
                if (ka->sa.sa_flags & TARGET_SA_SIGINFO)
1060
                        idx += 2;
1061

    
1062
                if (__put_user(retcodes[idx], rc))
1063
                        return 1;
1064
#if 0
1065
                flush_icache_range((target_ulong)rc,
1066
                                   (target_ulong)(rc + 1));
1067
#endif
1068
                retcode = ((target_ulong)rc) + thumb;
1069
        }
1070

    
1071
        env->regs[0] = usig;
1072
        env->regs[13] = (target_ulong)frame;
1073
        env->regs[14] = retcode;
1074
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1075

    
1076
#ifdef TARGET_CONFIG_CPU_32
1077
        env->cpsr = cpsr;
1078
#endif
1079

    
1080
        return 0;
1081
}
1082

    
1083
static void setup_frame(int usig, struct emulated_sigaction *ka,
1084
                        target_sigset_t *set, CPUState *regs)
1085
{
1086
        struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));
1087
        int err = 0;
1088

    
1089
        err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);
1090

    
1091
        if (TARGET_NSIG_WORDS > 1) {
1092
                err |= __copy_to_user(frame->extramask, &set->sig[1],
1093
                                      sizeof(frame->extramask));
1094
        }
1095

    
1096
        if (err == 0)
1097
            err = setup_return(regs, ka, &frame->retcode, frame, usig);
1098
        //        return err;
1099
}
1100

    
1101
static void setup_rt_frame(int usig, struct emulated_sigaction *ka, 
1102
                           target_siginfo_t *info,
1103
                           target_sigset_t *set, CPUState *env)
1104
{
1105
        struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));
1106
        int err = 0;
1107

    
1108
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
1109
            return /* 1 */;
1110

    
1111
        __put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);
1112
        __put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);
1113
        err |= copy_siginfo_to_user(&frame->info, info);
1114

    
1115
        /* Clear all the bits of the ucontext we don't use.  */
1116
        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
1117

    
1118
        err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
1119
                                env, set->sig[0]);
1120
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
1121

    
1122
        if (err == 0)
1123
                err = setup_return(env, ka, &frame->retcode, frame, usig);
1124

    
1125
        if (err == 0) {
1126
                /*
1127
                 * For realtime signals we must also set the second and third
1128
                 * arguments for the signal handler.
1129
                 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
1130
                 */
1131
            env->regs[1] = (target_ulong)frame->pinfo;
1132
            env->regs[2] = (target_ulong)frame->puc;
1133
        }
1134

    
1135
        //        return err;
1136
}
1137

    
1138
static int
1139
restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1140
{
1141
        int err = 0;
1142

    
1143
        __get_user_error(env->regs[0], &sc->arm_r0, err);
1144
        __get_user_error(env->regs[1], &sc->arm_r1, err);
1145
        __get_user_error(env->regs[2], &sc->arm_r2, err);
1146
        __get_user_error(env->regs[3], &sc->arm_r3, err);
1147
        __get_user_error(env->regs[4], &sc->arm_r4, err);
1148
        __get_user_error(env->regs[5], &sc->arm_r5, err);
1149
        __get_user_error(env->regs[6], &sc->arm_r6, err);
1150
        __get_user_error(env->regs[7], &sc->arm_r7, err);
1151
        __get_user_error(env->regs[8], &sc->arm_r8, err);
1152
        __get_user_error(env->regs[9], &sc->arm_r9, err);
1153
        __get_user_error(env->regs[10], &sc->arm_r10, err);
1154
        __get_user_error(env->regs[11], &sc->arm_fp, err);
1155
        __get_user_error(env->regs[12], &sc->arm_ip, err);
1156
        __get_user_error(env->regs[13], &sc->arm_sp, err);
1157
        __get_user_error(env->regs[14], &sc->arm_lr, err);
1158
        __get_user_error(env->regs[15], &sc->arm_pc, err);
1159
#ifdef TARGET_CONFIG_CPU_32
1160
        __get_user_error(env->cpsr, &sc->arm_cpsr, err);
1161
#endif
1162

    
1163
        err |= !valid_user_regs(env);
1164

    
1165
        return err;
1166
}
1167

    
1168
long do_sigreturn(CPUState *env)
1169
{
1170
        struct sigframe *frame;
1171
        target_sigset_t set;
1172
        sigset_t host_set;
1173

    
1174
        /*
1175
         * Since we stacked the signal on a 64-bit boundary,
1176
         * then 'sp' should be word aligned here.  If it's
1177
         * not, then the user is trying to mess with us.
1178
         */
1179
        if (env->regs[13] & 7)
1180
                goto badframe;
1181

    
1182
        frame = (struct sigframe *)env->regs[13];
1183

    
1184
#if 0
1185
        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
1186
                goto badframe;
1187
#endif
1188
        if (__get_user(set.sig[0], &frame->sc.oldmask)
1189
            || (TARGET_NSIG_WORDS > 1
1190
                && __copy_from_user(&set.sig[1], &frame->extramask,
1191
                                    sizeof(frame->extramask))))
1192
                goto badframe;
1193

    
1194
        target_to_host_sigset(&host_set, &set);
1195
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1196

    
1197
        if (restore_sigcontext(env, &frame->sc))
1198
                goto badframe;
1199

    
1200
#if 0
1201
        /* Send SIGTRAP if we're single-stepping */
1202
        if (ptrace_cancel_bpt(current))
1203
                send_sig(SIGTRAP, current, 1);
1204
#endif
1205
        return env->regs[0];
1206

    
1207
badframe:
1208
        force_sig(SIGSEGV /* , current */);
1209
        return 0;
1210
}
1211

    
1212
long do_rt_sigreturn(CPUState *env)
1213
{
1214
        struct rt_sigframe *frame;
1215
        target_sigset_t set;
1216
        sigset_t host_set;
1217

    
1218
        /*
1219
         * Since we stacked the signal on a 64-bit boundary,
1220
         * then 'sp' should be word aligned here.  If it's
1221
         * not, then the user is trying to mess with us.
1222
         */
1223
        if (env->regs[13] & 7)
1224
                goto badframe;
1225

    
1226
        frame = (struct rt_sigframe *)env->regs[13];
1227

    
1228
#if 0
1229
        if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
1230
                goto badframe;
1231
#endif
1232
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
1233
                goto badframe;
1234

    
1235
        target_to_host_sigset(&host_set, &set);
1236
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1237

    
1238
        if (restore_sigcontext(env, &frame->uc.uc_mcontext))
1239
                goto badframe;
1240

    
1241
#if 0
1242
        /* Send SIGTRAP if we're single-stepping */
1243
        if (ptrace_cancel_bpt(current))
1244
                send_sig(SIGTRAP, current, 1);
1245
#endif
1246
        return env->regs[0];
1247

    
1248
badframe:
1249
        force_sig(SIGSEGV /* , current */);
1250
        return 0;
1251
}
1252

    
1253
#else
1254

    
1255
static void setup_frame(int sig, struct emulated_sigaction *ka,
1256
                        target_sigset_t *set, CPUState *env)
1257
{
1258
    fprintf(stderr, "setup_frame: not implemented\n");
1259
}
1260

    
1261
static void setup_rt_frame(int sig, struct emulated_sigaction *ka, 
1262
                           target_siginfo_t *info,
1263
                           target_sigset_t *set, CPUState *env)
1264
{
1265
    fprintf(stderr, "setup_rt_frame: not implemented\n");
1266
}
1267

    
1268
long do_sigreturn(CPUState *env)
1269
{
1270
    fprintf(stderr, "do_sigreturn: not implemented\n");
1271
    return -ENOSYS;
1272
}
1273

    
1274
long do_rt_sigreturn(CPUState *env)
1275
{
1276
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1277
    return -ENOSYS;
1278
}
1279

    
1280
#endif
1281

    
1282
void process_pending_signals(void *cpu_env)
1283
{
1284
    int sig;
1285
    target_ulong handler;
1286
    sigset_t set, old_set;
1287
    target_sigset_t target_old_set;
1288
    struct emulated_sigaction *k;
1289
    struct sigqueue *q;
1290
    
1291
    if (!signal_pending)
1292
        return;
1293

    
1294
    k = sigact_table;
1295
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
1296
        if (k->pending)
1297
            goto handle_signal;
1298
        k++;
1299
    }
1300
    /* if no signal is pending, just return */
1301
    signal_pending = 0;
1302
    return;
1303

    
1304
 handle_signal:
1305
#ifdef DEBUG_SIGNAL
1306
    fprintf(stderr, "qemu: process signal %d\n", sig);
1307
#endif
1308
    /* dequeue signal */
1309
    q = k->first;
1310
    k->first = q->next;
1311
    if (!k->first)
1312
        k->pending = 0;
1313

    
1314
    handler = k->sa._sa_handler;
1315
    if (handler == TARGET_SIG_DFL) {
1316
        /* default handler : ignore some signal. The other are fatal */
1317
        if (sig != TARGET_SIGCHLD && 
1318
            sig != TARGET_SIGURG && 
1319
            sig != TARGET_SIGWINCH) {
1320
            force_sig(sig);
1321
        }
1322
    } else if (handler == TARGET_SIG_IGN) {
1323
        /* ignore sig */
1324
    } else if (handler == TARGET_SIG_ERR) {
1325
        force_sig(sig);
1326
    } else {
1327
        /* compute the blocked signals during the handler execution */
1328
        target_to_host_sigset(&set, &k->sa.sa_mask);
1329
        /* SA_NODEFER indicates that the current signal should not be
1330
           blocked during the handler */
1331
        if (!(k->sa.sa_flags & TARGET_SA_NODEFER))
1332
            sigaddset(&set, target_to_host_signal(sig));
1333
        
1334
        /* block signals in the handler using Linux */
1335
        sigprocmask(SIG_BLOCK, &set, &old_set);
1336
        /* save the previous blocked signal state to restore it at the
1337
           end of the signal execution (see do_sigreturn) */
1338
        host_to_target_sigset(&target_old_set, &old_set);
1339

    
1340
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
1341
#ifdef TARGET_I386
1342
        {
1343
            CPUX86State *env = cpu_env;
1344
            if (env->eflags & VM_MASK)
1345
                save_v86_state(env);
1346
        }
1347
#endif
1348
        /* prepare the stack frame of the virtual CPU */
1349
        if (k->sa.sa_flags & TARGET_SA_SIGINFO)
1350
            setup_rt_frame(sig, k, &q->info, &target_old_set, cpu_env);
1351
        else
1352
            setup_frame(sig, k, &target_old_set, cpu_env);
1353
        if (k->sa.sa_flags & TARGET_SA_RESETHAND)
1354
            k->sa._sa_handler = TARGET_SIG_DFL;
1355
    }
1356
    if (q != &k->info)
1357
        free_sigqueue(q);
1358
}
1359

    
1360