Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 8fcd3692

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
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
        /* default handler : ignore some signal. The other are fatal */
365
        if (sig != TARGET_SIGCHLD &&
366
            sig != TARGET_SIGURG &&
367
            sig != TARGET_SIGWINCH) {
368
            force_sig(sig);
369
        } else {
370
            return 0; /* indicate ignored */
371
        }
372
    } else if (handler == TARGET_SIG_IGN) {
373
        /* ignore signal */
374
        return 0;
375
    } else if (handler == TARGET_SIG_ERR) {
376
        force_sig(sig);
377
    } else {
378
        pq = &k->first;
379
        if (sig < TARGET_SIGRTMIN) {
380
            /* if non real time signal, we queue exactly one signal */
381
            if (!k->pending)
382
                q = &k->info;
383
            else
384
                return 0;
385
        } else {
386
            if (!k->pending) {
387
                /* first signal */
388
                q = &k->info;
389
            } else {
390
                q = alloc_sigqueue(env);
391
                if (!q)
392
                    return -EAGAIN;
393
                while (*pq != NULL)
394
                    pq = &(*pq)->next;
395
            }
396
        }
397
        *pq = q;
398
        q->info = *info;
399
        q->next = NULL;
400
        k->pending = 1;
401
        /* signal that a new signal is pending */
402
        ts->signal_pending = 1;
403
        return 1; /* indicates that the signal was queued */
404
    }
405
}
406

    
407
static void host_signal_handler(int host_signum, siginfo_t *info,
408
                                void *puc)
409
{
410
    int sig;
411
    target_siginfo_t tinfo;
412

    
413
    /* the CPU emulator uses some host signals to detect exceptions,
414
       we we forward to it some signals */
415
    if (host_signum == SIGSEGV || host_signum == SIGBUS) {
416
        if (cpu_signal_handler(host_signum, info, puc))
417
            return;
418
    }
419

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

    
434
/* do_sigaltstack() returns target values and errnos. */
435
/* compare linux/kernel/signal.c:do_sigaltstack() */
436
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
437
{
438
    int ret;
439
    struct target_sigaltstack oss;
440

    
441
    /* XXX: test errors */
442
    if(uoss_addr)
443
    {
444
        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
445
        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
446
        __put_user(sas_ss_flags(sp), &oss.ss_flags);
447
    }
448

    
449
    if(uss_addr)
450
    {
451
        struct target_sigaltstack *uss;
452
        struct target_sigaltstack ss;
453

    
454
        ret = -TARGET_EFAULT;
455
        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
456
            || __get_user(ss.ss_sp, &uss->ss_sp)
457
            || __get_user(ss.ss_size, &uss->ss_size)
458
            || __get_user(ss.ss_flags, &uss->ss_flags))
459
            goto out;
460
        unlock_user_struct(uss, uss_addr, 0);
461

    
462
        ret = -TARGET_EPERM;
463
        if (on_sig_stack(sp))
464
            goto out;
465

    
466
        ret = -TARGET_EINVAL;
467
        if (ss.ss_flags != TARGET_SS_DISABLE
468
            && ss.ss_flags != TARGET_SS_ONSTACK
469
            && ss.ss_flags != 0)
470
            goto out;
471

    
472
        if (ss.ss_flags == TARGET_SS_DISABLE) {
473
            ss.ss_size = 0;
474
            ss.ss_sp = 0;
475
        } else {
476
            ret = -TARGET_ENOMEM;
477
            if (ss.ss_size < MINSIGSTKSZ)
478
                goto out;
479
        }
480

    
481
        target_sigaltstack_used.ss_sp = ss.ss_sp;
482
        target_sigaltstack_used.ss_size = ss.ss_size;
483
    }
484

    
485
    if (uoss_addr) {
486
        ret = -TARGET_EFAULT;
487
        if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
488
            goto out;
489
    }
490

    
491
    ret = 0;
492
out:
493
    return ret;
494
}
495

    
496
/* do_sigaction() return host values and errnos */
497
int do_sigaction(int sig, const struct target_sigaction *act,
498
                 struct target_sigaction *oact)
499
{
500
    struct target_sigaction *k;
501
    struct sigaction act1;
502
    int host_sig;
503
    int ret = 0;
504

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

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

    
552
#ifndef offsetof
553
#define offsetof(type, field) ((size_t) &((type *)0)->field)
554
#endif
555

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

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

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

    
571
/* from the Linux kernel */
572

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

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

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

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

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

    
610
#define X86_FXSR_MAGIC                0x0000
611

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
784
        if (err)
785
                goto give_sigsegv;
786

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

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

    
797
        unlock_user_struct(frame, frame_addr, 1);
798

    
799
        return;
800

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

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

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

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

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

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

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

    
864
        if (err)
865
                goto give_sigsegv;
866

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

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

    
877
        unlock_user_struct(frame, frame_addr, 1);
878

    
879
        return;
880

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
995
#elif defined(TARGET_ARM)
996

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

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

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

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

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

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

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

    
1068
#define TARGET_CONFIG_CPU_32 1
1069

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

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

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

    
1088

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

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

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

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

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

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

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

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

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

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

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

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

    
1179
        return 0;
1180
}
1181

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1365
        err |= !valid_user_regs(env);
1366

    
1367
        return err;
1368
}
1369

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1437
    return 0;
1438
}
1439

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1557
#elif defined(TARGET_SPARC)
1558

    
1559
#define __SUNOS_MAXWIN   31
1560

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

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

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

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

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

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

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

    
1619

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1838

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1991
#define TARGET_STACK_BIAS 2047
1992

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

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

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

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

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

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

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

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

    
2112
    err = 0;
2113

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

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

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

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

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

    
2185
# warning signal handling not implemented
2186

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

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

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

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

    
2212
#elif defined(TARGET_ABI_MIPSN32)
2213

    
2214
# warning signal handling not implemented
2215

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

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

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

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

    
2241
#elif defined(TARGET_ABI_MIPSO32)
2242

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2417
    preempt_disable();
2418

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2570
#elif defined(TARGET_SH4)
2571

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

    
2578
struct target_sigcontext {
2579
    target_ulong  oldmask;
2580

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

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

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

    
2605

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

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

    
2621

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

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

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

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

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

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

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

    
2659
    return err;
2660
}
2661

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

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

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

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

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

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

    
2700
    signal = current_exec_domain_sig(sig);
2701

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

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

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

    
2720
    if (err)
2721
        goto give_sigsegv;
2722

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

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

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

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

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

    
2752
    signal = current_exec_domain_sig(sig);
2753

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

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

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

    
2783
    if (err)
2784
        goto give_sigsegv;
2785

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

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

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

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

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

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

    
2822
    if (err)
2823
        goto badframe;
2824

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3029
        restore_sigcontext(&frame->sc, env);
3030
        /* Compensate for the syscall return path advancing brk.  */
3031
        env->pc -= 2;
3032

    
3033
        unlock_user_struct(frame, frame_addr, 0);
3034
        return env->regs[10];
3035
  badframe:
3036
        unlock_user_struct(frame, frame_addr, 0);
3037
        force_sig(TARGET_SIGSEGV);
3038
}
3039

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

    
3046
#else
3047

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

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

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

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

    
3073
#endif
3074

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

    
3086
    if (!ts->signal_pending)
3087
        return;
3088

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

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

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

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

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

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