Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 60b19691

History | View | Annotate | Download (90.8 kB)

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

    
29
#include "qemu.h"
30
#include "target_signal.h"
31

    
32
//#define DEBUG_SIGNAL
33

    
34
static struct target_sigaltstack target_sigaltstack_used = {
35
    .ss_sp = 0,
36
    .ss_size = 0,
37
    .ss_flags = TARGET_SS_DISABLE,
38
};
39

    
40
static struct target_sigaction sigact_table[TARGET_NSIG];
41

    
42
static void host_signal_handler(int host_signum, siginfo_t *info,
43
                                void *puc);
44

    
45
static uint8_t host_to_target_signal_table[65] = {
46
    [SIGHUP] = TARGET_SIGHUP,
47
    [SIGINT] = TARGET_SIGINT,
48
    [SIGQUIT] = TARGET_SIGQUIT,
49
    [SIGILL] = TARGET_SIGILL,
50
    [SIGTRAP] = TARGET_SIGTRAP,
51
    [SIGABRT] = TARGET_SIGABRT,
52
/*    [SIGIOT] = TARGET_SIGIOT,*/
53
    [SIGBUS] = TARGET_SIGBUS,
54
    [SIGFPE] = TARGET_SIGFPE,
55
    [SIGKILL] = TARGET_SIGKILL,
56
    [SIGUSR1] = TARGET_SIGUSR1,
57
    [SIGSEGV] = TARGET_SIGSEGV,
58
    [SIGUSR2] = TARGET_SIGUSR2,
59
    [SIGPIPE] = TARGET_SIGPIPE,
60
    [SIGALRM] = TARGET_SIGALRM,
61
    [SIGTERM] = TARGET_SIGTERM,
62
#ifdef SIGSTKFLT
63
    [SIGSTKFLT] = TARGET_SIGSTKFLT,
64
#endif
65
    [SIGCHLD] = TARGET_SIGCHLD,
66
    [SIGCONT] = TARGET_SIGCONT,
67
    [SIGSTOP] = TARGET_SIGSTOP,
68
    [SIGTSTP] = TARGET_SIGTSTP,
69
    [SIGTTIN] = TARGET_SIGTTIN,
70
    [SIGTTOU] = TARGET_SIGTTOU,
71
    [SIGURG] = TARGET_SIGURG,
72
    [SIGXCPU] = TARGET_SIGXCPU,
73
    [SIGXFSZ] = TARGET_SIGXFSZ,
74
    [SIGVTALRM] = TARGET_SIGVTALRM,
75
    [SIGPROF] = TARGET_SIGPROF,
76
    [SIGWINCH] = TARGET_SIGWINCH,
77
    [SIGIO] = TARGET_SIGIO,
78
    [SIGPWR] = TARGET_SIGPWR,
79
    [SIGSYS] = TARGET_SIGSYS,
80
    /* next signals stay the same */
81
    /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
82
       host libpthread signals.  This assumes noone actually uses SIGRTMAX :-/
83
       To fix this properly we need to do manual signal delivery multiplexed
84
       over a single host signal.  */
85
    [__SIGRTMIN] = __SIGRTMAX,
86
    [__SIGRTMAX] = __SIGRTMIN,
87
};
88
static uint8_t target_to_host_signal_table[65];
89

    
90
static inline int on_sig_stack(unsigned long sp)
91
{
92
    return (sp - target_sigaltstack_used.ss_sp
93
            < target_sigaltstack_used.ss_size);
94
}
95

    
96
static inline int sas_ss_flags(unsigned long sp)
97
{
98
    return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
99
            : on_sig_stack(sp) ? SS_ONSTACK : 0);
100
}
101

    
102
static inline int host_to_target_signal(int sig)
103
{
104
    if (sig > 64)
105
        return sig;
106
    return host_to_target_signal_table[sig];
107
}
108

    
109
int target_to_host_signal(int sig)
110
{
111
    if (sig > 64)
112
        return sig;
113
    return target_to_host_signal_table[sig];
114
}
115

    
116
static inline void target_sigemptyset(target_sigset_t *set)
117
{
118
    memset(set, 0, sizeof(*set));
119
}
120

    
121
static inline void target_sigaddset(target_sigset_t *set, int signum)
122
{
123
    signum--;
124
    abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
125
    set->sig[signum / TARGET_NSIG_BPW] |= mask;
126
}
127

    
128
static inline int target_sigismember(const target_sigset_t *set, int signum)
129
{
130
    signum--;
131
    abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
132
    return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
133
}
134

    
135
static void host_to_target_sigset_internal(target_sigset_t *d,
136
                                           const sigset_t *s)
137
{
138
    int i;
139
    target_sigemptyset(d);
140
    for (i = 1; i <= TARGET_NSIG; i++) {
141
        if (sigismember(s, i)) {
142
            target_sigaddset(d, host_to_target_signal(i));
143
        }
144
    }
145
}
146

    
147
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
148
{
149
    target_sigset_t d1;
150
    int i;
151

    
152
    host_to_target_sigset_internal(&d1, s);
153
    for(i = 0;i < TARGET_NSIG_WORDS; i++)
154
        d->sig[i] = tswapl(d1.sig[i]);
155
}
156

    
157
static void target_to_host_sigset_internal(sigset_t *d,
158
                                           const target_sigset_t *s)
159
{
160
    int i;
161
    sigemptyset(d);
162
    for (i = 1; i <= TARGET_NSIG; i++) {
163
        if (target_sigismember(s, i)) {
164
            sigaddset(d, target_to_host_signal(i));
165
        }
166
     }
167
}
168

    
169
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
170
{
171
    target_sigset_t s1;
172
    int i;
173

    
174
    for(i = 0;i < TARGET_NSIG_WORDS; i++)
175
        s1.sig[i] = tswapl(s->sig[i]);
176
    target_to_host_sigset_internal(d, &s1);
177
}
178

    
179
void host_to_target_old_sigset(abi_ulong *old_sigset,
180
                               const sigset_t *sigset)
181
{
182
    target_sigset_t d;
183
    host_to_target_sigset(&d, sigset);
184
    *old_sigset = d.sig[0];
185
}
186

    
187
void target_to_host_old_sigset(sigset_t *sigset,
188
                               const abi_ulong *old_sigset)
189
{
190
    target_sigset_t d;
191
    int i;
192

    
193
    d.sig[0] = *old_sigset;
194
    for(i = 1;i < TARGET_NSIG_WORDS; i++)
195
        d.sig[i] = 0;
196
    target_to_host_sigset(sigset, &d);
197
}
198

    
199
/* siginfo conversion */
200

    
201
static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
202
                                                 const siginfo_t *info)
203
{
204
    int sig;
205
    sig = host_to_target_signal(info->si_signo);
206
    tinfo->si_signo = sig;
207
    tinfo->si_errno = 0;
208
    tinfo->si_code = info->si_code;
209
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
210
        sig == SIGBUS || sig == SIGTRAP) {
211
        /* should never come here, but who knows. The information for
212
           the target is irrelevant */
213
        tinfo->_sifields._sigfault._addr = 0;
214
    } else if (sig == SIGIO) {
215
        tinfo->_sifields._sigpoll._fd = info->si_fd;
216
    } else if (sig >= TARGET_SIGRTMIN) {
217
        tinfo->_sifields._rt._pid = info->si_pid;
218
        tinfo->_sifields._rt._uid = info->si_uid;
219
        /* XXX: potential problem if 64 bit */
220
        tinfo->_sifields._rt._sigval.sival_ptr =
221
            (abi_ulong)(unsigned long)info->si_value.sival_ptr;
222
    }
223
}
224

    
225
static void tswap_siginfo(target_siginfo_t *tinfo,
226
                          const target_siginfo_t *info)
227
{
228
    int sig;
229
    sig = info->si_signo;
230
    tinfo->si_signo = tswap32(sig);
231
    tinfo->si_errno = tswap32(info->si_errno);
232
    tinfo->si_code = tswap32(info->si_code);
233
    if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
234
        sig == SIGBUS || sig == SIGTRAP) {
235
        tinfo->_sifields._sigfault._addr =
236
            tswapl(info->_sifields._sigfault._addr);
237
    } else if (sig == SIGIO) {
238
        tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
239
    } else if (sig >= TARGET_SIGRTMIN) {
240
        tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
241
        tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
242
        tinfo->_sifields._rt._sigval.sival_ptr =
243
            tswapl(info->_sifields._rt._sigval.sival_ptr);
244
    }
245
}
246

    
247

    
248
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
249
{
250
    host_to_target_siginfo_noswap(tinfo, info);
251
    tswap_siginfo(tinfo, tinfo);
252
}
253

    
254
/* XXX: we support only POSIX RT signals are used. */
255
/* XXX: find a solution for 64 bit (additional malloced data is needed) */
256
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
257
{
258
    info->si_signo = tswap32(tinfo->si_signo);
259
    info->si_errno = tswap32(tinfo->si_errno);
260
    info->si_code = tswap32(tinfo->si_code);
261
    info->si_pid = tswap32(tinfo->_sifields._rt._pid);
262
    info->si_uid = tswap32(tinfo->_sifields._rt._uid);
263
    info->si_value.sival_ptr =
264
            (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
265
}
266

    
267
void signal_init(void)
268
{
269
    struct sigaction act;
270
    struct sigaction oact;
271
    int i, j;
272
    int host_sig;
273

    
274
    /* generate signal conversion tables */
275
    for(i = 1; i <= 64; i++) {
276
        if (host_to_target_signal_table[i] == 0)
277
            host_to_target_signal_table[i] = i;
278
    }
279
    for(i = 1; i <= 64; i++) {
280
        j = host_to_target_signal_table[i];
281
        target_to_host_signal_table[j] = i;
282
    }
283

    
284
    /* set all host signal handlers. ALL signals are blocked during
285
       the handlers to serialize them. */
286
    memset(sigact_table, 0, sizeof(sigact_table));
287

    
288
    sigfillset(&act.sa_mask);
289
    act.sa_flags = SA_SIGINFO;
290
    act.sa_sigaction = host_signal_handler;
291
    for(i = 1; i <= TARGET_NSIG; i++) {
292
        host_sig = target_to_host_signal(i);
293
        sigaction(host_sig, NULL, &oact);
294
        if (oact.sa_sigaction == (void *)SIG_IGN) {
295
            sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
296
        } else if (oact.sa_sigaction == (void *)SIG_DFL) {
297
            sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
298
        }
299
        /* If there's already a handler installed then something has
300
           gone horribly wrong, so don't even try to handle that case.  */
301
        /* Install some handlers for our own use.  */
302
        if (host_sig == SIGSEGV || host_sig == SIGBUS) {
303
            sigaction(host_sig, &act, NULL);
304
        }
305
    }
306
}
307

    
308
/* signal queue handling */
309

    
310
static inline struct sigqueue *alloc_sigqueue(CPUState *env)
311
{
312
    TaskState *ts = env->opaque;
313
    struct sigqueue *q = ts->first_free;
314
    if (!q)
315
        return NULL;
316
    ts->first_free = q->next;
317
    return q;
318
}
319

    
320
static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
321
{
322
    TaskState *ts = env->opaque;
323
    q->next = ts->first_free;
324
    ts->first_free = q;
325
}
326

    
327
/* abort execution with signal */
328
static void __attribute((noreturn)) force_sig(int sig)
329
{
330
    int host_sig;
331
    host_sig = target_to_host_signal(sig);
332
    fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
333
            sig, strsignal(host_sig));
334
#if 1
335
    _exit(-host_sig);
336
#else
337
    {
338
        struct sigaction act;
339
        sigemptyset(&act.sa_mask);
340
        act.sa_flags = SA_SIGINFO;
341
        act.sa_sigaction = SIG_DFL;
342
        sigaction(SIGABRT, &act, NULL);
343
        abort();
344
    }
345
#endif
346
}
347

    
348
/* queue a signal so that it will be send to the virtual CPU as soon
349
   as possible */
350
int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
351
{
352
    TaskState *ts = env->opaque;
353
    struct emulated_sigtable *k;
354
    struct sigqueue *q, **pq;
355
    abi_ulong handler;
356

    
357
#if defined(DEBUG_SIGNAL)
358
    fprintf(stderr, "queue_signal: sig=%d\n",
359
            sig);
360
#endif
361
    k = &ts->sigtab[sig - 1];
362
    handler = sigact_table[sig - 1]._sa_handler;
363
    if (handler == TARGET_SIG_DFL) {
364
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
365
            kill(getpid(),SIGSTOP);
366
            return 0;
367
        } else
368
        /* default handler : ignore some signal. The other are fatal */
369
        if (sig != TARGET_SIGCHLD &&
370
            sig != TARGET_SIGURG &&
371
            sig != TARGET_SIGWINCH &&
372
            sig != TARGET_SIGCONT) {
373
            force_sig(sig);
374
        } else {
375
            return 0; /* indicate ignored */
376
        }
377
    } else if (handler == TARGET_SIG_IGN) {
378
        /* ignore signal */
379
        return 0;
380
    } else if (handler == TARGET_SIG_ERR) {
381
        force_sig(sig);
382
    } else {
383
        pq = &k->first;
384
        if (sig < TARGET_SIGRTMIN) {
385
            /* if non real time signal, we queue exactly one signal */
386
            if (!k->pending)
387
                q = &k->info;
388
            else
389
                return 0;
390
        } else {
391
            if (!k->pending) {
392
                /* first signal */
393
                q = &k->info;
394
            } else {
395
                q = alloc_sigqueue(env);
396
                if (!q)
397
                    return -EAGAIN;
398
                while (*pq != NULL)
399
                    pq = &(*pq)->next;
400
            }
401
        }
402
        *pq = q;
403
        q->info = *info;
404
        q->next = NULL;
405
        k->pending = 1;
406
        /* signal that a new signal is pending */
407
        ts->signal_pending = 1;
408
        return 1; /* indicates that the signal was queued */
409
    }
410
}
411

    
412
static void host_signal_handler(int host_signum, siginfo_t *info,
413
                                void *puc)
414
{
415
    int sig;
416
    target_siginfo_t tinfo;
417

    
418
    /* the CPU emulator uses some host signals to detect exceptions,
419
       we we forward to it some signals */
420
    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
421
        if (cpu_signal_handler(host_signum, info, puc))
422
            return;
423
    }
424

    
425
    /* get target signal number */
426
    sig = host_to_target_signal(host_signum);
427
    if (sig < 1 || sig > TARGET_NSIG)
428
        return;
429
#if defined(DEBUG_SIGNAL)
430
    fprintf(stderr, "qemu: got signal %d\n", sig);
431
#endif
432
    host_to_target_siginfo_noswap(&tinfo, info);
433
    if (queue_signal(thread_env, sig, &tinfo) == 1) {
434
        /* interrupt the virtual CPU as soon as possible */
435
        cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
436
    }
437
}
438

    
439
/* do_sigaltstack() returns target values and errnos. */
440
/* compare linux/kernel/signal.c:do_sigaltstack() */
441
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
442
{
443
    int ret;
444
    struct target_sigaltstack oss;
445

    
446
    /* XXX: test errors */
447
    if(uoss_addr)
448
    {
449
        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
450
        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
451
        __put_user(sas_ss_flags(sp), &oss.ss_flags);
452
    }
453

    
454
    if(uss_addr)
455
    {
456
        struct target_sigaltstack *uss;
457
        struct target_sigaltstack ss;
458

    
459
        ret = -TARGET_EFAULT;
460
        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
461
            || __get_user(ss.ss_sp, &uss->ss_sp)
462
            || __get_user(ss.ss_size, &uss->ss_size)
463
            || __get_user(ss.ss_flags, &uss->ss_flags))
464
            goto out;
465
        unlock_user_struct(uss, uss_addr, 0);
466

    
467
        ret = -TARGET_EPERM;
468
        if (on_sig_stack(sp))
469
            goto out;
470

    
471
        ret = -TARGET_EINVAL;
472
        if (ss.ss_flags != TARGET_SS_DISABLE
473
            && ss.ss_flags != TARGET_SS_ONSTACK
474
            && ss.ss_flags != 0)
475
            goto out;
476

    
477
        if (ss.ss_flags == TARGET_SS_DISABLE) {
478
            ss.ss_size = 0;
479
            ss.ss_sp = 0;
480
        } else {
481
            ret = -TARGET_ENOMEM;
482
            if (ss.ss_size < MINSIGSTKSZ)
483
                goto out;
484
        }
485

    
486
        target_sigaltstack_used.ss_sp = ss.ss_sp;
487
        target_sigaltstack_used.ss_size = ss.ss_size;
488
    }
489

    
490
    if (uoss_addr) {
491
        ret = -TARGET_EFAULT;
492
        if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
493
            goto out;
494
    }
495

    
496
    ret = 0;
497
out:
498
    return ret;
499
}
500

    
501
/* do_sigaction() return host values and errnos */
502
int do_sigaction(int sig, const struct target_sigaction *act,
503
                 struct target_sigaction *oact)
504
{
505
    struct target_sigaction *k;
506
    struct sigaction act1;
507
    int host_sig;
508
    int ret = 0;
509

    
510
    if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
511
        return -EINVAL;
512
    k = &sigact_table[sig - 1];
513
#if defined(DEBUG_SIGNAL)
514
    fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
515
            sig, (int)act, (int)oact);
516
#endif
517
    if (oact) {
518
        oact->_sa_handler = tswapl(k->_sa_handler);
519
        oact->sa_flags = tswapl(k->sa_flags);
520
#if !defined(TARGET_MIPS)
521
        oact->sa_restorer = tswapl(k->sa_restorer);
522
#endif
523
        oact->sa_mask = k->sa_mask;
524
    }
525
    if (act) {
526
        /* FIXME: This is not threadsafe.  */
527
        k->_sa_handler = tswapl(act->_sa_handler);
528
        k->sa_flags = tswapl(act->sa_flags);
529
#if !defined(TARGET_MIPS)
530
        k->sa_restorer = tswapl(act->sa_restorer);
531
#endif
532
        k->sa_mask = act->sa_mask;
533

    
534
        /* we update the host linux signal state */
535
        host_sig = target_to_host_signal(sig);
536
        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
537
            sigfillset(&act1.sa_mask);
538
            act1.sa_flags = SA_SIGINFO;
539
            if (k->sa_flags & TARGET_SA_RESTART)
540
                act1.sa_flags |= SA_RESTART;
541
            /* NOTE: it is important to update the host kernel signal
542
               ignore state to avoid getting unexpected interrupted
543
               syscalls */
544
            if (k->_sa_handler == TARGET_SIG_IGN) {
545
                act1.sa_sigaction = (void *)SIG_IGN;
546
            } else if (k->_sa_handler == TARGET_SIG_DFL) {
547
                act1.sa_sigaction = (void *)SIG_DFL;
548
            } else {
549
                act1.sa_sigaction = host_signal_handler;
550
            }
551
            ret = sigaction(host_sig, &act1, NULL);
552
        }
553
    }
554
    return ret;
555
}
556

    
557
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
558
                                       const target_siginfo_t *info)
559
{
560
    tswap_siginfo(tinfo, info);
561
    return 0;
562
}
563

    
564
static inline int current_exec_domain_sig(int sig)
565
{
566
    return /* current->exec_domain && current->exec_domain->signal_invmap
567
              && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
568
}
569

    
570
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
571

    
572
/* from the Linux kernel */
573

    
574
struct target_fpreg {
575
        uint16_t significand[4];
576
        uint16_t exponent;
577
};
578

    
579
struct target_fpxreg {
580
        uint16_t significand[4];
581
        uint16_t exponent;
582
        uint16_t padding[3];
583
};
584

    
585
struct target_xmmreg {
586
        abi_ulong element[4];
587
};
588

    
589
struct target_fpstate {
590
        /* Regular FPU environment */
591
        abi_ulong       cw;
592
        abi_ulong       sw;
593
        abi_ulong       tag;
594
        abi_ulong       ipoff;
595
        abi_ulong       cssel;
596
        abi_ulong       dataoff;
597
        abi_ulong       datasel;
598
        struct target_fpreg        _st[8];
599
        uint16_t        status;
600
        uint16_t        magic;                /* 0xffff = regular FPU data only */
601

    
602
        /* FXSR FPU environment */
603
        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
604
        abi_ulong       mxcsr;
605
        abi_ulong       reserved;
606
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
607
        struct target_xmmreg        _xmm[8];
608
        abi_ulong       padding[56];
609
};
610

    
611
#define X86_FXSR_MAGIC                0x0000
612

    
613
struct target_sigcontext {
614
        uint16_t gs, __gsh;
615
        uint16_t fs, __fsh;
616
        uint16_t es, __esh;
617
        uint16_t ds, __dsh;
618
        abi_ulong edi;
619
        abi_ulong esi;
620
        abi_ulong ebp;
621
        abi_ulong esp;
622
        abi_ulong ebx;
623
        abi_ulong edx;
624
        abi_ulong ecx;
625
        abi_ulong eax;
626
        abi_ulong trapno;
627
        abi_ulong err;
628
        abi_ulong eip;
629
        uint16_t cs, __csh;
630
        abi_ulong eflags;
631
        abi_ulong esp_at_signal;
632
        uint16_t ss, __ssh;
633
        abi_ulong fpstate; /* pointer */
634
        abi_ulong oldmask;
635
        abi_ulong cr2;
636
};
637

    
638
struct target_ucontext {
639
        abi_ulong         tuc_flags;
640
        abi_ulong         tuc_link;
641
        target_stack_t          tuc_stack;
642
        struct target_sigcontext tuc_mcontext;
643
        target_sigset_t          tuc_sigmask;        /* mask last for extensibility */
644
};
645

    
646
struct sigframe
647
{
648
    abi_ulong pretcode;
649
    int sig;
650
    struct target_sigcontext sc;
651
    struct target_fpstate fpstate;
652
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
653
    char retcode[8];
654
};
655

    
656
struct rt_sigframe
657
{
658
    abi_ulong pretcode;
659
    int sig;
660
    abi_ulong pinfo;
661
    abi_ulong puc;
662
    struct target_siginfo info;
663
    struct target_ucontext uc;
664
    struct target_fpstate fpstate;
665
    char retcode[8];
666
};
667

    
668
/*
669
 * Set up a signal frame.
670
 */
671

    
672
/* XXX: save x87 state */
673
static int
674
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
675
                 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
676
{
677
        int err = 0;
678
        uint16_t magic;
679

    
680
        /* already locked in setup_frame() */
681
        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
682
        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
683
        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
684
        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
685
        err |= __put_user(env->regs[R_EDI], &sc->edi);
686
        err |= __put_user(env->regs[R_ESI], &sc->esi);
687
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
688
        err |= __put_user(env->regs[R_ESP], &sc->esp);
689
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
690
        err |= __put_user(env->regs[R_EDX], &sc->edx);
691
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
692
        err |= __put_user(env->regs[R_EAX], &sc->eax);
693
        err |= __put_user(env->exception_index, &sc->trapno);
694
        err |= __put_user(env->error_code, &sc->err);
695
        err |= __put_user(env->eip, &sc->eip);
696
        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
697
        err |= __put_user(env->eflags, &sc->eflags);
698
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
699
        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
700

    
701
        cpu_x86_fsave(env, fpstate_addr, 1);
702
        fpstate->status = fpstate->sw;
703
        magic = 0xffff;
704
        err |= __put_user(magic, &fpstate->magic);
705
        err |= __put_user(fpstate_addr, &sc->fpstate);
706

    
707
        /* non-iBCS2 extensions.. */
708
        err |= __put_user(mask, &sc->oldmask);
709
        err |= __put_user(env->cr[2], &sc->cr2);
710
        return err;
711
}
712

    
713
/*
714
 * Determine which stack to use..
715
 */
716

    
717
static inline abi_ulong
718
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
719
{
720
        unsigned long esp;
721

    
722
        /* Default to using normal stack */
723
        esp = env->regs[R_ESP];
724
        /* This is the X/Open sanctioned signal stack switching.  */
725
        if (ka->sa_flags & TARGET_SA_ONSTACK) {
726
            if (sas_ss_flags(esp) == 0)
727
                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
728
        }
729

    
730
        /* This is the legacy signal stack switching. */
731
        else
732
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
733
            !(ka->sa_flags & TARGET_SA_RESTORER) &&
734
            ka->sa_restorer) {
735
            esp = (unsigned long) ka->sa_restorer;
736
        }
737
        return (esp - frame_size) & -8ul;
738
}
739

    
740
/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
741
static void setup_frame(int sig, struct target_sigaction *ka,
742
                        target_sigset_t *set, CPUX86State *env)
743
{
744
        abi_ulong frame_addr;
745
        struct sigframe *frame;
746
        int i, err = 0;
747

    
748
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
749

    
750
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
751
                goto give_sigsegv;
752

    
753
        err |= __put_user(current_exec_domain_sig(sig),
754
                          &frame->sig);
755
        if (err)
756
                goto give_sigsegv;
757

    
758
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
759
                         frame_addr + offsetof(struct sigframe, fpstate));
760
        if (err)
761
                goto give_sigsegv;
762

    
763
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
764
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
765
                goto give_sigsegv;
766
        }
767

    
768
        /* Set up to return from userspace.  If provided, use a stub
769
           already in userspace.  */
770
        if (ka->sa_flags & TARGET_SA_RESTORER) {
771
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
772
        } else {
773
                uint16_t val16;
774
                abi_ulong retcode_addr;
775
                retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
776
                err |= __put_user(retcode_addr, &frame->pretcode);
777
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
778
                val16 = 0xb858;
779
                err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
780
                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
781
                val16 = 0x80cd;
782
                err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
783
        }
784

    
785
        if (err)
786
                goto give_sigsegv;
787

    
788
        /* Set up registers for signal handler */
789
        env->regs[R_ESP] = frame_addr;
790
        env->eip = ka->_sa_handler;
791

    
792
        cpu_x86_load_seg(env, R_DS, __USER_DS);
793
        cpu_x86_load_seg(env, R_ES, __USER_DS);
794
        cpu_x86_load_seg(env, R_SS, __USER_DS);
795
        cpu_x86_load_seg(env, R_CS, __USER_CS);
796
        env->eflags &= ~TF_MASK;
797

    
798
        unlock_user_struct(frame, frame_addr, 1);
799

    
800
        return;
801

    
802
give_sigsegv:
803
        unlock_user_struct(frame, frame_addr, 1);
804
        if (sig == TARGET_SIGSEGV)
805
                ka->_sa_handler = TARGET_SIG_DFL;
806
        force_sig(TARGET_SIGSEGV /* , current */);
807
}
808

    
809
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
810
static void setup_rt_frame(int sig, struct target_sigaction *ka,
811
                           target_siginfo_t *info,
812
                           target_sigset_t *set, CPUX86State *env)
813
{
814
        abi_ulong frame_addr, addr;
815
        struct rt_sigframe *frame;
816
        int i, err = 0;
817

    
818
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
819

    
820
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
821
                goto give_sigsegv;
822

    
823
        err |= __put_user(current_exec_domain_sig(sig),
824
                          &frame->sig);
825
        addr = frame_addr + offsetof(struct rt_sigframe, info);
826
        err |= __put_user(addr, &frame->pinfo);
827
        addr = frame_addr + offsetof(struct rt_sigframe, uc);
828
        err |= __put_user(addr, &frame->puc);
829
        err |= copy_siginfo_to_user(&frame->info, info);
830
        if (err)
831
                goto give_sigsegv;
832

    
833
        /* Create the ucontext.  */
834
        err |= __put_user(0, &frame->uc.tuc_flags);
835
        err |= __put_user(0, &frame->uc.tuc_link);
836
        err |= __put_user(target_sigaltstack_used.ss_sp,
837
                          &frame->uc.tuc_stack.ss_sp);
838
        err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
839
                          &frame->uc.tuc_stack.ss_flags);
840
        err |= __put_user(target_sigaltstack_used.ss_size,
841
                          &frame->uc.tuc_stack.ss_size);
842
        err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
843
                                env, set->sig[0], 
844
                                frame_addr + offsetof(struct rt_sigframe, fpstate));
845
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
846
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
847
                goto give_sigsegv;
848
        }
849

    
850
        /* Set up to return from userspace.  If provided, use a stub
851
           already in userspace.  */
852
        if (ka->sa_flags & TARGET_SA_RESTORER) {
853
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
854
        } else {
855
                uint16_t val16;
856
                addr = frame_addr + offsetof(struct rt_sigframe, retcode);
857
                err |= __put_user(addr, &frame->pretcode);
858
                /* This is movl $,%eax ; int $0x80 */
859
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
860
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
861
                val16 = 0x80cd;
862
                err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
863
        }
864

    
865
        if (err)
866
                goto give_sigsegv;
867

    
868
        /* Set up registers for signal handler */
869
        env->regs[R_ESP] = frame_addr;
870
        env->eip = ka->_sa_handler;
871

    
872
        cpu_x86_load_seg(env, R_DS, __USER_DS);
873
        cpu_x86_load_seg(env, R_ES, __USER_DS);
874
        cpu_x86_load_seg(env, R_SS, __USER_DS);
875
        cpu_x86_load_seg(env, R_CS, __USER_CS);
876
        env->eflags &= ~TF_MASK;
877

    
878
        unlock_user_struct(frame, frame_addr, 1);
879

    
880
        return;
881

    
882
give_sigsegv:
883
        unlock_user_struct(frame, frame_addr, 1);
884
        if (sig == TARGET_SIGSEGV)
885
                ka->_sa_handler = TARGET_SIG_DFL;
886
        force_sig(TARGET_SIGSEGV /* , current */);
887
}
888

    
889
static int
890
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
891
{
892
        unsigned int err = 0;
893
        abi_ulong fpstate_addr;
894
        unsigned int tmpflags;
895

    
896
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
897
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
898
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
899
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
900

    
901
        env->regs[R_EDI] = tswapl(sc->edi);
902
        env->regs[R_ESI] = tswapl(sc->esi);
903
        env->regs[R_EBP] = tswapl(sc->ebp);
904
        env->regs[R_ESP] = tswapl(sc->esp);
905
        env->regs[R_EBX] = tswapl(sc->ebx);
906
        env->regs[R_EDX] = tswapl(sc->edx);
907
        env->regs[R_ECX] = tswapl(sc->ecx);
908
        env->eip = tswapl(sc->eip);
909

    
910
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
911
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
912

    
913
        tmpflags = tswapl(sc->eflags);
914
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
915
        //                regs->orig_eax = -1;                /* disable syscall checks */
916

    
917
        fpstate_addr = tswapl(sc->fpstate);
918
        if (fpstate_addr != 0) {
919
                if (!access_ok(VERIFY_READ, fpstate_addr, 
920
                               sizeof(struct target_fpstate)))
921
                        goto badframe;
922
                cpu_x86_frstor(env, fpstate_addr, 1);
923
        }
924

    
925
        *peax = tswapl(sc->eax);
926
        return err;
927
badframe:
928
        return 1;
929
}
930

    
931
long do_sigreturn(CPUX86State *env)
932
{
933
    struct sigframe *frame;
934
    abi_ulong frame_addr = env->regs[R_ESP] - 8;
935
    target_sigset_t target_set;
936
    sigset_t set;
937
    int eax, i;
938

    
939
#if defined(DEBUG_SIGNAL)
940
    fprintf(stderr, "do_sigreturn\n");
941
#endif
942
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
943
        goto badframe;
944
    /* set blocked signals */
945
    if (__get_user(target_set.sig[0], &frame->sc.oldmask))
946
        goto badframe;
947
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
948
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
949
            goto badframe;
950
    }
951

    
952
    target_to_host_sigset_internal(&set, &target_set);
953
    sigprocmask(SIG_SETMASK, &set, NULL);
954

    
955
    /* restore registers */
956
    if (restore_sigcontext(env, &frame->sc, &eax))
957
        goto badframe;
958
    unlock_user_struct(frame, frame_addr, 0);
959
    return eax;
960

    
961
badframe:
962
    unlock_user_struct(frame, frame_addr, 0);
963
    force_sig(TARGET_SIGSEGV);
964
    return 0;
965
}
966

    
967
long do_rt_sigreturn(CPUX86State *env)
968
{
969
        abi_ulong frame_addr;
970
        struct rt_sigframe *frame;
971
        sigset_t set;
972
        int eax;
973

    
974
        frame_addr = env->regs[R_ESP] - 4;
975
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
976
                goto badframe;
977
        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
978
        sigprocmask(SIG_SETMASK, &set, NULL);
979

    
980
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
981
                goto badframe;
982

    
983
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
984
                           get_sp_from_cpustate(env)) == -EFAULT)
985
                goto badframe;
986

    
987
        unlock_user_struct(frame, frame_addr, 0);
988
        return eax;
989

    
990
badframe:
991
        unlock_user_struct(frame, frame_addr, 0);
992
        force_sig(TARGET_SIGSEGV);
993
        return 0;
994
}
995

    
996
#elif defined(TARGET_ARM)
997

    
998
struct target_sigcontext {
999
        abi_ulong trap_no;
1000
        abi_ulong error_code;
1001
        abi_ulong oldmask;
1002
        abi_ulong arm_r0;
1003
        abi_ulong arm_r1;
1004
        abi_ulong arm_r2;
1005
        abi_ulong arm_r3;
1006
        abi_ulong arm_r4;
1007
        abi_ulong arm_r5;
1008
        abi_ulong arm_r6;
1009
        abi_ulong arm_r7;
1010
        abi_ulong arm_r8;
1011
        abi_ulong arm_r9;
1012
        abi_ulong arm_r10;
1013
        abi_ulong arm_fp;
1014
        abi_ulong arm_ip;
1015
        abi_ulong arm_sp;
1016
        abi_ulong arm_lr;
1017
        abi_ulong arm_pc;
1018
        abi_ulong arm_cpsr;
1019
        abi_ulong fault_address;
1020
};
1021

    
1022
struct target_ucontext_v1 {
1023
    abi_ulong tuc_flags;
1024
    abi_ulong tuc_link;
1025
    target_stack_t tuc_stack;
1026
    struct target_sigcontext tuc_mcontext;
1027
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1028
};
1029

    
1030
struct target_ucontext_v2 {
1031
    abi_ulong tuc_flags;
1032
    abi_ulong tuc_link;
1033
    target_stack_t tuc_stack;
1034
    struct target_sigcontext tuc_mcontext;
1035
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1036
    char __unused[128 - sizeof(sigset_t)];
1037
    abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1038
};
1039

    
1040
struct sigframe_v1
1041
{
1042
    struct target_sigcontext sc;
1043
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
1044
    abi_ulong retcode;
1045
};
1046

    
1047
struct sigframe_v2
1048
{
1049
    struct target_ucontext_v2 uc;
1050
    abi_ulong retcode;
1051
};
1052

    
1053
struct rt_sigframe_v1
1054
{
1055
    abi_ulong pinfo;
1056
    abi_ulong puc;
1057
    struct target_siginfo info;
1058
    struct target_ucontext_v1 uc;
1059
    abi_ulong retcode;
1060
};
1061

    
1062
struct rt_sigframe_v2
1063
{
1064
    struct target_siginfo info;
1065
    struct target_ucontext_v2 uc;
1066
    abi_ulong retcode;
1067
};
1068

    
1069
#define TARGET_CONFIG_CPU_32 1
1070

    
1071
/*
1072
 * For ARM syscalls, we encode the syscall number into the instruction.
1073
 */
1074
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1075
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1076

    
1077
/*
1078
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
1079
 * need two 16-bit instructions.
1080
 */
1081
#define SWI_THUMB_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1082
#define SWI_THUMB_RT_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1083

    
1084
static const abi_ulong retcodes[4] = {
1085
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
1086
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
1087
};
1088

    
1089

    
1090
#define __get_user_error(x,p,e) __get_user(x, p)
1091

    
1092
static inline int valid_user_regs(CPUState *regs)
1093
{
1094
    return 1;
1095
}
1096

    
1097
static void
1098
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1099
                 CPUState *env, abi_ulong mask)
1100
{
1101
        __put_user(env->regs[0], &sc->arm_r0);
1102
        __put_user(env->regs[1], &sc->arm_r1);
1103
        __put_user(env->regs[2], &sc->arm_r2);
1104
        __put_user(env->regs[3], &sc->arm_r3);
1105
        __put_user(env->regs[4], &sc->arm_r4);
1106
        __put_user(env->regs[5], &sc->arm_r5);
1107
        __put_user(env->regs[6], &sc->arm_r6);
1108
        __put_user(env->regs[7], &sc->arm_r7);
1109
        __put_user(env->regs[8], &sc->arm_r8);
1110
        __put_user(env->regs[9], &sc->arm_r9);
1111
        __put_user(env->regs[10], &sc->arm_r10);
1112
        __put_user(env->regs[11], &sc->arm_fp);
1113
        __put_user(env->regs[12], &sc->arm_ip);
1114
        __put_user(env->regs[13], &sc->arm_sp);
1115
        __put_user(env->regs[14], &sc->arm_lr);
1116
        __put_user(env->regs[15], &sc->arm_pc);
1117
#ifdef TARGET_CONFIG_CPU_32
1118
        __put_user(cpsr_read(env), &sc->arm_cpsr);
1119
#endif
1120

    
1121
        __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1122
        __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1123
        __put_user(/* current->thread.address */ 0, &sc->fault_address);
1124
        __put_user(mask, &sc->oldmask);
1125
}
1126

    
1127
static inline abi_ulong
1128
get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1129
{
1130
        unsigned long sp = regs->regs[13];
1131

    
1132
        /*
1133
         * This is the X/Open sanctioned signal stack switching.
1134
         */
1135
        if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1136
            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1137
        /*
1138
         * ATPCS B01 mandates 8-byte alignment
1139
         */
1140
        return (sp - framesize) & ~7;
1141
}
1142

    
1143
static int
1144
setup_return(CPUState *env, struct target_sigaction *ka,
1145
             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1146
{
1147
        abi_ulong handler = ka->_sa_handler;
1148
        abi_ulong retcode;
1149
        int thumb = handler & 1;
1150

    
1151
        if (ka->sa_flags & TARGET_SA_RESTORER) {
1152
                retcode = ka->sa_restorer;
1153
        } else {
1154
                unsigned int idx = thumb;
1155

    
1156
                if (ka->sa_flags & TARGET_SA_SIGINFO)
1157
                        idx += 2;
1158

    
1159
                if (__put_user(retcodes[idx], rc))
1160
                        return 1;
1161
#if 0
1162
                flush_icache_range((abi_ulong)rc,
1163
                                   (abi_ulong)(rc + 1));
1164
#endif
1165
                retcode = rc_addr + thumb;
1166
        }
1167

    
1168
        env->regs[0] = usig;
1169
        env->regs[13] = frame_addr;
1170
        env->regs[14] = retcode;
1171
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1172
        env->thumb = thumb;
1173

    
1174
#if 0
1175
#ifdef TARGET_CONFIG_CPU_32
1176
        env->cpsr = cpsr;
1177
#endif
1178
#endif
1179

    
1180
        return 0;
1181
}
1182

    
1183
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1184
                              target_sigset_t *set, CPUState *env)
1185
{
1186
    struct target_sigaltstack stack;
1187
    int i;
1188

    
1189
    /* Clear all the bits of the ucontext we don't use.  */
1190
    memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1191

    
1192
    memset(&stack, 0, sizeof(stack));
1193
    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1194
    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1195
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1196
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1197

    
1198
    setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1199
    /* FIXME: Save coprocessor signal frame.  */
1200
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1201
        __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1202
    }
1203
}
1204

    
1205
/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1206
static void setup_frame_v1(int usig, struct target_sigaction *ka,
1207
                           target_sigset_t *set, CPUState *regs)
1208
{
1209
        struct sigframe_v1 *frame;
1210
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1211
        int i;
1212

    
1213
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1214
                return;
1215

    
1216
        setup_sigcontext(&frame->sc, regs, set->sig[0]);
1217

    
1218
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1219
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1220
                goto end;
1221
        }
1222

    
1223
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1224
                     frame_addr + offsetof(struct sigframe_v1, retcode));
1225

    
1226
end:
1227
        unlock_user_struct(frame, frame_addr, 1);
1228
}
1229

    
1230
static void setup_frame_v2(int usig, struct target_sigaction *ka,
1231
                           target_sigset_t *set, CPUState *regs)
1232
{
1233
        struct sigframe_v2 *frame;
1234
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1235

    
1236
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1237
                return;
1238

    
1239
        setup_sigframe_v2(&frame->uc, set, regs);
1240

    
1241
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1242
                     frame_addr + offsetof(struct sigframe_v2, retcode));
1243

    
1244
        unlock_user_struct(frame, frame_addr, 1);
1245
}
1246

    
1247
static void setup_frame(int usig, struct target_sigaction *ka,
1248
                        target_sigset_t *set, CPUState *regs)
1249
{
1250
    if (get_osversion() >= 0x020612) {
1251
        setup_frame_v2(usig, ka, set, regs);
1252
    } else {
1253
        setup_frame_v1(usig, ka, set, regs);
1254
    }
1255
}
1256

    
1257
/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1258
static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1259
                              target_siginfo_t *info,
1260
                              target_sigset_t *set, CPUState *env)
1261
{
1262
        struct rt_sigframe_v1 *frame;
1263
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1264
        struct target_sigaltstack stack;
1265
        int i;
1266
        abi_ulong info_addr, uc_addr;
1267

    
1268
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1269
            return /* 1 */;
1270

    
1271
        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1272
        __put_user(info_addr, &frame->pinfo);
1273
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1274
        __put_user(uc_addr, &frame->puc);
1275
        copy_siginfo_to_user(&frame->info, info);
1276

    
1277
        /* Clear all the bits of the ucontext we don't use.  */
1278
        memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1279

    
1280
        memset(&stack, 0, sizeof(stack));
1281
        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1282
        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1283
        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1284
        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1285

    
1286
        setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1287
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1288
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1289
                goto end;
1290
        }
1291

    
1292
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1293
                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1294

    
1295
        env->regs[1] = info_addr;
1296
        env->regs[2] = uc_addr;
1297

    
1298
end:
1299
        unlock_user_struct(frame, frame_addr, 1);
1300
}
1301

    
1302
static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1303
                              target_siginfo_t *info,
1304
                              target_sigset_t *set, CPUState *env)
1305
{
1306
        struct rt_sigframe_v2 *frame;
1307
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1308
        abi_ulong info_addr, uc_addr;
1309

    
1310
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1311
            return /* 1 */;
1312

    
1313
        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1314
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1315
        copy_siginfo_to_user(&frame->info, info);
1316

    
1317
        setup_sigframe_v2(&frame->uc, set, env);
1318

    
1319
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1320
                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1321

    
1322
        env->regs[1] = info_addr;
1323
        env->regs[2] = uc_addr;
1324

    
1325
        unlock_user_struct(frame, frame_addr, 1);
1326
}
1327

    
1328
static void setup_rt_frame(int usig, struct target_sigaction *ka,
1329
                           target_siginfo_t *info,
1330
                           target_sigset_t *set, CPUState *env)
1331
{
1332
    if (get_osversion() >= 0x020612) {
1333
        setup_rt_frame_v2(usig, ka, info, set, env);
1334
    } else {
1335
        setup_rt_frame_v1(usig, ka, info, set, env);
1336
    }
1337
}
1338

    
1339
static int
1340
restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1341
{
1342
        int err = 0;
1343
        uint32_t cpsr;
1344

    
1345
        __get_user_error(env->regs[0], &sc->arm_r0, err);
1346
        __get_user_error(env->regs[1], &sc->arm_r1, err);
1347
        __get_user_error(env->regs[2], &sc->arm_r2, err);
1348
        __get_user_error(env->regs[3], &sc->arm_r3, err);
1349
        __get_user_error(env->regs[4], &sc->arm_r4, err);
1350
        __get_user_error(env->regs[5], &sc->arm_r5, err);
1351
        __get_user_error(env->regs[6], &sc->arm_r6, err);
1352
        __get_user_error(env->regs[7], &sc->arm_r7, err);
1353
        __get_user_error(env->regs[8], &sc->arm_r8, err);
1354
        __get_user_error(env->regs[9], &sc->arm_r9, err);
1355
        __get_user_error(env->regs[10], &sc->arm_r10, err);
1356
        __get_user_error(env->regs[11], &sc->arm_fp, err);
1357
        __get_user_error(env->regs[12], &sc->arm_ip, err);
1358
        __get_user_error(env->regs[13], &sc->arm_sp, err);
1359
        __get_user_error(env->regs[14], &sc->arm_lr, err);
1360
        __get_user_error(env->regs[15], &sc->arm_pc, err);
1361
#ifdef TARGET_CONFIG_CPU_32
1362
        __get_user_error(cpsr, &sc->arm_cpsr, err);
1363
        cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1364
#endif
1365

    
1366
        err |= !valid_user_regs(env);
1367

    
1368
        return err;
1369
}
1370

    
1371
long do_sigreturn_v1(CPUState *env)
1372
{
1373
        abi_ulong frame_addr;
1374
        struct sigframe_v1 *frame;
1375
        target_sigset_t set;
1376
        sigset_t host_set;
1377
        int i;
1378

    
1379
        /*
1380
         * Since we stacked the signal on a 64-bit boundary,
1381
         * then 'sp' should be word aligned here.  If it's
1382
         * not, then the user is trying to mess with us.
1383
         */
1384
        if (env->regs[13] & 7)
1385
                goto badframe;
1386

    
1387
        frame_addr = env->regs[13];
1388
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1389
                goto badframe;
1390

    
1391
        if (__get_user(set.sig[0], &frame->sc.oldmask))
1392
            goto badframe;
1393
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1394
            if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1395
                goto badframe;
1396
        }
1397

    
1398
        target_to_host_sigset_internal(&host_set, &set);
1399
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1400

    
1401
        if (restore_sigcontext(env, &frame->sc))
1402
                goto badframe;
1403

    
1404
#if 0
1405
        /* Send SIGTRAP if we're single-stepping */
1406
        if (ptrace_cancel_bpt(current))
1407
                send_sig(SIGTRAP, current, 1);
1408
#endif
1409
        unlock_user_struct(frame, frame_addr, 0);
1410
        return env->regs[0];
1411

    
1412
badframe:
1413
        unlock_user_struct(frame, frame_addr, 0);
1414
        force_sig(SIGSEGV /* , current */);
1415
        return 0;
1416
}
1417

    
1418
static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1419
                                 struct target_ucontext_v2 *uc)
1420
{
1421
    sigset_t host_set;
1422

    
1423
    target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1424
    sigprocmask(SIG_SETMASK, &host_set, NULL);
1425

    
1426
    if (restore_sigcontext(env, &uc->tuc_mcontext))
1427
        return 1;
1428

    
1429
    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1430
        return 1;
1431

    
1432
#if 0
1433
    /* Send SIGTRAP if we're single-stepping */
1434
    if (ptrace_cancel_bpt(current))
1435
            send_sig(SIGTRAP, current, 1);
1436
#endif
1437

    
1438
    return 0;
1439
}
1440

    
1441
long do_sigreturn_v2(CPUState *env)
1442
{
1443
        abi_ulong frame_addr;
1444
        struct sigframe_v2 *frame;
1445

    
1446
        /*
1447
         * Since we stacked the signal on a 64-bit boundary,
1448
         * then 'sp' should be word aligned here.  If it's
1449
         * not, then the user is trying to mess with us.
1450
         */
1451
        if (env->regs[13] & 7)
1452
                goto badframe;
1453

    
1454
        frame_addr = env->regs[13];
1455
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1456
                goto badframe;
1457

    
1458
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1459
                goto badframe;
1460

    
1461
        unlock_user_struct(frame, frame_addr, 0);
1462
        return env->regs[0];
1463

    
1464
badframe:
1465
        unlock_user_struct(frame, frame_addr, 0);
1466
        force_sig(SIGSEGV /* , current */);
1467
        return 0;
1468
}
1469

    
1470
long do_sigreturn(CPUState *env)
1471
{
1472
    if (get_osversion() >= 0x020612) {
1473
        return do_sigreturn_v2(env);
1474
    } else {
1475
        return do_sigreturn_v1(env);
1476
    }
1477
}
1478

    
1479
long do_rt_sigreturn_v1(CPUState *env)
1480
{
1481
        abi_ulong frame_addr;
1482
        struct rt_sigframe_v1 *frame;
1483
        sigset_t host_set;
1484

    
1485
        /*
1486
         * Since we stacked the signal on a 64-bit boundary,
1487
         * then 'sp' should be word aligned here.  If it's
1488
         * not, then the user is trying to mess with us.
1489
         */
1490
        if (env->regs[13] & 7)
1491
                goto badframe;
1492

    
1493
        frame_addr = env->regs[13];
1494
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1495
                goto badframe;
1496

    
1497
        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1498
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1499

    
1500
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1501
                goto badframe;
1502

    
1503
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1504
                goto badframe;
1505

    
1506
#if 0
1507
        /* Send SIGTRAP if we're single-stepping */
1508
        if (ptrace_cancel_bpt(current))
1509
                send_sig(SIGTRAP, current, 1);
1510
#endif
1511
        unlock_user_struct(frame, frame_addr, 0);
1512
        return env->regs[0];
1513

    
1514
badframe:
1515
        unlock_user_struct(frame, frame_addr, 0);
1516
        force_sig(SIGSEGV /* , current */);
1517
        return 0;
1518
}
1519

    
1520
long do_rt_sigreturn_v2(CPUState *env)
1521
{
1522
        abi_ulong frame_addr;
1523
        struct rt_sigframe_v2 *frame;
1524

    
1525
        /*
1526
         * Since we stacked the signal on a 64-bit boundary,
1527
         * then 'sp' should be word aligned here.  If it's
1528
         * not, then the user is trying to mess with us.
1529
         */
1530
        if (env->regs[13] & 7)
1531
                goto badframe;
1532

    
1533
        frame_addr = env->regs[13];
1534
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1535
                goto badframe;
1536

    
1537
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1538
                goto badframe;
1539

    
1540
        unlock_user_struct(frame, frame_addr, 0);
1541
        return env->regs[0];
1542

    
1543
badframe:
1544
        unlock_user_struct(frame, frame_addr, 0);
1545
        force_sig(SIGSEGV /* , current */);
1546
        return 0;
1547
}
1548

    
1549
long do_rt_sigreturn(CPUState *env)
1550
{
1551
    if (get_osversion() >= 0x020612) {
1552
        return do_rt_sigreturn_v2(env);
1553
    } else {
1554
        return do_rt_sigreturn_v1(env);
1555
    }
1556
}
1557

    
1558
#elif defined(TARGET_SPARC)
1559

    
1560
#define __SUNOS_MAXWIN   31
1561

    
1562
/* This is what SunOS does, so shall I. */
1563
struct target_sigcontext {
1564
        abi_ulong sigc_onstack;      /* state to restore */
1565

    
1566
        abi_ulong sigc_mask;         /* sigmask to restore */
1567
        abi_ulong sigc_sp;           /* stack pointer */
1568
        abi_ulong sigc_pc;           /* program counter */
1569
        abi_ulong sigc_npc;          /* next program counter */
1570
        abi_ulong sigc_psr;          /* for condition codes etc */
1571
        abi_ulong sigc_g1;           /* User uses these two registers */
1572
        abi_ulong sigc_o0;           /* within the trampoline code. */
1573

    
1574
        /* Now comes information regarding the users window set
1575
         * at the time of the signal.
1576
         */
1577
        abi_ulong sigc_oswins;       /* outstanding windows */
1578

    
1579
        /* stack ptrs for each regwin buf */
1580
        char *sigc_spbuf[__SUNOS_MAXWIN];
1581

    
1582
        /* Windows to restore after signal */
1583
        struct {
1584
                abi_ulong locals[8];
1585
                abi_ulong ins[8];
1586
        } sigc_wbuf[__SUNOS_MAXWIN];
1587
};
1588
/* A Sparc stack frame */
1589
struct sparc_stackf {
1590
        abi_ulong locals[8];
1591
        abi_ulong ins[6];
1592
        struct sparc_stackf *fp;
1593
        abi_ulong callers_pc;
1594
        char *structptr;
1595
        abi_ulong xargs[6];
1596
        abi_ulong xxargs[1];
1597
};
1598

    
1599
typedef struct {
1600
        struct {
1601
                abi_ulong psr;
1602
                abi_ulong pc;
1603
                abi_ulong npc;
1604
                abi_ulong y;
1605
                abi_ulong u_regs[16]; /* globals and ins */
1606
        }               si_regs;
1607
        int             si_mask;
1608
} __siginfo_t;
1609

    
1610
typedef struct {
1611
        unsigned   long si_float_regs [32];
1612
        unsigned   long si_fsr;
1613
        unsigned   long si_fpqdepth;
1614
        struct {
1615
                unsigned long *insn_addr;
1616
                unsigned long insn;
1617
        } si_fpqueue [16];
1618
} qemu_siginfo_fpu_t;
1619

    
1620

    
1621
struct target_signal_frame {
1622
        struct sparc_stackf        ss;
1623
        __siginfo_t                info;
1624
        abi_ulong               fpu_save;
1625
        abi_ulong                insns[2] __attribute__ ((aligned (8)));
1626
        abi_ulong                extramask[TARGET_NSIG_WORDS - 1];
1627
        abi_ulong                extra_size; /* Should be 0 */
1628
        qemu_siginfo_fpu_t        fpu_state;
1629
};
1630
struct target_rt_signal_frame {
1631
        struct sparc_stackf        ss;
1632
        siginfo_t                info;
1633
        abi_ulong                regs[20];
1634
        sigset_t                mask;
1635
        abi_ulong               fpu_save;
1636
        unsigned int                insns[2];
1637
        stack_t                        stack;
1638
        unsigned int                extra_size; /* Should be 0 */
1639
        qemu_siginfo_fpu_t        fpu_state;
1640
};
1641

    
1642
#define UREG_O0        16
1643
#define UREG_O6        22
1644
#define UREG_I0        0
1645
#define UREG_I1        1
1646
#define UREG_I2        2
1647
#define UREG_I3        3
1648
#define UREG_I4        4
1649
#define UREG_I5        5
1650
#define UREG_I6        6
1651
#define UREG_I7        7
1652
#define UREG_L0               8
1653
#define UREG_FP        UREG_I6
1654
#define UREG_SP        UREG_O6
1655

    
1656
static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
1657
                                     CPUState *env, unsigned long framesize)
1658
{
1659
        abi_ulong sp;
1660

    
1661
        sp = env->regwptr[UREG_FP];
1662

    
1663
        /* This is the X/Open sanctioned signal stack switching.  */
1664
        if (sa->sa_flags & TARGET_SA_ONSTACK) {
1665
            if (!on_sig_stack(sp)
1666
                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1667
                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1668
        }
1669
        return sp - framesize;
1670
}
1671

    
1672
static int
1673
setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1674
{
1675
        int err = 0, i;
1676

    
1677
        err |= __put_user(env->psr, &si->si_regs.psr);
1678
        err |= __put_user(env->pc, &si->si_regs.pc);
1679
        err |= __put_user(env->npc, &si->si_regs.npc);
1680
        err |= __put_user(env->y, &si->si_regs.y);
1681
        for (i=0; i < 8; i++) {
1682
                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1683
        }
1684
        for (i=0; i < 8; i++) {
1685
                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1686
        }
1687
        err |= __put_user(mask, &si->si_mask);
1688
        return err;
1689
}
1690

    
1691
#if 0
1692
static int
1693
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1694
                 CPUState *env, unsigned long mask)
1695
{
1696
        int err = 0;
1697

1698
        err |= __put_user(mask, &sc->sigc_mask);
1699
        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1700
        err |= __put_user(env->pc, &sc->sigc_pc);
1701
        err |= __put_user(env->npc, &sc->sigc_npc);
1702
        err |= __put_user(env->psr, &sc->sigc_psr);
1703
        err |= __put_user(env->gregs[1], &sc->sigc_g1);
1704
        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1705

1706
        return err;
1707
}
1708
#endif
1709
#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1710

    
1711
static void setup_frame(int sig, struct target_sigaction *ka,
1712
                        target_sigset_t *set, CPUState *env)
1713
{
1714
        abi_ulong sf_addr;
1715
        struct target_signal_frame *sf;
1716
        int sigframe_size, err, i;
1717

    
1718
        /* 1. Make sure everything is clean */
1719
        //synchronize_user_stack();
1720

    
1721
        sigframe_size = NF_ALIGNEDSZ;
1722
        sf_addr = get_sigframe(ka, env, sigframe_size);
1723

    
1724
        sf = lock_user(VERIFY_WRITE, sf_addr, 
1725
                       sizeof(struct target_signal_frame), 0);
1726
        if (!sf)
1727
                goto sigsegv;
1728
                
1729
        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1730
#if 0
1731
        if (invalid_frame_pointer(sf, sigframe_size))
1732
                goto sigill_and_return;
1733
#endif
1734
        /* 2. Save the current process state */
1735
        err = setup___siginfo(&sf->info, env, set->sig[0]);
1736
        err |= __put_user(0, &sf->extra_size);
1737

    
1738
        //err |= save_fpu_state(regs, &sf->fpu_state);
1739
        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1740

    
1741
        err |= __put_user(set->sig[0], &sf->info.si_mask);
1742
        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1743
                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1744
        }
1745

    
1746
        for (i = 0; i < 8; i++) {
1747
                  err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1748
        }
1749
        for (i = 0; i < 8; i++) {
1750
                  err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1751
        }
1752
        if (err)
1753
                goto sigsegv;
1754

    
1755
        /* 3. signal handler back-trampoline and parameters */
1756
        env->regwptr[UREG_FP] = sf_addr;
1757
        env->regwptr[UREG_I0] = sig;
1758
        env->regwptr[UREG_I1] = sf_addr + 
1759
                offsetof(struct target_signal_frame, info);
1760
        env->regwptr[UREG_I2] = sf_addr + 
1761
                offsetof(struct target_signal_frame, info);
1762

    
1763
        /* 4. signal handler */
1764
        env->pc = ka->_sa_handler;
1765
        env->npc = (env->pc + 4);
1766
        /* 5. return to kernel instructions */
1767
        if (ka->sa_restorer)
1768
                env->regwptr[UREG_I7] = ka->sa_restorer;
1769
        else {
1770
                uint32_t val32;
1771

    
1772
                env->regwptr[UREG_I7] = sf_addr + 
1773
                        offsetof(struct target_signal_frame, insns) - 2 * 4;
1774

    
1775
                /* mov __NR_sigreturn, %g1 */
1776
                val32 = 0x821020d8;
1777
                err |= __put_user(val32, &sf->insns[0]);
1778

    
1779
                /* t 0x10 */
1780
                val32 = 0x91d02010;
1781
                err |= __put_user(val32, &sf->insns[1]);
1782
                if (err)
1783
                        goto sigsegv;
1784

    
1785
                /* Flush instruction space. */
1786
                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1787
                //                tb_flush(env);
1788
        }
1789
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1790
        return;
1791
#if 0
1792
sigill_and_return:
1793
        force_sig(TARGET_SIGILL);
1794
#endif
1795
sigsegv:
1796
        //fprintf(stderr, "force_sig\n");
1797
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1798
        force_sig(TARGET_SIGSEGV);
1799
}
1800
static inline int
1801
restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1802
{
1803
        int err;
1804
#if 0
1805
#ifdef CONFIG_SMP
1806
        if (current->flags & PF_USEDFPU)
1807
                regs->psr &= ~PSR_EF;
1808
#else
1809
        if (current == last_task_used_math) {
1810
                last_task_used_math = 0;
1811
                regs->psr &= ~PSR_EF;
1812
        }
1813
#endif
1814
        current->used_math = 1;
1815
        current->flags &= ~PF_USEDFPU;
1816
#endif
1817
#if 0
1818
        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1819
                return -EFAULT;
1820
#endif
1821

    
1822
#if 0
1823
        /* XXX: incorrect */
1824
        err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1825
                                     (sizeof(unsigned long) * 32));
1826
#endif
1827
        err |= __get_user(env->fsr, &fpu->si_fsr);
1828
#if 0
1829
        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1830
        if (current->thread.fpqdepth != 0)
1831
                err |= __copy_from_user(&current->thread.fpqueue[0],
1832
                                        &fpu->si_fpqueue[0],
1833
                                        ((sizeof(unsigned long) +
1834
                                        (sizeof(unsigned long *)))*16));
1835
#endif
1836
        return err;
1837
}
1838

    
1839

    
1840
static void setup_rt_frame(int sig, struct target_sigaction *ka,
1841
                           target_siginfo_t *info,
1842
                           target_sigset_t *set, CPUState *env)
1843
{
1844
    fprintf(stderr, "setup_rt_frame: not implemented\n");
1845
}
1846

    
1847
long do_sigreturn(CPUState *env)
1848
{
1849
        abi_ulong sf_addr;
1850
        struct target_signal_frame *sf;
1851
        uint32_t up_psr, pc, npc;
1852
        target_sigset_t set;
1853
        sigset_t host_set;
1854
        abi_ulong fpu_save_addr;
1855
        int err, i;
1856

    
1857
        sf_addr = env->regwptr[UREG_FP];
1858
        if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1859
                goto segv_and_exit;
1860
#if 0
1861
        fprintf(stderr, "sigreturn\n");
1862
        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1863
#endif
1864
        //cpu_dump_state(env, stderr, fprintf, 0);
1865

    
1866
        /* 1. Make sure we are not getting garbage from the user */
1867

    
1868
        if (sf_addr & 3)
1869
                goto segv_and_exit;
1870

    
1871
        err = __get_user(pc,  &sf->info.si_regs.pc);
1872
        err |= __get_user(npc, &sf->info.si_regs.npc);
1873

    
1874
        if ((pc | npc) & 3)
1875
                goto segv_and_exit;
1876

    
1877
        /* 2. Restore the state */
1878
        err |= __get_user(up_psr, &sf->info.si_regs.psr);
1879

    
1880
        /* User can only change condition codes and FPU enabling in %psr. */
1881
        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1882
                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1883

    
1884
        env->pc = pc;
1885
        env->npc = npc;
1886
        err |= __get_user(env->y, &sf->info.si_regs.y);
1887
        for (i=0; i < 8; i++) {
1888
                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1889
        }
1890
        for (i=0; i < 8; i++) {
1891
                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1892
        }
1893

    
1894
        err |= __get_user(fpu_save_addr, &sf->fpu_save);
1895

    
1896
        //if (fpu_save)
1897
        //        err |= restore_fpu_state(env, fpu_save);
1898

    
1899
        /* This is pretty much atomic, no amount locking would prevent
1900
         * the races which exist anyways.
1901
         */
1902
        err |= __get_user(set.sig[0], &sf->info.si_mask);
1903
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1904
            err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1905
        }
1906

    
1907
        target_to_host_sigset_internal(&host_set, &set);
1908
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1909

    
1910
        if (err)
1911
                goto segv_and_exit;
1912
        unlock_user_struct(sf, sf_addr, 0);
1913
        return env->regwptr[0];
1914

    
1915
segv_and_exit:
1916
        unlock_user_struct(sf, sf_addr, 0);
1917
        force_sig(TARGET_SIGSEGV);
1918
}
1919

    
1920
long do_rt_sigreturn(CPUState *env)
1921
{
1922
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1923
    return -TARGET_ENOSYS;
1924
}
1925

    
1926
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1927
#define MC_TSTATE 0
1928
#define MC_PC 1
1929
#define MC_NPC 2
1930
#define MC_Y 3
1931
#define MC_G1 4
1932
#define MC_G2 5
1933
#define MC_G3 6
1934
#define MC_G4 7
1935
#define MC_G5 8
1936
#define MC_G6 9
1937
#define MC_G7 10
1938
#define MC_O0 11
1939
#define MC_O1 12
1940
#define MC_O2 13
1941
#define MC_O3 14
1942
#define MC_O4 15
1943
#define MC_O5 16
1944
#define MC_O6 17
1945
#define MC_O7 18
1946
#define MC_NGREG 19
1947

    
1948
typedef abi_ulong target_mc_greg_t;
1949
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1950

    
1951
struct target_mc_fq {
1952
    abi_ulong *mcfq_addr;
1953
    uint32_t mcfq_insn;
1954
};
1955

    
1956
struct target_mc_fpu {
1957
    union {
1958
        uint32_t sregs[32];
1959
        uint64_t dregs[32];
1960
        //uint128_t qregs[16];
1961
    } mcfpu_fregs;
1962
    abi_ulong mcfpu_fsr;
1963
    abi_ulong mcfpu_fprs;
1964
    abi_ulong mcfpu_gsr;
1965
    struct target_mc_fq *mcfpu_fq;
1966
    unsigned char mcfpu_qcnt;
1967
    unsigned char mcfpu_qentsz;
1968
    unsigned char mcfpu_enab;
1969
};
1970
typedef struct target_mc_fpu target_mc_fpu_t;
1971

    
1972
typedef struct {
1973
    target_mc_gregset_t mc_gregs;
1974
    target_mc_greg_t mc_fp;
1975
    target_mc_greg_t mc_i7;
1976
    target_mc_fpu_t mc_fpregs;
1977
} target_mcontext_t;
1978

    
1979
struct target_ucontext {
1980
    struct target_ucontext *uc_link;
1981
    abi_ulong uc_flags;
1982
    target_sigset_t uc_sigmask;
1983
    target_mcontext_t uc_mcontext;
1984
};
1985

    
1986
/* A V9 register window */
1987
struct target_reg_window {
1988
    abi_ulong locals[8];
1989
    abi_ulong ins[8];
1990
};
1991

    
1992
#define TARGET_STACK_BIAS 2047
1993

    
1994
/* {set, get}context() needed for 64-bit SparcLinux userland. */
1995
void sparc64_set_context(CPUSPARCState *env)
1996
{
1997
    abi_ulong ucp_addr;
1998
    struct target_ucontext *ucp;
1999
    target_mc_gregset_t *grp;
2000
    abi_ulong pc, npc, tstate;
2001
    abi_ulong fp, i7, w_addr;
2002
    unsigned char fenab;
2003
    int err;
2004
    unsigned int i;
2005

    
2006
    ucp_addr = env->regwptr[UREG_I0];
2007
    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2008
        goto do_sigsegv;
2009
    grp  = &ucp->uc_mcontext.mc_gregs;
2010
    err  = __get_user(pc, &((*grp)[MC_PC]));
2011
    err |= __get_user(npc, &((*grp)[MC_NPC]));
2012
    if (err || ((pc | npc) & 3))
2013
        goto do_sigsegv;
2014
    if (env->regwptr[UREG_I1]) {
2015
        target_sigset_t target_set;
2016
        sigset_t set;
2017

    
2018
        if (TARGET_NSIG_WORDS == 1) {
2019
            if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2020
                goto do_sigsegv;
2021
        } else {
2022
            abi_ulong *src, *dst;
2023
            src = ucp->uc_sigmask.sig;
2024
            dst = target_set.sig;
2025
            for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2026
                 i++, dst++, src++)
2027
                err |= __get_user(*dst, src);
2028
            if (err)
2029
                goto do_sigsegv;
2030
        }
2031
        target_to_host_sigset_internal(&set, &target_set);
2032
        sigprocmask(SIG_SETMASK, &set, NULL);
2033
    }
2034
    env->pc = pc;
2035
    env->npc = npc;
2036
    err |= __get_user(env->y, &((*grp)[MC_Y]));
2037
    err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2038
    env->asi = (tstate >> 24) & 0xff;
2039
    PUT_CCR(env, tstate >> 32);
2040
    PUT_CWP64(env, tstate & 0x1f);
2041
    err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2042
    err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2043
    err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2044
    err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2045
    err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2046
    err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2047
    err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2048
    err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2049
    err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2050
    err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2051
    err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2052
    err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2053
    err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2054
    err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2055
    err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2056

    
2057
    err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2058
    err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2059

    
2060
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2061
    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2062
                 abi_ulong) != 0)
2063
        goto do_sigsegv;
2064
    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2065
                 abi_ulong) != 0)
2066
        goto do_sigsegv;
2067
    err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2068
    err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2069
    {
2070
        uint32_t *src, *dst;
2071
        src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2072
        dst = env->fpr;
2073
        /* XXX: check that the CPU storage is the same as user context */
2074
        for (i = 0; i < 64; i++, dst++, src++)
2075
            err |= __get_user(*dst, src);
2076
    }
2077
    err |= __get_user(env->fsr,
2078
                      &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2079
    err |= __get_user(env->gsr,
2080
                      &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2081
    if (err)
2082
        goto do_sigsegv;
2083
    unlock_user_struct(ucp, ucp_addr, 0);
2084
    return;
2085
 do_sigsegv:
2086
    unlock_user_struct(ucp, ucp_addr, 0);
2087
    force_sig(SIGSEGV);
2088
}
2089

    
2090
void sparc64_get_context(CPUSPARCState *env)
2091
{
2092
    abi_ulong ucp_addr;
2093
    struct target_ucontext *ucp;
2094
    target_mc_gregset_t *grp;
2095
    target_mcontext_t *mcp;
2096
    abi_ulong fp, i7, w_addr;
2097
    int err;
2098
    unsigned int i;
2099
    target_sigset_t target_set;
2100
    sigset_t set;
2101

    
2102
    ucp_addr = env->regwptr[UREG_I0];
2103
    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2104
        goto do_sigsegv;
2105
    
2106
    mcp = &ucp->uc_mcontext;
2107
    grp = &mcp->mc_gregs;
2108

    
2109
    /* Skip over the trap instruction, first. */
2110
    env->pc = env->npc;
2111
    env->npc += 4;
2112

    
2113
    err = 0;
2114

    
2115
    sigprocmask(0, NULL, &set);
2116
    host_to_target_sigset_internal(&target_set, &set);
2117
    if (TARGET_NSIG_WORDS == 1) {
2118
        err |= __put_user(target_set.sig[0],
2119
                          (abi_ulong *)&ucp->uc_sigmask);
2120
    } else {
2121
        abi_ulong *src, *dst;
2122
        src = target_set.sig;
2123
        dst = ucp->uc_sigmask.sig;
2124
        for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2125
             i++, dst++, src++)
2126
            err |= __put_user(*src, dst);
2127
        if (err)
2128
            goto do_sigsegv;
2129
    }
2130

    
2131
    /* XXX: tstate must be saved properly */
2132
    //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2133
    err |= __put_user(env->pc, &((*grp)[MC_PC]));
2134
    err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2135
    err |= __put_user(env->y, &((*grp)[MC_Y]));
2136
    err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2137
    err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2138
    err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2139
    err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2140
    err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2141
    err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2142
    err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2143
    err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2144
    err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2145
    err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2146
    err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2147
    err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2148
    err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2149
    err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2150
    err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2151

    
2152
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2153
    fp = i7 = 0;
2154
    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2155
                 abi_ulong) != 0)
2156
        goto do_sigsegv;
2157
    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2158
                 abi_ulong) != 0)
2159
        goto do_sigsegv;
2160
    err |= __put_user(fp, &(mcp->mc_fp));
2161
    err |= __put_user(i7, &(mcp->mc_i7));
2162

    
2163
    {
2164
        uint32_t *src, *dst;
2165
        src = env->fpr;
2166
        dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2167
        /* XXX: check that the CPU storage is the same as user context */
2168
        for (i = 0; i < 64; i++, dst++, src++)
2169
            err |= __put_user(*src, dst);
2170
    }
2171
    err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2172
    err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2173
    err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2174

    
2175
    if (err)
2176
        goto do_sigsegv;
2177
    unlock_user_struct(ucp, ucp_addr, 1);
2178
    return;
2179
 do_sigsegv:
2180
    unlock_user_struct(ucp, ucp_addr, 1);
2181
    force_sig(SIGSEGV);
2182
}
2183
#endif
2184
#elif defined(TARGET_ABI_MIPSN64)
2185

    
2186
# warning signal handling not implemented
2187

    
2188
static void setup_frame(int sig, struct target_sigaction *ka,
2189
                        target_sigset_t *set, CPUState *env)
2190
{
2191
    fprintf(stderr, "setup_frame: not implemented\n");
2192
}
2193

    
2194
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2195
                           target_siginfo_t *info,
2196
                           target_sigset_t *set, CPUState *env)
2197
{
2198
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2199
}
2200

    
2201
long do_sigreturn(CPUState *env)
2202
{
2203
    fprintf(stderr, "do_sigreturn: not implemented\n");
2204
    return -TARGET_ENOSYS;
2205
}
2206

    
2207
long do_rt_sigreturn(CPUState *env)
2208
{
2209
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2210
    return -TARGET_ENOSYS;
2211
}
2212

    
2213
#elif defined(TARGET_ABI_MIPSN32)
2214

    
2215
# warning signal handling not implemented
2216

    
2217
static void setup_frame(int sig, struct target_sigaction *ka,
2218
                        target_sigset_t *set, CPUState *env)
2219
{
2220
    fprintf(stderr, "setup_frame: not implemented\n");
2221
}
2222

    
2223
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2224
                           target_siginfo_t *info,
2225
                           target_sigset_t *set, CPUState *env)
2226
{
2227
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2228
}
2229

    
2230
long do_sigreturn(CPUState *env)
2231
{
2232
    fprintf(stderr, "do_sigreturn: not implemented\n");
2233
    return -TARGET_ENOSYS;
2234
}
2235

    
2236
long do_rt_sigreturn(CPUState *env)
2237
{
2238
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2239
    return -TARGET_ENOSYS;
2240
}
2241

    
2242
#elif defined(TARGET_ABI_MIPSO32)
2243

    
2244
struct target_sigcontext {
2245
    uint32_t   sc_regmask;     /* Unused */
2246
    uint32_t   sc_status;
2247
    uint64_t   sc_pc;
2248
    uint64_t   sc_regs[32];
2249
    uint64_t   sc_fpregs[32];
2250
    uint32_t   sc_ownedfp;     /* Unused */
2251
    uint32_t   sc_fpc_csr;
2252
    uint32_t   sc_fpc_eir;     /* Unused */
2253
    uint32_t   sc_used_math;
2254
    uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
2255
    uint64_t   sc_mdhi;
2256
    uint64_t   sc_mdlo;
2257
    target_ulong   sc_hi1;         /* Was sc_cause */
2258
    target_ulong   sc_lo1;         /* Was sc_badvaddr */
2259
    target_ulong   sc_hi2;         /* Was sc_sigset[4] */
2260
    target_ulong   sc_lo2;
2261
    target_ulong   sc_hi3;
2262
    target_ulong   sc_lo3;
2263
};
2264

    
2265
struct sigframe {
2266
    uint32_t sf_ass[4];                        /* argument save space for o32 */
2267
    uint32_t sf_code[2];                        /* signal trampoline */
2268
    struct target_sigcontext sf_sc;
2269
    target_sigset_t sf_mask;
2270
};
2271

    
2272
/* Install trampoline to jump back from signal handler */
2273
static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2274
{
2275
    int err;
2276

    
2277
    /*
2278
    * Set up the return code ...
2279
    *
2280
    *         li      v0, __NR__foo_sigreturn
2281
    *         syscall
2282
    */
2283

    
2284
    err = __put_user(0x24020000 + syscall, tramp + 0);
2285
    err |= __put_user(0x0000000c          , tramp + 1);
2286
    /* flush_cache_sigtramp((unsigned long) tramp); */
2287
    return err;
2288
}
2289

    
2290
static inline int
2291
setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2292
{
2293
    int err = 0;
2294

    
2295
    err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2296

    
2297
#define save_gp_reg(i) do {                                                   \
2298
        err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);        \
2299
    } while(0)
2300
    __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2301
    save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2302
    save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2303
    save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2304
    save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2305
    save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2306
    save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2307
    save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2308
    save_gp_reg(31);
2309
#undef save_gp_reg
2310

    
2311
    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2312
    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2313

    
2314
    /* Not used yet, but might be useful if we ever have DSP suppport */
2315
#if 0
2316
    if (cpu_has_dsp) {
2317
        err |= __put_user(mfhi1(), &sc->sc_hi1);
2318
        err |= __put_user(mflo1(), &sc->sc_lo1);
2319
        err |= __put_user(mfhi2(), &sc->sc_hi2);
2320
        err |= __put_user(mflo2(), &sc->sc_lo2);
2321
        err |= __put_user(mfhi3(), &sc->sc_hi3);
2322
        err |= __put_user(mflo3(), &sc->sc_lo3);
2323
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2324
    }
2325
    /* same with 64 bit */
2326
#ifdef CONFIG_64BIT
2327
    err |= __put_user(regs->hi, &sc->sc_hi[0]);
2328
    err |= __put_user(regs->lo, &sc->sc_lo[0]);
2329
    if (cpu_has_dsp) {
2330
        err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2331
        err |= __put_user(mflo1(), &sc->sc_lo[1]);
2332
        err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2333
        err |= __put_user(mflo2(), &sc->sc_lo[2]);
2334
        err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2335
        err |= __put_user(mflo3(), &sc->sc_lo[3]);
2336
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2337
    }
2338
#endif
2339
#endif
2340

    
2341
#if 0
2342
    err |= __put_user(!!used_math(), &sc->sc_used_math);
2343

2344
    if (!used_math())
2345
        goto out;
2346

2347
    /*
2348
    * Save FPU state to signal context.  Signal handler will "inherit"
2349
    * current FPU state.
2350
    */
2351
    preempt_disable();
2352

2353
    if (!is_fpu_owner()) {
2354
        own_fpu();
2355
        restore_fp(current);
2356
    }
2357
    err |= save_fp_context(sc);
2358

2359
    preempt_enable();
2360
    out:
2361
#endif
2362
    return err;
2363
}
2364

    
2365
static inline int
2366
restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2367
{
2368
    int err = 0;
2369

    
2370
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2371

    
2372
    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2373
    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2374

    
2375
#define restore_gp_reg(i) do {                                                           \
2376
        err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);                \
2377
    } while(0)
2378
    restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2379
    restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2380
    restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2381
    restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2382
    restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2383
    restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2384
    restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2385
    restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2386
    restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2387
    restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2388
    restore_gp_reg(31);
2389
#undef restore_gp_reg
2390

    
2391
#if 0
2392
    if (cpu_has_dsp) {
2393
        err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2394
        err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2395
        err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2396
        err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2397
        err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2398
        err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2399
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2400
    }
2401
#ifdef CONFIG_64BIT
2402
    err |= __get_user(regs->hi, &sc->sc_hi[0]);
2403
    err |= __get_user(regs->lo, &sc->sc_lo[0]);
2404
    if (cpu_has_dsp) {
2405
        err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2406
        err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2407
        err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2408
        err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2409
        err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2410
        err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2411
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2412
    }
2413
#endif
2414

    
2415
    err |= __get_user(used_math, &sc->sc_used_math);
2416
    conditional_used_math(used_math);
2417

    
2418
    preempt_disable();
2419

    
2420
    if (used_math()) {
2421
        /* restore fpu context if we have used it before */
2422
        own_fpu();
2423
        err |= restore_fp_context(sc);
2424
    } else {
2425
        /* signal handler may have used FPU.  Give it up. */
2426
        lose_fpu();
2427
    }
2428

    
2429
    preempt_enable();
2430
#endif
2431
    return err;
2432
}
2433
/*
2434
 * Determine which stack to use..
2435
 */
2436
static inline abi_ulong
2437
get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2438
{
2439
    unsigned long sp;
2440

    
2441
    /* Default to using normal stack */
2442
    sp = regs->active_tc.gpr[29];
2443

    
2444
    /*
2445
     * FPU emulator may have it's own trampoline active just
2446
     * above the user stack, 16-bytes before the next lowest
2447
     * 16 byte boundary.  Try to avoid trashing it.
2448
     */
2449
    sp -= 32;
2450

    
2451
    /* This is the X/Open sanctioned signal stack switching.  */
2452
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2453
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2454
    }
2455

    
2456
    return (sp - frame_size) & ~7;
2457
}
2458

    
2459
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2460
static void setup_frame(int sig, struct target_sigaction * ka,
2461
                        target_sigset_t *set, CPUState *regs)
2462
{
2463
    struct sigframe *frame;
2464
    abi_ulong frame_addr;
2465
    int i;
2466

    
2467
    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2468
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2469
        goto give_sigsegv;
2470

    
2471
    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2472

    
2473
    if(setup_sigcontext(regs, &frame->sf_sc))
2474
        goto give_sigsegv;
2475

    
2476
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2477
        if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2478
            goto give_sigsegv;
2479
    }
2480

    
2481
    /*
2482
    * Arguments to signal handler:
2483
    *
2484
    *   a0 = signal number
2485
    *   a1 = 0 (should be cause)
2486
    *   a2 = pointer to struct sigcontext
2487
    *
2488
    * $25 and PC point to the signal handler, $29 points to the
2489
    * struct sigframe.
2490
    */
2491
    regs->active_tc.gpr[ 4] = sig;
2492
    regs->active_tc.gpr[ 5] = 0;
2493
    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2494
    regs->active_tc.gpr[29] = frame_addr;
2495
    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2496
    /* The original kernel code sets CP0_EPC to the handler
2497
    * since it returns to userland using eret
2498
    * we cannot do this here, and we must set PC directly */
2499
    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2500
    unlock_user_struct(frame, frame_addr, 1);
2501
    return;
2502

    
2503
give_sigsegv:
2504
    unlock_user_struct(frame, frame_addr, 1);
2505
    force_sig(TARGET_SIGSEGV/*, current*/);
2506
    return;
2507
}
2508

    
2509
long do_sigreturn(CPUState *regs)
2510
{
2511
    struct sigframe *frame;
2512
    abi_ulong frame_addr;
2513
    sigset_t blocked;
2514
    target_sigset_t target_set;
2515
    int i;
2516

    
2517
#if defined(DEBUG_SIGNAL)
2518
    fprintf(stderr, "do_sigreturn\n");
2519
#endif
2520
    frame_addr = regs->active_tc.gpr[29];
2521
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2522
           goto badframe;
2523

    
2524
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2525
           if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2526
            goto badframe;
2527
    }
2528

    
2529
    target_to_host_sigset_internal(&blocked, &target_set);
2530
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2531

    
2532
    if (restore_sigcontext(regs, &frame->sf_sc))
2533
           goto badframe;
2534

    
2535
#if 0
2536
    /*
2537
     * Don't let your children do this ...
2538
     */
2539
    __asm__ __volatile__(
2540
           "move\t$29, %0\n\t"
2541
           "j\tsyscall_exit"
2542
           :/* no outputs */
2543
           :"r" (&regs));
2544
    /* Unreached */
2545
#endif
2546

    
2547
    regs->active_tc.PC = regs->CP0_EPC;
2548
    /* I am not sure this is right, but it seems to work
2549
    * maybe a problem with nested signals ? */
2550
    regs->CP0_EPC = 0;
2551
    return 0;
2552

    
2553
badframe:
2554
    force_sig(TARGET_SIGSEGV/*, current*/);
2555
    return 0;
2556
}
2557

    
2558
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2559
                           target_siginfo_t *info,
2560
                           target_sigset_t *set, CPUState *env)
2561
{
2562
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2563
}
2564

    
2565
long do_rt_sigreturn(CPUState *env)
2566
{
2567
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2568
    return -TARGET_ENOSYS;
2569
}
2570

    
2571
#elif defined(TARGET_SH4)
2572

    
2573
/*
2574
 * code and data structures from linux kernel:
2575
 * include/asm-sh/sigcontext.h
2576
 * arch/sh/kernel/signal.c
2577
 */
2578

    
2579
struct target_sigcontext {
2580
    target_ulong  oldmask;
2581

    
2582
    /* CPU registers */
2583
    target_ulong  sc_gregs[16];
2584
    target_ulong  sc_pc;
2585
    target_ulong  sc_pr;
2586
    target_ulong  sc_sr;
2587
    target_ulong  sc_gbr;
2588
    target_ulong  sc_mach;
2589
    target_ulong  sc_macl;
2590

    
2591
    /* FPU registers */
2592
    target_ulong  sc_fpregs[16];
2593
    target_ulong  sc_xfpregs[16];
2594
    unsigned int sc_fpscr;
2595
    unsigned int sc_fpul;
2596
    unsigned int sc_ownedfp;
2597
};
2598

    
2599
struct target_sigframe
2600
{
2601
    struct target_sigcontext sc;
2602
    target_ulong extramask[TARGET_NSIG_WORDS-1];
2603
    uint16_t retcode[3];
2604
};
2605

    
2606

    
2607
struct target_ucontext {
2608
    target_ulong uc_flags;
2609
    struct target_ucontext *uc_link;
2610
    target_stack_t uc_stack;
2611
    struct target_sigcontext uc_mcontext;
2612
    target_sigset_t uc_sigmask;        /* mask last for extensibility */
2613
};
2614

    
2615
struct target_rt_sigframe
2616
{
2617
    struct target_siginfo info;
2618
    struct target_ucontext uc;
2619
    uint16_t retcode[3];
2620
};
2621

    
2622

    
2623
#define MOVW(n)  (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2624
#define TRAP_NOARG 0xc310         /* Syscall w/no args (NR in R3) SH3/4 */
2625

    
2626
static abi_ulong get_sigframe(struct target_sigaction *ka,
2627
                         unsigned long sp, size_t frame_size)
2628
{
2629
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2630
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2631
    }
2632

    
2633
    return (sp - frame_size) & -8ul;
2634
}
2635

    
2636
static int setup_sigcontext(struct target_sigcontext *sc,
2637
                            CPUState *regs, unsigned long mask)
2638
{
2639
    int err = 0;
2640

    
2641
#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
2642
    COPY(gregs[0]); COPY(gregs[1]);
2643
    COPY(gregs[2]); COPY(gregs[3]);
2644
    COPY(gregs[4]); COPY(gregs[5]);
2645
    COPY(gregs[6]); COPY(gregs[7]);
2646
    COPY(gregs[8]); COPY(gregs[9]);
2647
    COPY(gregs[10]); COPY(gregs[11]);
2648
    COPY(gregs[12]); COPY(gregs[13]);
2649
    COPY(gregs[14]); COPY(gregs[15]);
2650
    COPY(gbr); COPY(mach);
2651
    COPY(macl); COPY(pr);
2652
    COPY(sr); COPY(pc);
2653
#undef COPY
2654

    
2655
    /* todo: save FPU registers here */
2656

    
2657
    /* non-iBCS2 extensions.. */
2658
    err |= __put_user(mask, &sc->oldmask);
2659

    
2660
    return err;
2661
}
2662

    
2663
static int restore_sigcontext(struct CPUState *regs,
2664
                              struct target_sigcontext *sc)
2665
{
2666
    unsigned int err = 0;
2667

    
2668
#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
2669
    COPY(gregs[1]);
2670
    COPY(gregs[2]); COPY(gregs[3]);
2671
    COPY(gregs[4]); COPY(gregs[5]);
2672
    COPY(gregs[6]); COPY(gregs[7]);
2673
    COPY(gregs[8]); COPY(gregs[9]);
2674
    COPY(gregs[10]); COPY(gregs[11]);
2675
    COPY(gregs[12]); COPY(gregs[13]);
2676
    COPY(gregs[14]); COPY(gregs[15]);
2677
    COPY(gbr); COPY(mach);
2678
    COPY(macl); COPY(pr);
2679
    COPY(sr); COPY(pc);
2680
#undef COPY
2681

    
2682
    /* todo: restore FPU registers here */
2683

    
2684
    regs->tra = -1;         /* disable syscall checks */
2685
    return err;
2686
}
2687

    
2688
static void setup_frame(int sig, struct target_sigaction *ka,
2689
                        target_sigset_t *set, CPUState *regs)
2690
{
2691
    struct target_sigframe *frame;
2692
    abi_ulong frame_addr;
2693
    int i;
2694
    int err = 0;
2695
    int signal;
2696

    
2697
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2698
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2699
        goto give_sigsegv;
2700

    
2701
    signal = current_exec_domain_sig(sig);
2702

    
2703
    err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2704

    
2705
    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2706
        err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2707
    }
2708

    
2709
    /* Set up to return from userspace.  If provided, use a stub
2710
       already in userspace.  */
2711
    if (ka->sa_flags & TARGET_SA_RESTORER) {
2712
        regs->pr = (unsigned long) ka->sa_restorer;
2713
    } else {
2714
        /* Generate return code (system call to sigreturn) */
2715
        err |= __put_user(MOVW(2), &frame->retcode[0]);
2716
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2717
        err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2718
        regs->pr = (unsigned long) frame->retcode;
2719
    }
2720

    
2721
    if (err)
2722
        goto give_sigsegv;
2723

    
2724
    /* Set up registers for signal handler */
2725
    regs->gregs[15] = (unsigned long) frame;
2726
    regs->gregs[4] = signal; /* Arg for signal handler */
2727
    regs->gregs[5] = 0;
2728
    regs->gregs[6] = (unsigned long) &frame->sc;
2729
    regs->pc = (unsigned long) ka->_sa_handler;
2730

    
2731
    unlock_user_struct(frame, frame_addr, 1);
2732
    return;
2733

    
2734
give_sigsegv:
2735
    unlock_user_struct(frame, frame_addr, 1);
2736
    force_sig(SIGSEGV);
2737
}
2738

    
2739
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2740
                           target_siginfo_t *info,
2741
                           target_sigset_t *set, CPUState *regs)
2742
{
2743
    struct target_rt_sigframe *frame;
2744
    abi_ulong frame_addr;
2745
    int i;
2746
    int err = 0;
2747
    int signal;
2748

    
2749
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2750
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2751
        goto give_sigsegv;
2752

    
2753
    signal = current_exec_domain_sig(sig);
2754

    
2755
    err |= copy_siginfo_to_user(&frame->info, info);
2756

    
2757
    /* Create the ucontext.  */
2758
    err |= __put_user(0, &frame->uc.uc_flags);
2759
    err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2760
    err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2761
                      &frame->uc.uc_stack.ss_sp);
2762
    err |= __put_user(sas_ss_flags(regs->gregs[15]),
2763
                      &frame->uc.uc_stack.ss_flags);
2764
    err |= __put_user(target_sigaltstack_used.ss_size,
2765
                      &frame->uc.uc_stack.ss_size);
2766
    err |= setup_sigcontext(&frame->uc.uc_mcontext,
2767
                            regs, set->sig[0]);
2768
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2769
        err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2770
    }
2771

    
2772
    /* Set up to return from userspace.  If provided, use a stub
2773
       already in userspace.  */
2774
    if (ka->sa_flags & TARGET_SA_RESTORER) {
2775
        regs->pr = (unsigned long) ka->sa_restorer;
2776
    } else {
2777
        /* Generate return code (system call to sigreturn) */
2778
        err |= __put_user(MOVW(2), &frame->retcode[0]);
2779
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2780
        err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2781
        regs->pr = (unsigned long) frame->retcode;
2782
    }
2783

    
2784
    if (err)
2785
        goto give_sigsegv;
2786

    
2787
    /* Set up registers for signal handler */
2788
    regs->gregs[15] = (unsigned long) frame;
2789
    regs->gregs[4] = signal; /* Arg for signal handler */
2790
    regs->gregs[5] = (unsigned long) &frame->info;
2791
    regs->gregs[6] = (unsigned long) &frame->uc;
2792
    regs->pc = (unsigned long) ka->_sa_handler;
2793

    
2794
    unlock_user_struct(frame, frame_addr, 1);
2795
    return;
2796

    
2797
give_sigsegv:
2798
    unlock_user_struct(frame, frame_addr, 1);
2799
    force_sig(SIGSEGV);
2800
}
2801

    
2802
long do_sigreturn(CPUState *regs)
2803
{
2804
    struct target_sigframe *frame;
2805
    abi_ulong frame_addr;
2806
    sigset_t blocked;
2807
    target_sigset_t target_set;
2808
    int i;
2809
    int err = 0;
2810

    
2811
#if defined(DEBUG_SIGNAL)
2812
    fprintf(stderr, "do_sigreturn\n");
2813
#endif
2814
    frame_addr = regs->gregs[15];
2815
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2816
           goto badframe;
2817

    
2818
    err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2819
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2820
        err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2821
    }
2822

    
2823
    if (err)
2824
        goto badframe;
2825

    
2826
    target_to_host_sigset_internal(&blocked, &target_set);
2827
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2828

    
2829
    if (restore_sigcontext(regs, &frame->sc))
2830
        goto badframe;
2831

    
2832
    unlock_user_struct(frame, frame_addr, 0);
2833
    return regs->gregs[0];
2834

    
2835
badframe:
2836
    unlock_user_struct(frame, frame_addr, 0);
2837
    force_sig(TARGET_SIGSEGV);
2838
    return 0;
2839
}
2840

    
2841
long do_rt_sigreturn(CPUState *regs)
2842
{
2843
    struct target_rt_sigframe *frame;
2844
    abi_ulong frame_addr;
2845
    sigset_t blocked;
2846

    
2847
#if defined(DEBUG_SIGNAL)
2848
    fprintf(stderr, "do_rt_sigreturn\n");
2849
#endif
2850
    frame_addr = regs->gregs[15];
2851
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2852
           goto badframe;
2853

    
2854
    target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2855
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2856

    
2857
    if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2858
        goto badframe;
2859

    
2860
    if (do_sigaltstack(frame_addr +
2861
                       offsetof(struct target_rt_sigframe, uc.uc_stack),
2862
                       0, get_sp_from_cpustate(regs)) == -EFAULT)
2863
        goto badframe;
2864

    
2865
    unlock_user_struct(frame, frame_addr, 0);
2866
    return regs->gregs[0];
2867

    
2868
badframe:
2869
    unlock_user_struct(frame, frame_addr, 0);
2870
    force_sig(TARGET_SIGSEGV);
2871
    return 0;
2872
}
2873
#elif defined(TARGET_CRIS)
2874

    
2875
struct target_sigcontext {
2876
        struct target_pt_regs regs;  /* needs to be first */
2877
        uint32_t oldmask;
2878
        uint32_t usp;    /* usp before stacking this gunk on it */
2879
};
2880

    
2881
/* Signal frames. */
2882
struct target_signal_frame {
2883
        struct target_sigcontext sc;
2884
        uint32_t extramask[TARGET_NSIG_WORDS - 1];
2885
        uint8_t retcode[8];       /* Trampoline code. */
2886
};
2887

    
2888
struct rt_signal_frame {
2889
        struct siginfo *pinfo;
2890
        void *puc;
2891
        struct siginfo info;
2892
        struct ucontext uc;
2893
        uint8_t retcode[8];       /* Trampoline code. */
2894
};
2895

    
2896
static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2897
{
2898
        __put_user(env->regs[0], &sc->regs.r0);
2899
        __put_user(env->regs[1], &sc->regs.r1);
2900
        __put_user(env->regs[2], &sc->regs.r2);
2901
        __put_user(env->regs[3], &sc->regs.r3);
2902
        __put_user(env->regs[4], &sc->regs.r4);
2903
        __put_user(env->regs[5], &sc->regs.r5);
2904
        __put_user(env->regs[6], &sc->regs.r6);
2905
        __put_user(env->regs[7], &sc->regs.r7);
2906
        __put_user(env->regs[8], &sc->regs.r8);
2907
        __put_user(env->regs[9], &sc->regs.r9);
2908
        __put_user(env->regs[10], &sc->regs.r10);
2909
        __put_user(env->regs[11], &sc->regs.r11);
2910
        __put_user(env->regs[12], &sc->regs.r12);
2911
        __put_user(env->regs[13], &sc->regs.r13);
2912
        __put_user(env->regs[14], &sc->usp);
2913
        __put_user(env->regs[15], &sc->regs.acr);
2914
        __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2915
        __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2916
        __put_user(env->pc, &sc->regs.erp);
2917
}
2918

    
2919
static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2920
{
2921
        __get_user(env->regs[0], &sc->regs.r0);
2922
        __get_user(env->regs[1], &sc->regs.r1);
2923
        __get_user(env->regs[2], &sc->regs.r2);
2924
        __get_user(env->regs[3], &sc->regs.r3);
2925
        __get_user(env->regs[4], &sc->regs.r4);
2926
        __get_user(env->regs[5], &sc->regs.r5);
2927
        __get_user(env->regs[6], &sc->regs.r6);
2928
        __get_user(env->regs[7], &sc->regs.r7);
2929
        __get_user(env->regs[8], &sc->regs.r8);
2930
        __get_user(env->regs[9], &sc->regs.r9);
2931
        __get_user(env->regs[10], &sc->regs.r10);
2932
        __get_user(env->regs[11], &sc->regs.r11);
2933
        __get_user(env->regs[12], &sc->regs.r12);
2934
        __get_user(env->regs[13], &sc->regs.r13);
2935
        __get_user(env->regs[14], &sc->usp);
2936
        __get_user(env->regs[15], &sc->regs.acr);
2937
        __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2938
        __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2939
        __get_user(env->pc, &sc->regs.erp);
2940
}
2941

    
2942
static abi_ulong get_sigframe(CPUState *env, int framesize)
2943
{
2944
        abi_ulong sp;
2945
        /* Align the stack downwards to 4.  */
2946
        sp = (env->regs[R_SP] & ~3);
2947
        return sp - framesize;
2948
}
2949

    
2950
static void setup_frame(int sig, struct target_sigaction *ka,
2951
                        target_sigset_t *set, CPUState *env)
2952
{
2953
        struct target_signal_frame *frame;
2954
        abi_ulong frame_addr;
2955
        int err = 0;
2956
        int i;
2957

    
2958
        frame_addr = get_sigframe(env, sizeof *frame);
2959
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2960
                goto badframe;
2961

    
2962
        /*
2963
         * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2964
         * use this trampoline anymore but it sets it up for GDB.
2965
         * In QEMU, using the trampoline simplifies things a bit so we use it.
2966
         *
2967
         * This is movu.w __NR_sigreturn, r9; break 13;
2968
         */
2969
        err |= __put_user(0x9c5f, frame->retcode+0);
2970
        err |= __put_user(TARGET_NR_sigreturn, 
2971
                          frame->retcode+2);
2972
        err |= __put_user(0xe93d, frame->retcode+4);
2973

    
2974
        /* Save the mask.  */
2975
        err |= __put_user(set->sig[0], &frame->sc.oldmask);
2976
        if (err)
2977
                goto badframe;
2978

    
2979
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2980
                if (__put_user(set->sig[i], &frame->extramask[i - 1]))
2981
                        goto badframe;
2982
        }
2983

    
2984
        setup_sigcontext(&frame->sc, env);
2985

    
2986
        /* Move the stack and setup the arguments for the handler.  */
2987
        env->regs[R_SP] = (uint32_t) (unsigned long) frame;
2988
        env->regs[10] = sig;
2989
        env->pc = (unsigned long) ka->_sa_handler;
2990
        /* Link SRP so the guest returns through the trampoline.  */
2991
        env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
2992

    
2993
        unlock_user_struct(frame, frame_addr, 1);
2994
        return;
2995
  badframe:
2996
        unlock_user_struct(frame, frame_addr, 1);
2997
        force_sig(TARGET_SIGSEGV);
2998
}
2999

    
3000
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3001
                           target_siginfo_t *info,
3002
                           target_sigset_t *set, CPUState *env)
3003
{
3004
    fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3005
}
3006

    
3007
long do_sigreturn(CPUState *env)
3008
{
3009
        struct target_signal_frame *frame;
3010
        abi_ulong frame_addr;
3011
        target_sigset_t target_set;
3012
        sigset_t set;
3013
        int i;
3014

    
3015
        frame_addr = env->regs[R_SP];
3016
        /* Make sure the guest isn't playing games.  */
3017
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3018
                goto badframe;
3019

    
3020
        /* Restore blocked signals */
3021
        if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3022
                goto badframe;
3023
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3024
                if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3025
                        goto badframe;
3026
        }
3027
        target_to_host_sigset_internal(&set, &target_set);
3028
        sigprocmask(SIG_SETMASK, &set, NULL);
3029

    
3030
        restore_sigcontext(&frame->sc, env);
3031
        unlock_user_struct(frame, frame_addr, 0);
3032
        return env->regs[10];
3033
  badframe:
3034
        unlock_user_struct(frame, frame_addr, 0);
3035
        force_sig(TARGET_SIGSEGV);
3036
}
3037

    
3038
long do_rt_sigreturn(CPUState *env)
3039
{
3040
    fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3041
    return -TARGET_ENOSYS;
3042
}
3043

    
3044
#else
3045

    
3046
static void setup_frame(int sig, struct target_sigaction *ka,
3047
                        target_sigset_t *set, CPUState *env)
3048
{
3049
    fprintf(stderr, "setup_frame: not implemented\n");
3050
}
3051

    
3052
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3053
                           target_siginfo_t *info,
3054
                           target_sigset_t *set, CPUState *env)
3055
{
3056
    fprintf(stderr, "setup_rt_frame: not implemented\n");
3057
}
3058

    
3059
long do_sigreturn(CPUState *env)
3060
{
3061
    fprintf(stderr, "do_sigreturn: not implemented\n");
3062
    return -TARGET_ENOSYS;
3063
}
3064

    
3065
long do_rt_sigreturn(CPUState *env)
3066
{
3067
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3068
    return -TARGET_ENOSYS;
3069
}
3070

    
3071
#endif
3072

    
3073
void process_pending_signals(CPUState *cpu_env)
3074
{
3075
    int sig;
3076
    abi_ulong handler;
3077
    sigset_t set, old_set;
3078
    target_sigset_t target_old_set;
3079
    struct emulated_sigtable *k;
3080
    struct target_sigaction *sa;
3081
    struct sigqueue *q;
3082
    TaskState *ts = cpu_env->opaque;
3083

    
3084
    if (!ts->signal_pending)
3085
        return;
3086

    
3087
    /* FIXME: This is not threadsafe.  */
3088
    k = ts->sigtab;
3089
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
3090
        if (k->pending)
3091
            goto handle_signal;
3092
        k++;
3093
    }
3094
    /* if no signal is pending, just return */
3095
    ts->signal_pending = 0;
3096
    return;
3097

    
3098
 handle_signal:
3099
#ifdef DEBUG_SIGNAL
3100
    fprintf(stderr, "qemu: process signal %d\n", sig);
3101
#endif
3102
    /* dequeue signal */
3103
    q = k->first;
3104
    k->first = q->next;
3105
    if (!k->first)
3106
        k->pending = 0;
3107

    
3108
    sig = gdb_handlesig (cpu_env, sig);
3109
    if (!sig) {
3110
        fprintf (stderr, "Lost signal\n");
3111
        abort();
3112
    }
3113

    
3114
    sa = &sigact_table[sig - 1];
3115
    handler = sa->_sa_handler;
3116
    if (handler == TARGET_SIG_DFL) {
3117
        /* default handler : ignore some signal. The other are fatal */
3118
        if (sig != TARGET_SIGCHLD &&
3119
            sig != TARGET_SIGURG &&
3120
            sig != TARGET_SIGWINCH) {
3121
            force_sig(sig);
3122
        }
3123
    } else if (handler == TARGET_SIG_IGN) {
3124
        /* ignore sig */
3125
    } else if (handler == TARGET_SIG_ERR) {
3126
        force_sig(sig);
3127
    } else {
3128
        /* compute the blocked signals during the handler execution */
3129
        target_to_host_sigset(&set, &sa->sa_mask);
3130
        /* SA_NODEFER indicates that the current signal should not be
3131
           blocked during the handler */
3132
        if (!(sa->sa_flags & TARGET_SA_NODEFER))
3133
            sigaddset(&set, target_to_host_signal(sig));
3134

    
3135
        /* block signals in the handler using Linux */
3136
        sigprocmask(SIG_BLOCK, &set, &old_set);
3137
        /* save the previous blocked signal state to restore it at the
3138
           end of the signal execution (see do_sigreturn) */
3139
        host_to_target_sigset_internal(&target_old_set, &old_set);
3140

    
3141
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
3142
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
3143
        {
3144
            CPUX86State *env = cpu_env;
3145
            if (env->eflags & VM_MASK)
3146
                save_v86_state(env);
3147
        }
3148
#endif
3149
        /* prepare the stack frame of the virtual CPU */
3150
        if (sa->sa_flags & TARGET_SA_SIGINFO)
3151
            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3152
        else
3153
            setup_frame(sig, sa, &target_old_set, cpu_env);
3154
        if (sa->sa_flags & TARGET_SA_RESETHAND)
3155
            sa->_sa_handler = TARGET_SIG_DFL;
3156
    }
3157
    if (q != &k->info)
3158
        free_sigqueue(cpu_env, q);
3159
}