Statistics
| Branch: | Revision:

root / linux-user / signal.c @ ac509d88

History | View | Annotate | Download (90.7 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
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
553
                                       const target_siginfo_t *info)
554
{
555
    tswap_siginfo(tinfo, info);
556
    return 0;
557
}
558

    
559
static inline int current_exec_domain_sig(int sig)
560
{
561
    return /* current->exec_domain && current->exec_domain->signal_invmap
562
              && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
563
}
564

    
565
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
566

    
567
/* from the Linux kernel */
568

    
569
struct target_fpreg {
570
        uint16_t significand[4];
571
        uint16_t exponent;
572
};
573

    
574
struct target_fpxreg {
575
        uint16_t significand[4];
576
        uint16_t exponent;
577
        uint16_t padding[3];
578
};
579

    
580
struct target_xmmreg {
581
        abi_ulong element[4];
582
};
583

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

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

    
606
#define X86_FXSR_MAGIC                0x0000
607

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

    
633
struct target_ucontext {
634
        abi_ulong         tuc_flags;
635
        abi_ulong         tuc_link;
636
        target_stack_t          tuc_stack;
637
        struct target_sigcontext tuc_mcontext;
638
        target_sigset_t          tuc_sigmask;        /* mask last for extensibility */
639
};
640

    
641
struct sigframe
642
{
643
    abi_ulong pretcode;
644
    int sig;
645
    struct target_sigcontext sc;
646
    struct target_fpstate fpstate;
647
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
648
    char retcode[8];
649
};
650

    
651
struct rt_sigframe
652
{
653
    abi_ulong pretcode;
654
    int sig;
655
    abi_ulong pinfo;
656
    abi_ulong puc;
657
    struct target_siginfo info;
658
    struct target_ucontext uc;
659
    struct target_fpstate fpstate;
660
    char retcode[8];
661
};
662

    
663
/*
664
 * Set up a signal frame.
665
 */
666

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

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

    
696
        cpu_x86_fsave(env, fpstate_addr, 1);
697
        fpstate->status = fpstate->sw;
698
        magic = 0xffff;
699
        err |= __put_user(magic, &fpstate->magic);
700
        err |= __put_user(fpstate_addr, &sc->fpstate);
701

    
702
        /* non-iBCS2 extensions.. */
703
        err |= __put_user(mask, &sc->oldmask);
704
        err |= __put_user(env->cr[2], &sc->cr2);
705
        return err;
706
}
707

    
708
/*
709
 * Determine which stack to use..
710
 */
711

    
712
static inline abi_ulong
713
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
714
{
715
        unsigned long esp;
716

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

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

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

    
743
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
744

    
745
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
746
                goto give_sigsegv;
747

    
748
        err |= __put_user(current_exec_domain_sig(sig),
749
                          &frame->sig);
750
        if (err)
751
                goto give_sigsegv;
752

    
753
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
754
                         frame_addr + offsetof(struct sigframe, fpstate));
755
        if (err)
756
                goto give_sigsegv;
757

    
758
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
759
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
760
                goto give_sigsegv;
761
        }
762

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

    
780
        if (err)
781
                goto give_sigsegv;
782

    
783
        /* Set up registers for signal handler */
784
        env->regs[R_ESP] = frame_addr;
785
        env->eip = ka->_sa_handler;
786

    
787
        cpu_x86_load_seg(env, R_DS, __USER_DS);
788
        cpu_x86_load_seg(env, R_ES, __USER_DS);
789
        cpu_x86_load_seg(env, R_SS, __USER_DS);
790
        cpu_x86_load_seg(env, R_CS, __USER_CS);
791
        env->eflags &= ~TF_MASK;
792

    
793
        unlock_user_struct(frame, frame_addr, 1);
794

    
795
        return;
796

    
797
give_sigsegv:
798
        unlock_user_struct(frame, frame_addr, 1);
799
        if (sig == TARGET_SIGSEGV)
800
                ka->_sa_handler = TARGET_SIG_DFL;
801
        force_sig(TARGET_SIGSEGV /* , current */);
802
}
803

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

    
813
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
814

    
815
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
816
                goto give_sigsegv;
817

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

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

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

    
860
        if (err)
861
                goto give_sigsegv;
862

    
863
        /* Set up registers for signal handler */
864
        env->regs[R_ESP] = frame_addr;
865
        env->eip = ka->_sa_handler;
866

    
867
        cpu_x86_load_seg(env, R_DS, __USER_DS);
868
        cpu_x86_load_seg(env, R_ES, __USER_DS);
869
        cpu_x86_load_seg(env, R_SS, __USER_DS);
870
        cpu_x86_load_seg(env, R_CS, __USER_CS);
871
        env->eflags &= ~TF_MASK;
872

    
873
        unlock_user_struct(frame, frame_addr, 1);
874

    
875
        return;
876

    
877
give_sigsegv:
878
        unlock_user_struct(frame, frame_addr, 1);
879
        if (sig == TARGET_SIGSEGV)
880
                ka->_sa_handler = TARGET_SIG_DFL;
881
        force_sig(TARGET_SIGSEGV /* , current */);
882
}
883

    
884
static int
885
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
886
{
887
        unsigned int err = 0;
888
        abi_ulong fpstate_addr;
889
        unsigned int tmpflags;
890

    
891
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
892
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
893
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
894
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
895

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

    
905
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
906
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
907

    
908
        tmpflags = tswapl(sc->eflags);
909
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
910
        //                regs->orig_eax = -1;                /* disable syscall checks */
911

    
912
        fpstate_addr = tswapl(sc->fpstate);
913
        if (fpstate_addr != 0) {
914
                if (!access_ok(VERIFY_READ, fpstate_addr, 
915
                               sizeof(struct target_fpstate)))
916
                        goto badframe;
917
                cpu_x86_frstor(env, fpstate_addr, 1);
918
        }
919

    
920
        *peax = tswapl(sc->eax);
921
        return err;
922
badframe:
923
        return 1;
924
}
925

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

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

    
947
    target_to_host_sigset_internal(&set, &target_set);
948
    sigprocmask(SIG_SETMASK, &set, NULL);
949

    
950
    /* restore registers */
951
    if (restore_sigcontext(env, &frame->sc, &eax))
952
        goto badframe;
953
    unlock_user_struct(frame, frame_addr, 0);
954
    return eax;
955

    
956
badframe:
957
    unlock_user_struct(frame, frame_addr, 0);
958
    force_sig(TARGET_SIGSEGV);
959
    return 0;
960
}
961

    
962
long do_rt_sigreturn(CPUX86State *env)
963
{
964
        abi_ulong frame_addr;
965
        struct rt_sigframe *frame;
966
        sigset_t set;
967
        int eax;
968

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

    
975
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
976
                goto badframe;
977

    
978
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
979
                           get_sp_from_cpustate(env)) == -EFAULT)
980
                goto badframe;
981

    
982
        unlock_user_struct(frame, frame_addr, 0);
983
        return eax;
984

    
985
badframe:
986
        unlock_user_struct(frame, frame_addr, 0);
987
        force_sig(TARGET_SIGSEGV);
988
        return 0;
989
}
990

    
991
#elif defined(TARGET_ARM)
992

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

    
1017
struct target_ucontext_v1 {
1018
    abi_ulong tuc_flags;
1019
    abi_ulong tuc_link;
1020
    target_stack_t tuc_stack;
1021
    struct target_sigcontext tuc_mcontext;
1022
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1023
};
1024

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

    
1035
struct sigframe_v1
1036
{
1037
    struct target_sigcontext sc;
1038
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
1039
    abi_ulong retcode;
1040
};
1041

    
1042
struct sigframe_v2
1043
{
1044
    struct target_ucontext_v2 uc;
1045
    abi_ulong retcode;
1046
};
1047

    
1048
struct rt_sigframe_v1
1049
{
1050
    abi_ulong pinfo;
1051
    abi_ulong puc;
1052
    struct target_siginfo info;
1053
    struct target_ucontext_v1 uc;
1054
    abi_ulong retcode;
1055
};
1056

    
1057
struct rt_sigframe_v2
1058
{
1059
    struct target_siginfo info;
1060
    struct target_ucontext_v2 uc;
1061
    abi_ulong retcode;
1062
};
1063

    
1064
#define TARGET_CONFIG_CPU_32 1
1065

    
1066
/*
1067
 * For ARM syscalls, we encode the syscall number into the instruction.
1068
 */
1069
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1070
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1071

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

    
1079
static const abi_ulong retcodes[4] = {
1080
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
1081
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
1082
};
1083

    
1084

    
1085
#define __get_user_error(x,p,e) __get_user(x, p)
1086

    
1087
static inline int valid_user_regs(CPUState *regs)
1088
{
1089
    return 1;
1090
}
1091

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

    
1116
        __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1117
        __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1118
        __put_user(/* current->thread.address */ 0, &sc->fault_address);
1119
        __put_user(mask, &sc->oldmask);
1120
}
1121

    
1122
static inline abi_ulong
1123
get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1124
{
1125
        unsigned long sp = regs->regs[13];
1126

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

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

    
1146
        if (ka->sa_flags & TARGET_SA_RESTORER) {
1147
                retcode = ka->sa_restorer;
1148
        } else {
1149
                unsigned int idx = thumb;
1150

    
1151
                if (ka->sa_flags & TARGET_SA_SIGINFO)
1152
                        idx += 2;
1153

    
1154
                if (__put_user(retcodes[idx], rc))
1155
                        return 1;
1156
#if 0
1157
                flush_icache_range((abi_ulong)rc,
1158
                                   (abi_ulong)(rc + 1));
1159
#endif
1160
                retcode = rc_addr + thumb;
1161
        }
1162

    
1163
        env->regs[0] = usig;
1164
        env->regs[13] = frame_addr;
1165
        env->regs[14] = retcode;
1166
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1167
        env->thumb = thumb;
1168

    
1169
#if 0
1170
#ifdef TARGET_CONFIG_CPU_32
1171
        env->cpsr = cpsr;
1172
#endif
1173
#endif
1174

    
1175
        return 0;
1176
}
1177

    
1178
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1179
                              target_sigset_t *set, CPUState *env)
1180
{
1181
    struct target_sigaltstack stack;
1182
    int i;
1183

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

    
1187
    memset(&stack, 0, sizeof(stack));
1188
    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1189
    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1190
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1191
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1192

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

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

    
1208
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1209
                return;
1210

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

    
1213
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1214
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1215
                goto end;
1216
        }
1217

    
1218
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1219
                     frame_addr + offsetof(struct sigframe_v1, retcode));
1220

    
1221
end:
1222
        unlock_user_struct(frame, frame_addr, 1);
1223
}
1224

    
1225
static void setup_frame_v2(int usig, struct target_sigaction *ka,
1226
                           target_sigset_t *set, CPUState *regs)
1227
{
1228
        struct sigframe_v2 *frame;
1229
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1230

    
1231
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1232
                return;
1233

    
1234
        setup_sigframe_v2(&frame->uc, set, regs);
1235

    
1236
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1237
                     frame_addr + offsetof(struct sigframe_v2, retcode));
1238

    
1239
        unlock_user_struct(frame, frame_addr, 1);
1240
}
1241

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

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

    
1263
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1264
            return /* 1 */;
1265

    
1266
        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1267
        __put_user(info_addr, &frame->pinfo);
1268
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1269
        __put_user(uc_addr, &frame->puc);
1270
        copy_siginfo_to_user(&frame->info, info);
1271

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

    
1275
        memset(&stack, 0, sizeof(stack));
1276
        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1277
        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1278
        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1279
        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1280

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

    
1287
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1288
                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1289

    
1290
        env->regs[1] = info_addr;
1291
        env->regs[2] = uc_addr;
1292

    
1293
end:
1294
        unlock_user_struct(frame, frame_addr, 1);
1295
}
1296

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

    
1305
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1306
            return /* 1 */;
1307

    
1308
        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1309
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1310
        copy_siginfo_to_user(&frame->info, info);
1311

    
1312
        setup_sigframe_v2(&frame->uc, set, env);
1313

    
1314
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1315
                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1316

    
1317
        env->regs[1] = info_addr;
1318
        env->regs[2] = uc_addr;
1319

    
1320
        unlock_user_struct(frame, frame_addr, 1);
1321
}
1322

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

    
1334
static int
1335
restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1336
{
1337
        int err = 0;
1338
        uint32_t cpsr;
1339

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

    
1361
        err |= !valid_user_regs(env);
1362

    
1363
        return err;
1364
}
1365

    
1366
long do_sigreturn_v1(CPUState *env)
1367
{
1368
        abi_ulong frame_addr;
1369
        struct sigframe_v1 *frame;
1370
        target_sigset_t set;
1371
        sigset_t host_set;
1372
        int i;
1373

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

    
1382
        frame_addr = env->regs[13];
1383
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1384
                goto badframe;
1385

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

    
1393
        target_to_host_sigset_internal(&host_set, &set);
1394
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1395

    
1396
        if (restore_sigcontext(env, &frame->sc))
1397
                goto badframe;
1398

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

    
1407
badframe:
1408
        unlock_user_struct(frame, frame_addr, 0);
1409
        force_sig(SIGSEGV /* , current */);
1410
        return 0;
1411
}
1412

    
1413
static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1414
                                 struct target_ucontext_v2 *uc)
1415
{
1416
    sigset_t host_set;
1417

    
1418
    target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1419
    sigprocmask(SIG_SETMASK, &host_set, NULL);
1420

    
1421
    if (restore_sigcontext(env, &uc->tuc_mcontext))
1422
        return 1;
1423

    
1424
    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1425
        return 1;
1426

    
1427
#if 0
1428
    /* Send SIGTRAP if we're single-stepping */
1429
    if (ptrace_cancel_bpt(current))
1430
            send_sig(SIGTRAP, current, 1);
1431
#endif
1432

    
1433
    return 0;
1434
}
1435

    
1436
long do_sigreturn_v2(CPUState *env)
1437
{
1438
        abi_ulong frame_addr;
1439
        struct sigframe_v2 *frame;
1440

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

    
1449
        frame_addr = env->regs[13];
1450
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1451
                goto badframe;
1452

    
1453
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1454
                goto badframe;
1455

    
1456
        unlock_user_struct(frame, frame_addr, 0);
1457
        return env->regs[0];
1458

    
1459
badframe:
1460
        unlock_user_struct(frame, frame_addr, 0);
1461
        force_sig(SIGSEGV /* , current */);
1462
        return 0;
1463
}
1464

    
1465
long do_sigreturn(CPUState *env)
1466
{
1467
    if (get_osversion() >= 0x020612) {
1468
        return do_sigreturn_v2(env);
1469
    } else {
1470
        return do_sigreturn_v1(env);
1471
    }
1472
}
1473

    
1474
long do_rt_sigreturn_v1(CPUState *env)
1475
{
1476
        abi_ulong frame_addr;
1477
        struct rt_sigframe_v1 *frame;
1478
        sigset_t host_set;
1479

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

    
1488
        frame_addr = env->regs[13];
1489
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1490
                goto badframe;
1491

    
1492
        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1493
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1494

    
1495
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1496
                goto badframe;
1497

    
1498
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1499
                goto badframe;
1500

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

    
1509
badframe:
1510
        unlock_user_struct(frame, frame_addr, 0);
1511
        force_sig(SIGSEGV /* , current */);
1512
        return 0;
1513
}
1514

    
1515
long do_rt_sigreturn_v2(CPUState *env)
1516
{
1517
        abi_ulong frame_addr;
1518
        struct rt_sigframe_v2 *frame;
1519

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

    
1528
        frame_addr = env->regs[13];
1529
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1530
                goto badframe;
1531

    
1532
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1533
                goto badframe;
1534

    
1535
        unlock_user_struct(frame, frame_addr, 0);
1536
        return env->regs[0];
1537

    
1538
badframe:
1539
        unlock_user_struct(frame, frame_addr, 0);
1540
        force_sig(SIGSEGV /* , current */);
1541
        return 0;
1542
}
1543

    
1544
long do_rt_sigreturn(CPUState *env)
1545
{
1546
    if (get_osversion() >= 0x020612) {
1547
        return do_rt_sigreturn_v2(env);
1548
    } else {
1549
        return do_rt_sigreturn_v1(env);
1550
    }
1551
}
1552

    
1553
#elif defined(TARGET_SPARC)
1554

    
1555
#define __SUNOS_MAXWIN   31
1556

    
1557
/* This is what SunOS does, so shall I. */
1558
struct target_sigcontext {
1559
        abi_ulong sigc_onstack;      /* state to restore */
1560

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

    
1569
        /* Now comes information regarding the users window set
1570
         * at the time of the signal.
1571
         */
1572
        abi_ulong sigc_oswins;       /* outstanding windows */
1573

    
1574
        /* stack ptrs for each regwin buf */
1575
        char *sigc_spbuf[__SUNOS_MAXWIN];
1576

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

    
1594
typedef struct {
1595
        struct {
1596
                abi_ulong psr;
1597
                abi_ulong pc;
1598
                abi_ulong npc;
1599
                abi_ulong y;
1600
                abi_ulong u_regs[16]; /* globals and ins */
1601
        }               si_regs;
1602
        int             si_mask;
1603
} __siginfo_t;
1604

    
1605
typedef struct {
1606
        unsigned   long si_float_regs [32];
1607
        unsigned   long si_fsr;
1608
        unsigned   long si_fpqdepth;
1609
        struct {
1610
                unsigned long *insn_addr;
1611
                unsigned long insn;
1612
        } si_fpqueue [16];
1613
} qemu_siginfo_fpu_t;
1614

    
1615

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

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

    
1651
static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
1652
                                     CPUState *env, unsigned long framesize)
1653
{
1654
        abi_ulong sp;
1655

    
1656
        sp = env->regwptr[UREG_FP];
1657

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

    
1667
static int
1668
setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1669
{
1670
        int err = 0, i;
1671

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

    
1686
#if 0
1687
static int
1688
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1689
                 CPUState *env, unsigned long mask)
1690
{
1691
        int err = 0;
1692

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

1701
        return err;
1702
}
1703
#endif
1704
#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1705

    
1706
static void setup_frame(int sig, struct target_sigaction *ka,
1707
                        target_sigset_t *set, CPUState *env)
1708
{
1709
        abi_ulong sf_addr;
1710
        struct target_signal_frame *sf;
1711
        int sigframe_size, err, i;
1712

    
1713
        /* 1. Make sure everything is clean */
1714
        //synchronize_user_stack();
1715

    
1716
        sigframe_size = NF_ALIGNEDSZ;
1717
        sf_addr = get_sigframe(ka, env, sigframe_size);
1718

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

    
1733
        //err |= save_fpu_state(regs, &sf->fpu_state);
1734
        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1735

    
1736
        err |= __put_user(set->sig[0], &sf->info.si_mask);
1737
        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1738
                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1739
        }
1740

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

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

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

    
1767
                env->regwptr[UREG_I7] = sf_addr + 
1768
                        offsetof(struct target_signal_frame, insns) - 2 * 4;
1769

    
1770
                /* mov __NR_sigreturn, %g1 */
1771
                val32 = 0x821020d8;
1772
                err |= __put_user(val32, &sf->insns[0]);
1773

    
1774
                /* t 0x10 */
1775
                val32 = 0x91d02010;
1776
                err |= __put_user(val32, &sf->insns[1]);
1777
                if (err)
1778
                        goto sigsegv;
1779

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

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

    
1834

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

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

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

    
1861
        /* 1. Make sure we are not getting garbage from the user */
1862

    
1863
        if (sf_addr & 3)
1864
                goto segv_and_exit;
1865

    
1866
        err = __get_user(pc,  &sf->info.si_regs.pc);
1867
        err |= __get_user(npc, &sf->info.si_regs.npc);
1868

    
1869
        if ((pc | npc) & 3)
1870
                goto segv_and_exit;
1871

    
1872
        /* 2. Restore the state */
1873
        err |= __get_user(up_psr, &sf->info.si_regs.psr);
1874

    
1875
        /* User can only change condition codes and FPU enabling in %psr. */
1876
        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1877
                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1878

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

    
1889
        err |= __get_user(fpu_save_addr, &sf->fpu_save);
1890

    
1891
        //if (fpu_save)
1892
        //        err |= restore_fpu_state(env, fpu_save);
1893

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

    
1902
        target_to_host_sigset_internal(&host_set, &set);
1903
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1904

    
1905
        if (err)
1906
                goto segv_and_exit;
1907
        unlock_user_struct(sf, sf_addr, 0);
1908
        return env->regwptr[0];
1909

    
1910
segv_and_exit:
1911
        unlock_user_struct(sf, sf_addr, 0);
1912
        force_sig(TARGET_SIGSEGV);
1913
}
1914

    
1915
long do_rt_sigreturn(CPUState *env)
1916
{
1917
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1918
    return -TARGET_ENOSYS;
1919
}
1920

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

    
1943
typedef abi_ulong target_mc_greg_t;
1944
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1945

    
1946
struct target_mc_fq {
1947
    abi_ulong *mcfq_addr;
1948
    uint32_t mcfq_insn;
1949
};
1950

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

    
1967
typedef struct {
1968
    target_mc_gregset_t mc_gregs;
1969
    target_mc_greg_t mc_fp;
1970
    target_mc_greg_t mc_i7;
1971
    target_mc_fpu_t mc_fpregs;
1972
} target_mcontext_t;
1973

    
1974
struct target_ucontext {
1975
    struct target_ucontext *uc_link;
1976
    abi_ulong uc_flags;
1977
    target_sigset_t uc_sigmask;
1978
    target_mcontext_t uc_mcontext;
1979
};
1980

    
1981
/* A V9 register window */
1982
struct target_reg_window {
1983
    abi_ulong locals[8];
1984
    abi_ulong ins[8];
1985
};
1986

    
1987
#define TARGET_STACK_BIAS 2047
1988

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

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

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

    
2052
    err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2053
    err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2054

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

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

    
2097
    ucp_addr = env->regwptr[UREG_I0];
2098
    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2099
        goto do_sigsegv;
2100
    
2101
    mcp = &ucp->uc_mcontext;
2102
    grp = &mcp->mc_gregs;
2103

    
2104
    /* Skip over the trap instruction, first. */
2105
    env->pc = env->npc;
2106
    env->npc += 4;
2107

    
2108
    err = 0;
2109

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

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

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

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

    
2170
    if (err)
2171
        goto do_sigsegv;
2172
    unlock_user_struct(ucp, ucp_addr, 1);
2173
    return;
2174
 do_sigsegv:
2175
    unlock_user_struct(ucp, ucp_addr, 1);
2176
    force_sig(SIGSEGV);
2177
}
2178
#endif
2179
#elif defined(TARGET_ABI_MIPSN64)
2180

    
2181
# warning signal handling not implemented
2182

    
2183
static void setup_frame(int sig, struct target_sigaction *ka,
2184
                        target_sigset_t *set, CPUState *env)
2185
{
2186
    fprintf(stderr, "setup_frame: not implemented\n");
2187
}
2188

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

    
2196
long do_sigreturn(CPUState *env)
2197
{
2198
    fprintf(stderr, "do_sigreturn: not implemented\n");
2199
    return -TARGET_ENOSYS;
2200
}
2201

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

    
2208
#elif defined(TARGET_ABI_MIPSN32)
2209

    
2210
# warning signal handling not implemented
2211

    
2212
static void setup_frame(int sig, struct target_sigaction *ka,
2213
                        target_sigset_t *set, CPUState *env)
2214
{
2215
    fprintf(stderr, "setup_frame: not implemented\n");
2216
}
2217

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

    
2225
long do_sigreturn(CPUState *env)
2226
{
2227
    fprintf(stderr, "do_sigreturn: not implemented\n");
2228
    return -TARGET_ENOSYS;
2229
}
2230

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

    
2237
#elif defined(TARGET_ABI_MIPSO32)
2238

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

    
2260
struct sigframe {
2261
    uint32_t sf_ass[4];                        /* argument save space for o32 */
2262
    uint32_t sf_code[2];                        /* signal trampoline */
2263
    struct target_sigcontext sf_sc;
2264
    target_sigset_t sf_mask;
2265
};
2266

    
2267
/* Install trampoline to jump back from signal handler */
2268
static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2269
{
2270
    int err;
2271

    
2272
    /*
2273
    * Set up the return code ...
2274
    *
2275
    *         li      v0, __NR__foo_sigreturn
2276
    *         syscall
2277
    */
2278

    
2279
    err = __put_user(0x24020000 + syscall, tramp + 0);
2280
    err |= __put_user(0x0000000c          , tramp + 1);
2281
    /* flush_cache_sigtramp((unsigned long) tramp); */
2282
    return err;
2283
}
2284

    
2285
static inline int
2286
setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2287
{
2288
    int err = 0;
2289

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

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

    
2306
    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2307
    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2308

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

    
2336
#if 0
2337
    err |= __put_user(!!used_math(), &sc->sc_used_math);
2338

2339
    if (!used_math())
2340
        goto out;
2341

2342
    /*
2343
    * Save FPU state to signal context.  Signal handler will "inherit"
2344
    * current FPU state.
2345
    */
2346
    preempt_disable();
2347

2348
    if (!is_fpu_owner()) {
2349
        own_fpu();
2350
        restore_fp(current);
2351
    }
2352
    err |= save_fp_context(sc);
2353

2354
    preempt_enable();
2355
    out:
2356
#endif
2357
    return err;
2358
}
2359

    
2360
static inline int
2361
restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2362
{
2363
    int err = 0;
2364

    
2365
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2366

    
2367
    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2368
    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2369

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

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

    
2410
    err |= __get_user(used_math, &sc->sc_used_math);
2411
    conditional_used_math(used_math);
2412

    
2413
    preempt_disable();
2414

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

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

    
2436
    /* Default to using normal stack */
2437
    sp = regs->active_tc.gpr[29];
2438

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

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

    
2451
    return (sp - frame_size) & ~7;
2452
}
2453

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

    
2462
    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2463
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2464
        goto give_sigsegv;
2465

    
2466
    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2467

    
2468
    if(setup_sigcontext(regs, &frame->sf_sc))
2469
        goto give_sigsegv;
2470

    
2471
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2472
        if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2473
            goto give_sigsegv;
2474
    }
2475

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

    
2498
give_sigsegv:
2499
    unlock_user_struct(frame, frame_addr, 1);
2500
    force_sig(TARGET_SIGSEGV/*, current*/);
2501
    return;
2502
}
2503

    
2504
long do_sigreturn(CPUState *regs)
2505
{
2506
    struct sigframe *frame;
2507
    abi_ulong frame_addr;
2508
    sigset_t blocked;
2509
    target_sigset_t target_set;
2510
    int i;
2511

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

    
2519
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2520
           if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2521
            goto badframe;
2522
    }
2523

    
2524
    target_to_host_sigset_internal(&blocked, &target_set);
2525
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2526

    
2527
    if (restore_sigcontext(regs, &frame->sf_sc))
2528
           goto badframe;
2529

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

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

    
2548
badframe:
2549
    force_sig(TARGET_SIGSEGV/*, current*/);
2550
    return 0;
2551
}
2552

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

    
2560
long do_rt_sigreturn(CPUState *env)
2561
{
2562
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2563
    return -TARGET_ENOSYS;
2564
}
2565

    
2566
#elif defined(TARGET_SH4)
2567

    
2568
/*
2569
 * code and data structures from linux kernel:
2570
 * include/asm-sh/sigcontext.h
2571
 * arch/sh/kernel/signal.c
2572
 */
2573

    
2574
struct target_sigcontext {
2575
    target_ulong  oldmask;
2576

    
2577
    /* CPU registers */
2578
    target_ulong  sc_gregs[16];
2579
    target_ulong  sc_pc;
2580
    target_ulong  sc_pr;
2581
    target_ulong  sc_sr;
2582
    target_ulong  sc_gbr;
2583
    target_ulong  sc_mach;
2584
    target_ulong  sc_macl;
2585

    
2586
    /* FPU registers */
2587
    target_ulong  sc_fpregs[16];
2588
    target_ulong  sc_xfpregs[16];
2589
    unsigned int sc_fpscr;
2590
    unsigned int sc_fpul;
2591
    unsigned int sc_ownedfp;
2592
};
2593

    
2594
struct target_sigframe
2595
{
2596
    struct target_sigcontext sc;
2597
    target_ulong extramask[TARGET_NSIG_WORDS-1];
2598
    uint16_t retcode[3];
2599
};
2600

    
2601

    
2602
struct target_ucontext {
2603
    target_ulong uc_flags;
2604
    struct target_ucontext *uc_link;
2605
    target_stack_t uc_stack;
2606
    struct target_sigcontext uc_mcontext;
2607
    target_sigset_t uc_sigmask;        /* mask last for extensibility */
2608
};
2609

    
2610
struct target_rt_sigframe
2611
{
2612
    struct target_siginfo info;
2613
    struct target_ucontext uc;
2614
    uint16_t retcode[3];
2615
};
2616

    
2617

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

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

    
2628
    return (sp - frame_size) & -8ul;
2629
}
2630

    
2631
static int setup_sigcontext(struct target_sigcontext *sc,
2632
                            CPUState *regs, unsigned long mask)
2633
{
2634
    int err = 0;
2635

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

    
2650
    /* todo: save FPU registers here */
2651

    
2652
    /* non-iBCS2 extensions.. */
2653
    err |= __put_user(mask, &sc->oldmask);
2654

    
2655
    return err;
2656
}
2657

    
2658
static int restore_sigcontext(struct CPUState *regs,
2659
                              struct target_sigcontext *sc)
2660
{
2661
    unsigned int err = 0;
2662

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

    
2677
    /* todo: restore FPU registers here */
2678

    
2679
    regs->tra = -1;         /* disable syscall checks */
2680
    return err;
2681
}
2682

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

    
2692
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2693
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2694
        goto give_sigsegv;
2695

    
2696
    signal = current_exec_domain_sig(sig);
2697

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

    
2700
    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2701
        err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2702
    }
2703

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

    
2716
    if (err)
2717
        goto give_sigsegv;
2718

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

    
2726
    unlock_user_struct(frame, frame_addr, 1);
2727
    return;
2728

    
2729
give_sigsegv:
2730
    unlock_user_struct(frame, frame_addr, 1);
2731
    force_sig(SIGSEGV);
2732
}
2733

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

    
2744
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2745
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2746
        goto give_sigsegv;
2747

    
2748
    signal = current_exec_domain_sig(sig);
2749

    
2750
    err |= copy_siginfo_to_user(&frame->info, info);
2751

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

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

    
2779
    if (err)
2780
        goto give_sigsegv;
2781

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

    
2789
    unlock_user_struct(frame, frame_addr, 1);
2790
    return;
2791

    
2792
give_sigsegv:
2793
    unlock_user_struct(frame, frame_addr, 1);
2794
    force_sig(SIGSEGV);
2795
}
2796

    
2797
long do_sigreturn(CPUState *regs)
2798
{
2799
    struct target_sigframe *frame;
2800
    abi_ulong frame_addr;
2801
    sigset_t blocked;
2802
    target_sigset_t target_set;
2803
    int i;
2804
    int err = 0;
2805

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

    
2813
    err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2814
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2815
        err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2816
    }
2817

    
2818
    if (err)
2819
        goto badframe;
2820

    
2821
    target_to_host_sigset_internal(&blocked, &target_set);
2822
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2823

    
2824
    if (restore_sigcontext(regs, &frame->sc))
2825
        goto badframe;
2826

    
2827
    unlock_user_struct(frame, frame_addr, 0);
2828
    return regs->gregs[0];
2829

    
2830
badframe:
2831
    unlock_user_struct(frame, frame_addr, 0);
2832
    force_sig(TARGET_SIGSEGV);
2833
    return 0;
2834
}
2835

    
2836
long do_rt_sigreturn(CPUState *regs)
2837
{
2838
    struct target_rt_sigframe *frame;
2839
    abi_ulong frame_addr;
2840
    sigset_t blocked;
2841

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

    
2849
    target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2850
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2851

    
2852
    if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2853
        goto badframe;
2854

    
2855
    if (do_sigaltstack(frame_addr +
2856
                       offsetof(struct target_rt_sigframe, uc.uc_stack),
2857
                       0, get_sp_from_cpustate(regs)) == -EFAULT)
2858
        goto badframe;
2859

    
2860
    unlock_user_struct(frame, frame_addr, 0);
2861
    return regs->gregs[0];
2862

    
2863
badframe:
2864
    unlock_user_struct(frame, frame_addr, 0);
2865
    force_sig(TARGET_SIGSEGV);
2866
    return 0;
2867
}
2868
#elif defined(TARGET_CRIS)
2869

    
2870
struct target_sigcontext {
2871
        struct target_pt_regs regs;  /* needs to be first */
2872
        uint32_t oldmask;
2873
        uint32_t usp;    /* usp before stacking this gunk on it */
2874
};
2875

    
2876
/* Signal frames. */
2877
struct target_signal_frame {
2878
        struct target_sigcontext sc;
2879
        uint32_t extramask[TARGET_NSIG_WORDS - 1];
2880
        uint8_t retcode[8];       /* Trampoline code. */
2881
};
2882

    
2883
struct rt_signal_frame {
2884
        struct siginfo *pinfo;
2885
        void *puc;
2886
        struct siginfo info;
2887
        struct ucontext uc;
2888
        uint8_t retcode[8];       /* Trampoline code. */
2889
};
2890

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

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

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

    
2945
static void setup_frame(int sig, struct target_sigaction *ka,
2946
                        target_sigset_t *set, CPUState *env)
2947
{
2948
        struct target_signal_frame *frame;
2949
        abi_ulong frame_addr;
2950
        int err = 0;
2951
        int i;
2952

    
2953
        frame_addr = get_sigframe(env, sizeof *frame);
2954
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2955
                goto badframe;
2956

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

    
2969
        /* Save the mask.  */
2970
        err |= __put_user(set->sig[0], &frame->sc.oldmask);
2971
        if (err)
2972
                goto badframe;
2973

    
2974
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2975
                if (__put_user(set->sig[i], &frame->extramask[i - 1]))
2976
                        goto badframe;
2977
        }
2978

    
2979
        setup_sigcontext(&frame->sc, env);
2980

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

    
2988
        unlock_user_struct(frame, frame_addr, 1);
2989
        return;
2990
  badframe:
2991
        unlock_user_struct(frame, frame_addr, 1);
2992
        force_sig(TARGET_SIGSEGV);
2993
}
2994

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

    
3002
long do_sigreturn(CPUState *env)
3003
{
3004
        struct target_signal_frame *frame;
3005
        abi_ulong frame_addr;
3006
        target_sigset_t target_set;
3007
        sigset_t set;
3008
        int i;
3009

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

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

    
3025
        restore_sigcontext(&frame->sc, env);
3026
        /* Compensate for the syscall return path advancing brk.  */
3027
        env->pc -= 2;
3028

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

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

    
3042
#else
3043

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

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

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

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

    
3069
#endif
3070

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

    
3082
    if (!ts->signal_pending)
3083
        return;
3084

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

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

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

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

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

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