Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 1d9d8b55

History | View | Annotate | Download (92.5 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., 51 Franklin Street - Fifth Floor, Boston,
19
 *  MA 02110-1301, USA.
20
 */
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <stdarg.h>
25
#include <unistd.h>
26
#include <signal.h>
27
#include <errno.h>
28
#include <assert.h>
29
#include <sys/ucontext.h>
30

    
31
#include "qemu.h"
32
#include "qemu-common.h"
33
#include "target_signal.h"
34

    
35
//#define DEBUG_SIGNAL
36

    
37
static struct target_sigaltstack target_sigaltstack_used = {
38
    .ss_sp = 0,
39
    .ss_size = 0,
40
    .ss_flags = TARGET_SS_DISABLE,
41
};
42

    
43
static struct target_sigaction sigact_table[TARGET_NSIG];
44

    
45
static void host_signal_handler(int host_signum, siginfo_t *info,
46
                                void *puc);
47

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

    
93
static inline int on_sig_stack(unsigned long sp)
94
{
95
    return (sp - target_sigaltstack_used.ss_sp
96
            < target_sigaltstack_used.ss_size);
97
}
98

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

    
105
int host_to_target_signal(int sig)
106
{
107
    if (sig > 64)
108
        return sig;
109
    return host_to_target_signal_table[sig];
110
}
111

    
112
int target_to_host_signal(int sig)
113
{
114
    if (sig > 64)
115
        return sig;
116
    return target_to_host_signal_table[sig];
117
}
118

    
119
static inline void target_sigemptyset(target_sigset_t *set)
120
{
121
    memset(set, 0, sizeof(*set));
122
}
123

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

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

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

    
150
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
151
{
152
    target_sigset_t d1;
153
    int i;
154

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

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

    
172
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
173
{
174
    target_sigset_t s1;
175
    int i;
176

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

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

    
190
void target_to_host_old_sigset(sigset_t *sigset,
191
                               const abi_ulong *old_sigset)
192
{
193
    target_sigset_t d;
194
    int i;
195

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

    
202
/* siginfo conversion */
203

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

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

    
250

    
251
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
252
{
253
    host_to_target_siginfo_noswap(tinfo, info);
254
    tswap_siginfo(tinfo, tinfo);
255
}
256

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

    
270
static int fatal_signal (int sig)
271
{
272
    switch (sig) {
273
    case TARGET_SIGCHLD:
274
    case TARGET_SIGURG:
275
    case TARGET_SIGWINCH:
276
        /* Ignored by default.  */
277
        return 0;
278
    case TARGET_SIGCONT:
279
    case TARGET_SIGSTOP:
280
    case TARGET_SIGTSTP:
281
    case TARGET_SIGTTIN:
282
    case TARGET_SIGTTOU:
283
        /* Job control signals.  */
284
        return 0;
285
    default:
286
        return 1;
287
    }
288
}
289

    
290
void signal_init(void)
291
{
292
    struct sigaction act;
293
    struct sigaction oact;
294
    int i, j;
295
    int host_sig;
296

    
297
    /* generate signal conversion tables */
298
    for(i = 1; i <= 64; i++) {
299
        if (host_to_target_signal_table[i] == 0)
300
            host_to_target_signal_table[i] = i;
301
    }
302
    for(i = 1; i <= 64; i++) {
303
        j = host_to_target_signal_table[i];
304
        target_to_host_signal_table[j] = i;
305
    }
306

    
307
    /* set all host signal handlers. ALL signals are blocked during
308
       the handlers to serialize them. */
309
    memset(sigact_table, 0, sizeof(sigact_table));
310

    
311
    sigfillset(&act.sa_mask);
312
    act.sa_flags = SA_SIGINFO;
313
    act.sa_sigaction = host_signal_handler;
314
    for(i = 1; i <= TARGET_NSIG; i++) {
315
        host_sig = target_to_host_signal(i);
316
        sigaction(host_sig, NULL, &oact);
317
        if (oact.sa_sigaction == (void *)SIG_IGN) {
318
            sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
319
        } else if (oact.sa_sigaction == (void *)SIG_DFL) {
320
            sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
321
        }
322
        /* If there's already a handler installed then something has
323
           gone horribly wrong, so don't even try to handle that case.  */
324
        /* Install some handlers for our own use.  We need at least
325
           SIGSEGV and SIGBUS, to detect exceptions.  We can not just
326
           trap all signals because it affects syscall interrupt
327
           behavior.  But do trap all default-fatal signals.  */
328
        if (fatal_signal (i))
329
            sigaction(host_sig, &act, NULL);
330
    }
331
}
332

    
333
/* signal queue handling */
334

    
335
static inline struct sigqueue *alloc_sigqueue(CPUState *env)
336
{
337
    TaskState *ts = env->opaque;
338
    struct sigqueue *q = ts->first_free;
339
    if (!q)
340
        return NULL;
341
    ts->first_free = q->next;
342
    return q;
343
}
344

    
345
static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
346
{
347
    TaskState *ts = env->opaque;
348
    q->next = ts->first_free;
349
    ts->first_free = q;
350
}
351

    
352
/* abort execution with signal */
353
static void QEMU_NORETURN force_sig(int sig)
354
{
355
    int host_sig;
356
    struct sigaction act;
357
    host_sig = target_to_host_signal(sig);
358
    fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
359
            sig, strsignal(host_sig));
360
    gdb_signalled(thread_env, sig);
361

    
362
    /* The proper exit code for dieing from an uncaught signal is
363
     * -<signal>.  The kernel doesn't allow exit() or _exit() to pass
364
     * a negative value.  To get the proper exit code we need to
365
     * actually die from an uncaught signal.  Here the default signal
366
     * handler is installed, we send ourself a signal and we wait for
367
     * it to arrive. */
368
    sigfillset(&act.sa_mask);
369
    act.sa_handler = SIG_DFL;
370
    sigaction(host_sig, &act, NULL);
371

    
372
    /* For some reason raise(host_sig) doesn't send the signal when
373
     * statically linked on x86-64. */
374
    kill(getpid(), host_sig);
375

    
376
    /* Make sure the signal isn't masked (just reuse the mask inside
377
    of act) */
378
    sigdelset(&act.sa_mask, host_sig);
379
    sigsuspend(&act.sa_mask);
380

    
381
    /* unreachable */
382
    assert(0);
383

    
384
}
385

    
386
/* queue a signal so that it will be send to the virtual CPU as soon
387
   as possible */
388
int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
389
{
390
    TaskState *ts = env->opaque;
391
    struct emulated_sigtable *k;
392
    struct sigqueue *q, **pq;
393
    abi_ulong handler;
394
    int queue;
395

    
396
#if defined(DEBUG_SIGNAL)
397
    fprintf(stderr, "queue_signal: sig=%d\n",
398
            sig);
399
#endif
400
    k = &ts->sigtab[sig - 1];
401
    queue = gdb_queuesig ();
402
    handler = sigact_table[sig - 1]._sa_handler;
403
    if (!queue && handler == TARGET_SIG_DFL) {
404
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
405
            kill(getpid(),SIGSTOP);
406
            return 0;
407
        } else
408
        /* default handler : ignore some signal. The other are fatal */
409
        if (sig != TARGET_SIGCHLD &&
410
            sig != TARGET_SIGURG &&
411
            sig != TARGET_SIGWINCH &&
412
            sig != TARGET_SIGCONT) {
413
            force_sig(sig);
414
        } else {
415
            return 0; /* indicate ignored */
416
        }
417
    } else if (!queue && handler == TARGET_SIG_IGN) {
418
        /* ignore signal */
419
        return 0;
420
    } else if (!queue && handler == TARGET_SIG_ERR) {
421
        force_sig(sig);
422
    } else {
423
        pq = &k->first;
424
        if (sig < TARGET_SIGRTMIN) {
425
            /* if non real time signal, we queue exactly one signal */
426
            if (!k->pending)
427
                q = &k->info;
428
            else
429
                return 0;
430
        } else {
431
            if (!k->pending) {
432
                /* first signal */
433
                q = &k->info;
434
            } else {
435
                q = alloc_sigqueue(env);
436
                if (!q)
437
                    return -EAGAIN;
438
                while (*pq != NULL)
439
                    pq = &(*pq)->next;
440
            }
441
        }
442
        *pq = q;
443
        q->info = *info;
444
        q->next = NULL;
445
        k->pending = 1;
446
        /* signal that a new signal is pending */
447
        ts->signal_pending = 1;
448
        return 1; /* indicates that the signal was queued */
449
    }
450
}
451

    
452
static void host_signal_handler(int host_signum, siginfo_t *info,
453
                                void *puc)
454
{
455
    int sig;
456
    target_siginfo_t tinfo;
457

    
458
    /* the CPU emulator uses some host signals to detect exceptions,
459
       we forward to it some signals */
460
    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
461
        && info->si_code > 0) {
462
        if (cpu_signal_handler(host_signum, info, puc))
463
            return;
464
    }
465

    
466
    /* get target signal number */
467
    sig = host_to_target_signal(host_signum);
468
    if (sig < 1 || sig > TARGET_NSIG)
469
        return;
470
#if defined(DEBUG_SIGNAL)
471
    fprintf(stderr, "qemu: got signal %d\n", sig);
472
#endif
473
    host_to_target_siginfo_noswap(&tinfo, info);
474
    if (queue_signal(thread_env, sig, &tinfo) == 1) {
475
        /* interrupt the virtual CPU as soon as possible */
476
        cpu_exit(thread_env);
477
    }
478
}
479

    
480
/* do_sigaltstack() returns target values and errnos. */
481
/* compare linux/kernel/signal.c:do_sigaltstack() */
482
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
483
{
484
    int ret;
485
    struct target_sigaltstack oss;
486

    
487
    /* XXX: test errors */
488
    if(uoss_addr)
489
    {
490
        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
491
        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
492
        __put_user(sas_ss_flags(sp), &oss.ss_flags);
493
    }
494

    
495
    if(uss_addr)
496
    {
497
        struct target_sigaltstack *uss;
498
        struct target_sigaltstack ss;
499

    
500
        ret = -TARGET_EFAULT;
501
        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
502
            || __get_user(ss.ss_sp, &uss->ss_sp)
503
            || __get_user(ss.ss_size, &uss->ss_size)
504
            || __get_user(ss.ss_flags, &uss->ss_flags))
505
            goto out;
506
        unlock_user_struct(uss, uss_addr, 0);
507

    
508
        ret = -TARGET_EPERM;
509
        if (on_sig_stack(sp))
510
            goto out;
511

    
512
        ret = -TARGET_EINVAL;
513
        if (ss.ss_flags != TARGET_SS_DISABLE
514
            && ss.ss_flags != TARGET_SS_ONSTACK
515
            && ss.ss_flags != 0)
516
            goto out;
517

    
518
        if (ss.ss_flags == TARGET_SS_DISABLE) {
519
            ss.ss_size = 0;
520
            ss.ss_sp = 0;
521
        } else {
522
            ret = -TARGET_ENOMEM;
523
            if (ss.ss_size < MINSIGSTKSZ)
524
                goto out;
525
        }
526

    
527
        target_sigaltstack_used.ss_sp = ss.ss_sp;
528
        target_sigaltstack_used.ss_size = ss.ss_size;
529
    }
530

    
531
    if (uoss_addr) {
532
        ret = -TARGET_EFAULT;
533
        if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
534
            goto out;
535
    }
536

    
537
    ret = 0;
538
out:
539
    return ret;
540
}
541

    
542
/* do_sigaction() return host values and errnos */
543
int do_sigaction(int sig, const struct target_sigaction *act,
544
                 struct target_sigaction *oact)
545
{
546
    struct target_sigaction *k;
547
    struct sigaction act1;
548
    int host_sig;
549
    int ret = 0;
550

    
551
    if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
552
        return -EINVAL;
553
    k = &sigact_table[sig - 1];
554
#if defined(DEBUG_SIGNAL)
555
    fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
556
            sig, (int)act, (int)oact);
557
#endif
558
    if (oact) {
559
        oact->_sa_handler = tswapl(k->_sa_handler);
560
        oact->sa_flags = tswapl(k->sa_flags);
561
#if !defined(TARGET_MIPS)
562
        oact->sa_restorer = tswapl(k->sa_restorer);
563
#endif
564
        oact->sa_mask = k->sa_mask;
565
    }
566
    if (act) {
567
        /* FIXME: This is not threadsafe.  */
568
        k->_sa_handler = tswapl(act->_sa_handler);
569
        k->sa_flags = tswapl(act->sa_flags);
570
#if !defined(TARGET_MIPS)
571
        k->sa_restorer = tswapl(act->sa_restorer);
572
#endif
573
        k->sa_mask = act->sa_mask;
574

    
575
        /* we update the host linux signal state */
576
        host_sig = target_to_host_signal(sig);
577
        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
578
            sigfillset(&act1.sa_mask);
579
            act1.sa_flags = SA_SIGINFO;
580
            if (k->sa_flags & TARGET_SA_RESTART)
581
                act1.sa_flags |= SA_RESTART;
582
            /* NOTE: it is important to update the host kernel signal
583
               ignore state to avoid getting unexpected interrupted
584
               syscalls */
585
            if (k->_sa_handler == TARGET_SIG_IGN) {
586
                act1.sa_sigaction = (void *)SIG_IGN;
587
            } else if (k->_sa_handler == TARGET_SIG_DFL) {
588
                if (fatal_signal (sig))
589
                    act1.sa_sigaction = host_signal_handler;
590
                else
591
                    act1.sa_sigaction = (void *)SIG_DFL;
592
            } else {
593
                act1.sa_sigaction = host_signal_handler;
594
            }
595
            ret = sigaction(host_sig, &act1, NULL);
596
        }
597
    }
598
    return ret;
599
}
600

    
601
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
602
                                       const target_siginfo_t *info)
603
{
604
    tswap_siginfo(tinfo, info);
605
    return 0;
606
}
607

    
608
static inline int current_exec_domain_sig(int sig)
609
{
610
    return /* current->exec_domain && current->exec_domain->signal_invmap
611
              && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
612
}
613

    
614
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
615

    
616
/* from the Linux kernel */
617

    
618
struct target_fpreg {
619
        uint16_t significand[4];
620
        uint16_t exponent;
621
};
622

    
623
struct target_fpxreg {
624
        uint16_t significand[4];
625
        uint16_t exponent;
626
        uint16_t padding[3];
627
};
628

    
629
struct target_xmmreg {
630
        abi_ulong element[4];
631
};
632

    
633
struct target_fpstate {
634
        /* Regular FPU environment */
635
        abi_ulong       cw;
636
        abi_ulong       sw;
637
        abi_ulong       tag;
638
        abi_ulong       ipoff;
639
        abi_ulong       cssel;
640
        abi_ulong       dataoff;
641
        abi_ulong       datasel;
642
        struct target_fpreg        _st[8];
643
        uint16_t        status;
644
        uint16_t        magic;                /* 0xffff = regular FPU data only */
645

    
646
        /* FXSR FPU environment */
647
        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
648
        abi_ulong       mxcsr;
649
        abi_ulong       reserved;
650
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
651
        struct target_xmmreg        _xmm[8];
652
        abi_ulong       padding[56];
653
};
654

    
655
#define X86_FXSR_MAGIC                0x0000
656

    
657
struct target_sigcontext {
658
        uint16_t gs, __gsh;
659
        uint16_t fs, __fsh;
660
        uint16_t es, __esh;
661
        uint16_t ds, __dsh;
662
        abi_ulong edi;
663
        abi_ulong esi;
664
        abi_ulong ebp;
665
        abi_ulong esp;
666
        abi_ulong ebx;
667
        abi_ulong edx;
668
        abi_ulong ecx;
669
        abi_ulong eax;
670
        abi_ulong trapno;
671
        abi_ulong err;
672
        abi_ulong eip;
673
        uint16_t cs, __csh;
674
        abi_ulong eflags;
675
        abi_ulong esp_at_signal;
676
        uint16_t ss, __ssh;
677
        abi_ulong fpstate; /* pointer */
678
        abi_ulong oldmask;
679
        abi_ulong cr2;
680
};
681

    
682
struct target_ucontext {
683
        abi_ulong         tuc_flags;
684
        abi_ulong         tuc_link;
685
        target_stack_t          tuc_stack;
686
        struct target_sigcontext tuc_mcontext;
687
        target_sigset_t          tuc_sigmask;        /* mask last for extensibility */
688
};
689

    
690
struct sigframe
691
{
692
    abi_ulong pretcode;
693
    int sig;
694
    struct target_sigcontext sc;
695
    struct target_fpstate fpstate;
696
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
697
    char retcode[8];
698
};
699

    
700
struct rt_sigframe
701
{
702
    abi_ulong pretcode;
703
    int sig;
704
    abi_ulong pinfo;
705
    abi_ulong puc;
706
    struct target_siginfo info;
707
    struct target_ucontext uc;
708
    struct target_fpstate fpstate;
709
    char retcode[8];
710
};
711

    
712
/*
713
 * Set up a signal frame.
714
 */
715

    
716
/* XXX: save x87 state */
717
static int
718
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
719
                 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
720
{
721
        int err = 0;
722
        uint16_t magic;
723

    
724
        /* already locked in setup_frame() */
725
        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
726
        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
727
        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
728
        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
729
        err |= __put_user(env->regs[R_EDI], &sc->edi);
730
        err |= __put_user(env->regs[R_ESI], &sc->esi);
731
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
732
        err |= __put_user(env->regs[R_ESP], &sc->esp);
733
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
734
        err |= __put_user(env->regs[R_EDX], &sc->edx);
735
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
736
        err |= __put_user(env->regs[R_EAX], &sc->eax);
737
        err |= __put_user(env->exception_index, &sc->trapno);
738
        err |= __put_user(env->error_code, &sc->err);
739
        err |= __put_user(env->eip, &sc->eip);
740
        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
741
        err |= __put_user(env->eflags, &sc->eflags);
742
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
743
        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
744

    
745
        cpu_x86_fsave(env, fpstate_addr, 1);
746
        fpstate->status = fpstate->sw;
747
        magic = 0xffff;
748
        err |= __put_user(magic, &fpstate->magic);
749
        err |= __put_user(fpstate_addr, &sc->fpstate);
750

    
751
        /* non-iBCS2 extensions.. */
752
        err |= __put_user(mask, &sc->oldmask);
753
        err |= __put_user(env->cr[2], &sc->cr2);
754
        return err;
755
}
756

    
757
/*
758
 * Determine which stack to use..
759
 */
760

    
761
static inline abi_ulong
762
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
763
{
764
        unsigned long esp;
765

    
766
        /* Default to using normal stack */
767
        esp = env->regs[R_ESP];
768
        /* This is the X/Open sanctioned signal stack switching.  */
769
        if (ka->sa_flags & TARGET_SA_ONSTACK) {
770
            if (sas_ss_flags(esp) == 0)
771
                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
772
        }
773

    
774
        /* This is the legacy signal stack switching. */
775
        else
776
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
777
            !(ka->sa_flags & TARGET_SA_RESTORER) &&
778
            ka->sa_restorer) {
779
            esp = (unsigned long) ka->sa_restorer;
780
        }
781
        return (esp - frame_size) & -8ul;
782
}
783

    
784
/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
785
static void setup_frame(int sig, struct target_sigaction *ka,
786
                        target_sigset_t *set, CPUX86State *env)
787
{
788
        abi_ulong frame_addr;
789
        struct sigframe *frame;
790
        int i, err = 0;
791

    
792
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
793

    
794
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
795
                goto give_sigsegv;
796

    
797
        err |= __put_user(current_exec_domain_sig(sig),
798
                          &frame->sig);
799
        if (err)
800
                goto give_sigsegv;
801

    
802
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
803
                         frame_addr + offsetof(struct sigframe, fpstate));
804
        if (err)
805
                goto give_sigsegv;
806

    
807
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
808
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
809
                goto give_sigsegv;
810
        }
811

    
812
        /* Set up to return from userspace.  If provided, use a stub
813
           already in userspace.  */
814
        if (ka->sa_flags & TARGET_SA_RESTORER) {
815
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
816
        } else {
817
                uint16_t val16;
818
                abi_ulong retcode_addr;
819
                retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
820
                err |= __put_user(retcode_addr, &frame->pretcode);
821
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
822
                val16 = 0xb858;
823
                err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
824
                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
825
                val16 = 0x80cd;
826
                err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
827
        }
828

    
829
        if (err)
830
                goto give_sigsegv;
831

    
832
        /* Set up registers for signal handler */
833
        env->regs[R_ESP] = frame_addr;
834
        env->eip = ka->_sa_handler;
835

    
836
        cpu_x86_load_seg(env, R_DS, __USER_DS);
837
        cpu_x86_load_seg(env, R_ES, __USER_DS);
838
        cpu_x86_load_seg(env, R_SS, __USER_DS);
839
        cpu_x86_load_seg(env, R_CS, __USER_CS);
840
        env->eflags &= ~TF_MASK;
841

    
842
        unlock_user_struct(frame, frame_addr, 1);
843

    
844
        return;
845

    
846
give_sigsegv:
847
        unlock_user_struct(frame, frame_addr, 1);
848
        if (sig == TARGET_SIGSEGV)
849
                ka->_sa_handler = TARGET_SIG_DFL;
850
        force_sig(TARGET_SIGSEGV /* , current */);
851
}
852

    
853
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
854
static void setup_rt_frame(int sig, struct target_sigaction *ka,
855
                           target_siginfo_t *info,
856
                           target_sigset_t *set, CPUX86State *env)
857
{
858
        abi_ulong frame_addr, addr;
859
        struct rt_sigframe *frame;
860
        int i, err = 0;
861

    
862
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
863

    
864
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
865
                goto give_sigsegv;
866

    
867
        err |= __put_user(current_exec_domain_sig(sig),
868
                          &frame->sig);
869
        addr = frame_addr + offsetof(struct rt_sigframe, info);
870
        err |= __put_user(addr, &frame->pinfo);
871
        addr = frame_addr + offsetof(struct rt_sigframe, uc);
872
        err |= __put_user(addr, &frame->puc);
873
        err |= copy_siginfo_to_user(&frame->info, info);
874
        if (err)
875
                goto give_sigsegv;
876

    
877
        /* Create the ucontext.  */
878
        err |= __put_user(0, &frame->uc.tuc_flags);
879
        err |= __put_user(0, &frame->uc.tuc_link);
880
        err |= __put_user(target_sigaltstack_used.ss_sp,
881
                          &frame->uc.tuc_stack.ss_sp);
882
        err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
883
                          &frame->uc.tuc_stack.ss_flags);
884
        err |= __put_user(target_sigaltstack_used.ss_size,
885
                          &frame->uc.tuc_stack.ss_size);
886
        err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
887
                                env, set->sig[0], 
888
                                frame_addr + offsetof(struct rt_sigframe, fpstate));
889
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
890
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
891
                goto give_sigsegv;
892
        }
893

    
894
        /* Set up to return from userspace.  If provided, use a stub
895
           already in userspace.  */
896
        if (ka->sa_flags & TARGET_SA_RESTORER) {
897
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
898
        } else {
899
                uint16_t val16;
900
                addr = frame_addr + offsetof(struct rt_sigframe, retcode);
901
                err |= __put_user(addr, &frame->pretcode);
902
                /* This is movl $,%eax ; int $0x80 */
903
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
904
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
905
                val16 = 0x80cd;
906
                err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
907
        }
908

    
909
        if (err)
910
                goto give_sigsegv;
911

    
912
        /* Set up registers for signal handler */
913
        env->regs[R_ESP] = frame_addr;
914
        env->eip = ka->_sa_handler;
915

    
916
        cpu_x86_load_seg(env, R_DS, __USER_DS);
917
        cpu_x86_load_seg(env, R_ES, __USER_DS);
918
        cpu_x86_load_seg(env, R_SS, __USER_DS);
919
        cpu_x86_load_seg(env, R_CS, __USER_CS);
920
        env->eflags &= ~TF_MASK;
921

    
922
        unlock_user_struct(frame, frame_addr, 1);
923

    
924
        return;
925

    
926
give_sigsegv:
927
        unlock_user_struct(frame, frame_addr, 1);
928
        if (sig == TARGET_SIGSEGV)
929
                ka->_sa_handler = TARGET_SIG_DFL;
930
        force_sig(TARGET_SIGSEGV /* , current */);
931
}
932

    
933
static int
934
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
935
{
936
        unsigned int err = 0;
937
        abi_ulong fpstate_addr;
938
        unsigned int tmpflags;
939

    
940
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
941
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
942
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
943
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
944

    
945
        env->regs[R_EDI] = tswapl(sc->edi);
946
        env->regs[R_ESI] = tswapl(sc->esi);
947
        env->regs[R_EBP] = tswapl(sc->ebp);
948
        env->regs[R_ESP] = tswapl(sc->esp);
949
        env->regs[R_EBX] = tswapl(sc->ebx);
950
        env->regs[R_EDX] = tswapl(sc->edx);
951
        env->regs[R_ECX] = tswapl(sc->ecx);
952
        env->eip = tswapl(sc->eip);
953

    
954
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
955
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
956

    
957
        tmpflags = tswapl(sc->eflags);
958
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
959
        //                regs->orig_eax = -1;                /* disable syscall checks */
960

    
961
        fpstate_addr = tswapl(sc->fpstate);
962
        if (fpstate_addr != 0) {
963
                if (!access_ok(VERIFY_READ, fpstate_addr, 
964
                               sizeof(struct target_fpstate)))
965
                        goto badframe;
966
                cpu_x86_frstor(env, fpstate_addr, 1);
967
        }
968

    
969
        *peax = tswapl(sc->eax);
970
        return err;
971
badframe:
972
        return 1;
973
}
974

    
975
long do_sigreturn(CPUX86State *env)
976
{
977
    struct sigframe *frame;
978
    abi_ulong frame_addr = env->regs[R_ESP] - 8;
979
    target_sigset_t target_set;
980
    sigset_t set;
981
    int eax, i;
982

    
983
#if defined(DEBUG_SIGNAL)
984
    fprintf(stderr, "do_sigreturn\n");
985
#endif
986
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
987
        goto badframe;
988
    /* set blocked signals */
989
    if (__get_user(target_set.sig[0], &frame->sc.oldmask))
990
        goto badframe;
991
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
992
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
993
            goto badframe;
994
    }
995

    
996
    target_to_host_sigset_internal(&set, &target_set);
997
    sigprocmask(SIG_SETMASK, &set, NULL);
998

    
999
    /* restore registers */
1000
    if (restore_sigcontext(env, &frame->sc, &eax))
1001
        goto badframe;
1002
    unlock_user_struct(frame, frame_addr, 0);
1003
    return eax;
1004

    
1005
badframe:
1006
    unlock_user_struct(frame, frame_addr, 0);
1007
    force_sig(TARGET_SIGSEGV);
1008
    return 0;
1009
}
1010

    
1011
long do_rt_sigreturn(CPUX86State *env)
1012
{
1013
        abi_ulong frame_addr;
1014
        struct rt_sigframe *frame;
1015
        sigset_t set;
1016
        int eax;
1017

    
1018
        frame_addr = env->regs[R_ESP] - 4;
1019
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1020
                goto badframe;
1021
        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1022
        sigprocmask(SIG_SETMASK, &set, NULL);
1023

    
1024
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1025
                goto badframe;
1026

    
1027
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
1028
                           get_sp_from_cpustate(env)) == -EFAULT)
1029
                goto badframe;
1030

    
1031
        unlock_user_struct(frame, frame_addr, 0);
1032
        return eax;
1033

    
1034
badframe:
1035
        unlock_user_struct(frame, frame_addr, 0);
1036
        force_sig(TARGET_SIGSEGV);
1037
        return 0;
1038
}
1039

    
1040
#elif defined(TARGET_ARM)
1041

    
1042
struct target_sigcontext {
1043
        abi_ulong trap_no;
1044
        abi_ulong error_code;
1045
        abi_ulong oldmask;
1046
        abi_ulong arm_r0;
1047
        abi_ulong arm_r1;
1048
        abi_ulong arm_r2;
1049
        abi_ulong arm_r3;
1050
        abi_ulong arm_r4;
1051
        abi_ulong arm_r5;
1052
        abi_ulong arm_r6;
1053
        abi_ulong arm_r7;
1054
        abi_ulong arm_r8;
1055
        abi_ulong arm_r9;
1056
        abi_ulong arm_r10;
1057
        abi_ulong arm_fp;
1058
        abi_ulong arm_ip;
1059
        abi_ulong arm_sp;
1060
        abi_ulong arm_lr;
1061
        abi_ulong arm_pc;
1062
        abi_ulong arm_cpsr;
1063
        abi_ulong fault_address;
1064
};
1065

    
1066
struct target_ucontext_v1 {
1067
    abi_ulong tuc_flags;
1068
    abi_ulong tuc_link;
1069
    target_stack_t tuc_stack;
1070
    struct target_sigcontext tuc_mcontext;
1071
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1072
};
1073

    
1074
struct target_ucontext_v2 {
1075
    abi_ulong tuc_flags;
1076
    abi_ulong tuc_link;
1077
    target_stack_t tuc_stack;
1078
    struct target_sigcontext tuc_mcontext;
1079
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1080
    char __unused[128 - sizeof(sigset_t)];
1081
    abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1082
};
1083

    
1084
struct sigframe_v1
1085
{
1086
    struct target_sigcontext sc;
1087
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
1088
    abi_ulong retcode;
1089
};
1090

    
1091
struct sigframe_v2
1092
{
1093
    struct target_ucontext_v2 uc;
1094
    abi_ulong retcode;
1095
};
1096

    
1097
struct rt_sigframe_v1
1098
{
1099
    abi_ulong pinfo;
1100
    abi_ulong puc;
1101
    struct target_siginfo info;
1102
    struct target_ucontext_v1 uc;
1103
    abi_ulong retcode;
1104
};
1105

    
1106
struct rt_sigframe_v2
1107
{
1108
    struct target_siginfo info;
1109
    struct target_ucontext_v2 uc;
1110
    abi_ulong retcode;
1111
};
1112

    
1113
#define TARGET_CONFIG_CPU_32 1
1114

    
1115
/*
1116
 * For ARM syscalls, we encode the syscall number into the instruction.
1117
 */
1118
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1119
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1120

    
1121
/*
1122
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
1123
 * need two 16-bit instructions.
1124
 */
1125
#define SWI_THUMB_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1126
#define SWI_THUMB_RT_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1127

    
1128
static const abi_ulong retcodes[4] = {
1129
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
1130
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
1131
};
1132

    
1133

    
1134
#define __get_user_error(x,p,e) __get_user(x, p)
1135

    
1136
static inline int valid_user_regs(CPUState *regs)
1137
{
1138
    return 1;
1139
}
1140

    
1141
static void
1142
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1143
                 CPUState *env, abi_ulong mask)
1144
{
1145
        __put_user(env->regs[0], &sc->arm_r0);
1146
        __put_user(env->regs[1], &sc->arm_r1);
1147
        __put_user(env->regs[2], &sc->arm_r2);
1148
        __put_user(env->regs[3], &sc->arm_r3);
1149
        __put_user(env->regs[4], &sc->arm_r4);
1150
        __put_user(env->regs[5], &sc->arm_r5);
1151
        __put_user(env->regs[6], &sc->arm_r6);
1152
        __put_user(env->regs[7], &sc->arm_r7);
1153
        __put_user(env->regs[8], &sc->arm_r8);
1154
        __put_user(env->regs[9], &sc->arm_r9);
1155
        __put_user(env->regs[10], &sc->arm_r10);
1156
        __put_user(env->regs[11], &sc->arm_fp);
1157
        __put_user(env->regs[12], &sc->arm_ip);
1158
        __put_user(env->regs[13], &sc->arm_sp);
1159
        __put_user(env->regs[14], &sc->arm_lr);
1160
        __put_user(env->regs[15], &sc->arm_pc);
1161
#ifdef TARGET_CONFIG_CPU_32
1162
        __put_user(cpsr_read(env), &sc->arm_cpsr);
1163
#endif
1164

    
1165
        __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1166
        __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1167
        __put_user(/* current->thread.address */ 0, &sc->fault_address);
1168
        __put_user(mask, &sc->oldmask);
1169
}
1170

    
1171
static inline abi_ulong
1172
get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1173
{
1174
        unsigned long sp = regs->regs[13];
1175

    
1176
        /*
1177
         * This is the X/Open sanctioned signal stack switching.
1178
         */
1179
        if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1180
            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1181
        /*
1182
         * ATPCS B01 mandates 8-byte alignment
1183
         */
1184
        return (sp - framesize) & ~7;
1185
}
1186

    
1187
static int
1188
setup_return(CPUState *env, struct target_sigaction *ka,
1189
             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1190
{
1191
        abi_ulong handler = ka->_sa_handler;
1192
        abi_ulong retcode;
1193
        int thumb = handler & 1;
1194

    
1195
        if (ka->sa_flags & TARGET_SA_RESTORER) {
1196
                retcode = ka->sa_restorer;
1197
        } else {
1198
                unsigned int idx = thumb;
1199

    
1200
                if (ka->sa_flags & TARGET_SA_SIGINFO)
1201
                        idx += 2;
1202

    
1203
                if (__put_user(retcodes[idx], rc))
1204
                        return 1;
1205
#if 0
1206
                flush_icache_range((abi_ulong)rc,
1207
                                   (abi_ulong)(rc + 1));
1208
#endif
1209
                retcode = rc_addr + thumb;
1210
        }
1211

    
1212
        env->regs[0] = usig;
1213
        env->regs[13] = frame_addr;
1214
        env->regs[14] = retcode;
1215
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1216
        env->thumb = thumb;
1217

    
1218
#if 0
1219
#ifdef TARGET_CONFIG_CPU_32
1220
        env->cpsr = cpsr;
1221
#endif
1222
#endif
1223

    
1224
        return 0;
1225
}
1226

    
1227
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1228
                              target_sigset_t *set, CPUState *env)
1229
{
1230
    struct target_sigaltstack stack;
1231
    int i;
1232

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

    
1236
    memset(&stack, 0, sizeof(stack));
1237
    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1238
    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1239
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1240
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1241

    
1242
    setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1243
    /* FIXME: Save coprocessor signal frame.  */
1244
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1245
        __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1246
    }
1247
}
1248

    
1249
/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1250
static void setup_frame_v1(int usig, struct target_sigaction *ka,
1251
                           target_sigset_t *set, CPUState *regs)
1252
{
1253
        struct sigframe_v1 *frame;
1254
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1255
        int i;
1256

    
1257
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1258
                return;
1259

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

    
1262
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1263
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1264
                goto end;
1265
        }
1266

    
1267
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1268
                     frame_addr + offsetof(struct sigframe_v1, retcode));
1269

    
1270
end:
1271
        unlock_user_struct(frame, frame_addr, 1);
1272
}
1273

    
1274
static void setup_frame_v2(int usig, struct target_sigaction *ka,
1275
                           target_sigset_t *set, CPUState *regs)
1276
{
1277
        struct sigframe_v2 *frame;
1278
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1279

    
1280
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1281
                return;
1282

    
1283
        setup_sigframe_v2(&frame->uc, set, regs);
1284

    
1285
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1286
                     frame_addr + offsetof(struct sigframe_v2, retcode));
1287

    
1288
        unlock_user_struct(frame, frame_addr, 1);
1289
}
1290

    
1291
static void setup_frame(int usig, struct target_sigaction *ka,
1292
                        target_sigset_t *set, CPUState *regs)
1293
{
1294
    if (get_osversion() >= 0x020612) {
1295
        setup_frame_v2(usig, ka, set, regs);
1296
    } else {
1297
        setup_frame_v1(usig, ka, set, regs);
1298
    }
1299
}
1300

    
1301
/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1302
static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1303
                              target_siginfo_t *info,
1304
                              target_sigset_t *set, CPUState *env)
1305
{
1306
        struct rt_sigframe_v1 *frame;
1307
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1308
        struct target_sigaltstack stack;
1309
        int i;
1310
        abi_ulong info_addr, uc_addr;
1311

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

    
1315
        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1316
        __put_user(info_addr, &frame->pinfo);
1317
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1318
        __put_user(uc_addr, &frame->puc);
1319
        copy_siginfo_to_user(&frame->info, info);
1320

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

    
1324
        memset(&stack, 0, sizeof(stack));
1325
        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1326
        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1327
        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1328
        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1329

    
1330
        setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1331
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1332
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1333
                goto end;
1334
        }
1335

    
1336
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1337
                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1338

    
1339
        env->regs[1] = info_addr;
1340
        env->regs[2] = uc_addr;
1341

    
1342
end:
1343
        unlock_user_struct(frame, frame_addr, 1);
1344
}
1345

    
1346
static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1347
                              target_siginfo_t *info,
1348
                              target_sigset_t *set, CPUState *env)
1349
{
1350
        struct rt_sigframe_v2 *frame;
1351
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1352
        abi_ulong info_addr, uc_addr;
1353

    
1354
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1355
            return /* 1 */;
1356

    
1357
        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1358
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1359
        copy_siginfo_to_user(&frame->info, info);
1360

    
1361
        setup_sigframe_v2(&frame->uc, set, env);
1362

    
1363
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1364
                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1365

    
1366
        env->regs[1] = info_addr;
1367
        env->regs[2] = uc_addr;
1368

    
1369
        unlock_user_struct(frame, frame_addr, 1);
1370
}
1371

    
1372
static void setup_rt_frame(int usig, struct target_sigaction *ka,
1373
                           target_siginfo_t *info,
1374
                           target_sigset_t *set, CPUState *env)
1375
{
1376
    if (get_osversion() >= 0x020612) {
1377
        setup_rt_frame_v2(usig, ka, info, set, env);
1378
    } else {
1379
        setup_rt_frame_v1(usig, ka, info, set, env);
1380
    }
1381
}
1382

    
1383
static int
1384
restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1385
{
1386
        int err = 0;
1387
        uint32_t cpsr;
1388

    
1389
        __get_user_error(env->regs[0], &sc->arm_r0, err);
1390
        __get_user_error(env->regs[1], &sc->arm_r1, err);
1391
        __get_user_error(env->regs[2], &sc->arm_r2, err);
1392
        __get_user_error(env->regs[3], &sc->arm_r3, err);
1393
        __get_user_error(env->regs[4], &sc->arm_r4, err);
1394
        __get_user_error(env->regs[5], &sc->arm_r5, err);
1395
        __get_user_error(env->regs[6], &sc->arm_r6, err);
1396
        __get_user_error(env->regs[7], &sc->arm_r7, err);
1397
        __get_user_error(env->regs[8], &sc->arm_r8, err);
1398
        __get_user_error(env->regs[9], &sc->arm_r9, err);
1399
        __get_user_error(env->regs[10], &sc->arm_r10, err);
1400
        __get_user_error(env->regs[11], &sc->arm_fp, err);
1401
        __get_user_error(env->regs[12], &sc->arm_ip, err);
1402
        __get_user_error(env->regs[13], &sc->arm_sp, err);
1403
        __get_user_error(env->regs[14], &sc->arm_lr, err);
1404
        __get_user_error(env->regs[15], &sc->arm_pc, err);
1405
#ifdef TARGET_CONFIG_CPU_32
1406
        __get_user_error(cpsr, &sc->arm_cpsr, err);
1407
        cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1408
#endif
1409

    
1410
        err |= !valid_user_regs(env);
1411

    
1412
        return err;
1413
}
1414

    
1415
static long do_sigreturn_v1(CPUState *env)
1416
{
1417
        abi_ulong frame_addr;
1418
        struct sigframe_v1 *frame;
1419
        target_sigset_t set;
1420
        sigset_t host_set;
1421
        int i;
1422

    
1423
        /*
1424
         * Since we stacked the signal on a 64-bit boundary,
1425
         * then 'sp' should be word aligned here.  If it's
1426
         * not, then the user is trying to mess with us.
1427
         */
1428
        if (env->regs[13] & 7)
1429
                goto badframe;
1430

    
1431
        frame_addr = env->regs[13];
1432
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1433
                goto badframe;
1434

    
1435
        if (__get_user(set.sig[0], &frame->sc.oldmask))
1436
            goto badframe;
1437
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1438
            if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1439
                goto badframe;
1440
        }
1441

    
1442
        target_to_host_sigset_internal(&host_set, &set);
1443
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1444

    
1445
        if (restore_sigcontext(env, &frame->sc))
1446
                goto badframe;
1447

    
1448
#if 0
1449
        /* Send SIGTRAP if we're single-stepping */
1450
        if (ptrace_cancel_bpt(current))
1451
                send_sig(SIGTRAP, current, 1);
1452
#endif
1453
        unlock_user_struct(frame, frame_addr, 0);
1454
        return env->regs[0];
1455

    
1456
badframe:
1457
        unlock_user_struct(frame, frame_addr, 0);
1458
        force_sig(SIGSEGV /* , current */);
1459
        return 0;
1460
}
1461

    
1462
static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1463
                                 struct target_ucontext_v2 *uc)
1464
{
1465
    sigset_t host_set;
1466

    
1467
    target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1468
    sigprocmask(SIG_SETMASK, &host_set, NULL);
1469

    
1470
    if (restore_sigcontext(env, &uc->tuc_mcontext))
1471
        return 1;
1472

    
1473
    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1474
        return 1;
1475

    
1476
#if 0
1477
    /* Send SIGTRAP if we're single-stepping */
1478
    if (ptrace_cancel_bpt(current))
1479
            send_sig(SIGTRAP, current, 1);
1480
#endif
1481

    
1482
    return 0;
1483
}
1484

    
1485
static long do_sigreturn_v2(CPUState *env)
1486
{
1487
        abi_ulong frame_addr;
1488
        struct sigframe_v2 *frame;
1489

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

    
1498
        frame_addr = env->regs[13];
1499
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1500
                goto badframe;
1501

    
1502
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1503
                goto badframe;
1504

    
1505
        unlock_user_struct(frame, frame_addr, 0);
1506
        return env->regs[0];
1507

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

    
1514
long do_sigreturn(CPUState *env)
1515
{
1516
    if (get_osversion() >= 0x020612) {
1517
        return do_sigreturn_v2(env);
1518
    } else {
1519
        return do_sigreturn_v1(env);
1520
    }
1521
}
1522

    
1523
static long do_rt_sigreturn_v1(CPUState *env)
1524
{
1525
        abi_ulong frame_addr;
1526
        struct rt_sigframe_v1 *frame;
1527
        sigset_t host_set;
1528

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

    
1537
        frame_addr = env->regs[13];
1538
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1539
                goto badframe;
1540

    
1541
        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1542
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1543

    
1544
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1545
                goto badframe;
1546

    
1547
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1548
                goto badframe;
1549

    
1550
#if 0
1551
        /* Send SIGTRAP if we're single-stepping */
1552
        if (ptrace_cancel_bpt(current))
1553
                send_sig(SIGTRAP, current, 1);
1554
#endif
1555
        unlock_user_struct(frame, frame_addr, 0);
1556
        return env->regs[0];
1557

    
1558
badframe:
1559
        unlock_user_struct(frame, frame_addr, 0);
1560
        force_sig(SIGSEGV /* , current */);
1561
        return 0;
1562
}
1563

    
1564
static long do_rt_sigreturn_v2(CPUState *env)
1565
{
1566
        abi_ulong frame_addr;
1567
        struct rt_sigframe_v2 *frame;
1568

    
1569
        /*
1570
         * Since we stacked the signal on a 64-bit boundary,
1571
         * then 'sp' should be word aligned here.  If it's
1572
         * not, then the user is trying to mess with us.
1573
         */
1574
        if (env->regs[13] & 7)
1575
                goto badframe;
1576

    
1577
        frame_addr = env->regs[13];
1578
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1579
                goto badframe;
1580

    
1581
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1582
                goto badframe;
1583

    
1584
        unlock_user_struct(frame, frame_addr, 0);
1585
        return env->regs[0];
1586

    
1587
badframe:
1588
        unlock_user_struct(frame, frame_addr, 0);
1589
        force_sig(SIGSEGV /* , current */);
1590
        return 0;
1591
}
1592

    
1593
long do_rt_sigreturn(CPUState *env)
1594
{
1595
    if (get_osversion() >= 0x020612) {
1596
        return do_rt_sigreturn_v2(env);
1597
    } else {
1598
        return do_rt_sigreturn_v1(env);
1599
    }
1600
}
1601

    
1602
#elif defined(TARGET_SPARC)
1603

    
1604
#define __SUNOS_MAXWIN   31
1605

    
1606
/* This is what SunOS does, so shall I. */
1607
struct target_sigcontext {
1608
        abi_ulong sigc_onstack;      /* state to restore */
1609

    
1610
        abi_ulong sigc_mask;         /* sigmask to restore */
1611
        abi_ulong sigc_sp;           /* stack pointer */
1612
        abi_ulong sigc_pc;           /* program counter */
1613
        abi_ulong sigc_npc;          /* next program counter */
1614
        abi_ulong sigc_psr;          /* for condition codes etc */
1615
        abi_ulong sigc_g1;           /* User uses these two registers */
1616
        abi_ulong sigc_o0;           /* within the trampoline code. */
1617

    
1618
        /* Now comes information regarding the users window set
1619
         * at the time of the signal.
1620
         */
1621
        abi_ulong sigc_oswins;       /* outstanding windows */
1622

    
1623
        /* stack ptrs for each regwin buf */
1624
        char *sigc_spbuf[__SUNOS_MAXWIN];
1625

    
1626
        /* Windows to restore after signal */
1627
        struct {
1628
                abi_ulong locals[8];
1629
                abi_ulong ins[8];
1630
        } sigc_wbuf[__SUNOS_MAXWIN];
1631
};
1632
/* A Sparc stack frame */
1633
struct sparc_stackf {
1634
        abi_ulong locals[8];
1635
        abi_ulong ins[6];
1636
        struct sparc_stackf *fp;
1637
        abi_ulong callers_pc;
1638
        char *structptr;
1639
        abi_ulong xargs[6];
1640
        abi_ulong xxargs[1];
1641
};
1642

    
1643
typedef struct {
1644
        struct {
1645
                abi_ulong psr;
1646
                abi_ulong pc;
1647
                abi_ulong npc;
1648
                abi_ulong y;
1649
                abi_ulong u_regs[16]; /* globals and ins */
1650
        }               si_regs;
1651
        int             si_mask;
1652
} __siginfo_t;
1653

    
1654
typedef struct {
1655
        unsigned   long si_float_regs [32];
1656
        unsigned   long si_fsr;
1657
        unsigned   long si_fpqdepth;
1658
        struct {
1659
                unsigned long *insn_addr;
1660
                unsigned long insn;
1661
        } si_fpqueue [16];
1662
} qemu_siginfo_fpu_t;
1663

    
1664

    
1665
struct target_signal_frame {
1666
        struct sparc_stackf        ss;
1667
        __siginfo_t                info;
1668
        abi_ulong               fpu_save;
1669
        abi_ulong                insns[2] __attribute__ ((aligned (8)));
1670
        abi_ulong                extramask[TARGET_NSIG_WORDS - 1];
1671
        abi_ulong                extra_size; /* Should be 0 */
1672
        qemu_siginfo_fpu_t        fpu_state;
1673
};
1674
struct target_rt_signal_frame {
1675
        struct sparc_stackf        ss;
1676
        siginfo_t                info;
1677
        abi_ulong                regs[20];
1678
        sigset_t                mask;
1679
        abi_ulong               fpu_save;
1680
        unsigned int                insns[2];
1681
        stack_t                        stack;
1682
        unsigned int                extra_size; /* Should be 0 */
1683
        qemu_siginfo_fpu_t        fpu_state;
1684
};
1685

    
1686
#define UREG_O0        16
1687
#define UREG_O6        22
1688
#define UREG_I0        0
1689
#define UREG_I1        1
1690
#define UREG_I2        2
1691
#define UREG_I3        3
1692
#define UREG_I4        4
1693
#define UREG_I5        5
1694
#define UREG_I6        6
1695
#define UREG_I7        7
1696
#define UREG_L0               8
1697
#define UREG_FP        UREG_I6
1698
#define UREG_SP        UREG_O6
1699

    
1700
static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
1701
                                     CPUState *env, unsigned long framesize)
1702
{
1703
        abi_ulong sp;
1704

    
1705
        sp = env->regwptr[UREG_FP];
1706

    
1707
        /* This is the X/Open sanctioned signal stack switching.  */
1708
        if (sa->sa_flags & TARGET_SA_ONSTACK) {
1709
            if (!on_sig_stack(sp)
1710
                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1711
                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1712
        }
1713
        return sp - framesize;
1714
}
1715

    
1716
static int
1717
setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1718
{
1719
        int err = 0, i;
1720

    
1721
        err |= __put_user(env->psr, &si->si_regs.psr);
1722
        err |= __put_user(env->pc, &si->si_regs.pc);
1723
        err |= __put_user(env->npc, &si->si_regs.npc);
1724
        err |= __put_user(env->y, &si->si_regs.y);
1725
        for (i=0; i < 8; i++) {
1726
                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1727
        }
1728
        for (i=0; i < 8; i++) {
1729
                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1730
        }
1731
        err |= __put_user(mask, &si->si_mask);
1732
        return err;
1733
}
1734

    
1735
#if 0
1736
static int
1737
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1738
                 CPUState *env, unsigned long mask)
1739
{
1740
        int err = 0;
1741

1742
        err |= __put_user(mask, &sc->sigc_mask);
1743
        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1744
        err |= __put_user(env->pc, &sc->sigc_pc);
1745
        err |= __put_user(env->npc, &sc->sigc_npc);
1746
        err |= __put_user(env->psr, &sc->sigc_psr);
1747
        err |= __put_user(env->gregs[1], &sc->sigc_g1);
1748
        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1749

1750
        return err;
1751
}
1752
#endif
1753
#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1754

    
1755
static void setup_frame(int sig, struct target_sigaction *ka,
1756
                        target_sigset_t *set, CPUState *env)
1757
{
1758
        abi_ulong sf_addr;
1759
        struct target_signal_frame *sf;
1760
        int sigframe_size, err, i;
1761

    
1762
        /* 1. Make sure everything is clean */
1763
        //synchronize_user_stack();
1764

    
1765
        sigframe_size = NF_ALIGNEDSZ;
1766
        sf_addr = get_sigframe(ka, env, sigframe_size);
1767

    
1768
        sf = lock_user(VERIFY_WRITE, sf_addr, 
1769
                       sizeof(struct target_signal_frame), 0);
1770
        if (!sf)
1771
                goto sigsegv;
1772
                
1773
        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1774
#if 0
1775
        if (invalid_frame_pointer(sf, sigframe_size))
1776
                goto sigill_and_return;
1777
#endif
1778
        /* 2. Save the current process state */
1779
        err = setup___siginfo(&sf->info, env, set->sig[0]);
1780
        err |= __put_user(0, &sf->extra_size);
1781

    
1782
        //err |= save_fpu_state(regs, &sf->fpu_state);
1783
        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1784

    
1785
        err |= __put_user(set->sig[0], &sf->info.si_mask);
1786
        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1787
                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1788
        }
1789

    
1790
        for (i = 0; i < 8; i++) {
1791
                  err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1792
        }
1793
        for (i = 0; i < 8; i++) {
1794
                  err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1795
        }
1796
        if (err)
1797
                goto sigsegv;
1798

    
1799
        /* 3. signal handler back-trampoline and parameters */
1800
        env->regwptr[UREG_FP] = sf_addr;
1801
        env->regwptr[UREG_I0] = sig;
1802
        env->regwptr[UREG_I1] = sf_addr + 
1803
                offsetof(struct target_signal_frame, info);
1804
        env->regwptr[UREG_I2] = sf_addr + 
1805
                offsetof(struct target_signal_frame, info);
1806

    
1807
        /* 4. signal handler */
1808
        env->pc = ka->_sa_handler;
1809
        env->npc = (env->pc + 4);
1810
        /* 5. return to kernel instructions */
1811
        if (ka->sa_restorer)
1812
                env->regwptr[UREG_I7] = ka->sa_restorer;
1813
        else {
1814
                uint32_t val32;
1815

    
1816
                env->regwptr[UREG_I7] = sf_addr + 
1817
                        offsetof(struct target_signal_frame, insns) - 2 * 4;
1818

    
1819
                /* mov __NR_sigreturn, %g1 */
1820
                val32 = 0x821020d8;
1821
                err |= __put_user(val32, &sf->insns[0]);
1822

    
1823
                /* t 0x10 */
1824
                val32 = 0x91d02010;
1825
                err |= __put_user(val32, &sf->insns[1]);
1826
                if (err)
1827
                        goto sigsegv;
1828

    
1829
                /* Flush instruction space. */
1830
                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1831
                //                tb_flush(env);
1832
        }
1833
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1834
        return;
1835
#if 0
1836
sigill_and_return:
1837
        force_sig(TARGET_SIGILL);
1838
#endif
1839
sigsegv:
1840
        //fprintf(stderr, "force_sig\n");
1841
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1842
        force_sig(TARGET_SIGSEGV);
1843
}
1844
static inline int
1845
restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1846
{
1847
        int err;
1848
#if 0
1849
#ifdef CONFIG_SMP
1850
        if (current->flags & PF_USEDFPU)
1851
                regs->psr &= ~PSR_EF;
1852
#else
1853
        if (current == last_task_used_math) {
1854
                last_task_used_math = 0;
1855
                regs->psr &= ~PSR_EF;
1856
        }
1857
#endif
1858
        current->used_math = 1;
1859
        current->flags &= ~PF_USEDFPU;
1860
#endif
1861
#if 0
1862
        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1863
                return -EFAULT;
1864
#endif
1865

    
1866
#if 0
1867
        /* XXX: incorrect */
1868
        err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1869
                                     (sizeof(unsigned long) * 32));
1870
#endif
1871
        err |= __get_user(env->fsr, &fpu->si_fsr);
1872
#if 0
1873
        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1874
        if (current->thread.fpqdepth != 0)
1875
                err |= __copy_from_user(&current->thread.fpqueue[0],
1876
                                        &fpu->si_fpqueue[0],
1877
                                        ((sizeof(unsigned long) +
1878
                                        (sizeof(unsigned long *)))*16));
1879
#endif
1880
        return err;
1881
}
1882

    
1883

    
1884
static void setup_rt_frame(int sig, struct target_sigaction *ka,
1885
                           target_siginfo_t *info,
1886
                           target_sigset_t *set, CPUState *env)
1887
{
1888
    fprintf(stderr, "setup_rt_frame: not implemented\n");
1889
}
1890

    
1891
long do_sigreturn(CPUState *env)
1892
{
1893
        abi_ulong sf_addr;
1894
        struct target_signal_frame *sf;
1895
        uint32_t up_psr, pc, npc;
1896
        target_sigset_t set;
1897
        sigset_t host_set;
1898
        abi_ulong fpu_save_addr;
1899
        int err, i;
1900

    
1901
        sf_addr = env->regwptr[UREG_FP];
1902
        if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1903
                goto segv_and_exit;
1904
#if 0
1905
        fprintf(stderr, "sigreturn\n");
1906
        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1907
#endif
1908
        //cpu_dump_state(env, stderr, fprintf, 0);
1909

    
1910
        /* 1. Make sure we are not getting garbage from the user */
1911

    
1912
        if (sf_addr & 3)
1913
                goto segv_and_exit;
1914

    
1915
        err = __get_user(pc,  &sf->info.si_regs.pc);
1916
        err |= __get_user(npc, &sf->info.si_regs.npc);
1917

    
1918
        if ((pc | npc) & 3)
1919
                goto segv_and_exit;
1920

    
1921
        /* 2. Restore the state */
1922
        err |= __get_user(up_psr, &sf->info.si_regs.psr);
1923

    
1924
        /* User can only change condition codes and FPU enabling in %psr. */
1925
        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1926
                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1927

    
1928
        env->pc = pc;
1929
        env->npc = npc;
1930
        err |= __get_user(env->y, &sf->info.si_regs.y);
1931
        for (i=0; i < 8; i++) {
1932
                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1933
        }
1934
        for (i=0; i < 8; i++) {
1935
                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1936
        }
1937

    
1938
        err |= __get_user(fpu_save_addr, &sf->fpu_save);
1939

    
1940
        //if (fpu_save)
1941
        //        err |= restore_fpu_state(env, fpu_save);
1942

    
1943
        /* This is pretty much atomic, no amount locking would prevent
1944
         * the races which exist anyways.
1945
         */
1946
        err |= __get_user(set.sig[0], &sf->info.si_mask);
1947
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1948
            err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1949
        }
1950

    
1951
        target_to_host_sigset_internal(&host_set, &set);
1952
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1953

    
1954
        if (err)
1955
                goto segv_and_exit;
1956
        unlock_user_struct(sf, sf_addr, 0);
1957
        return env->regwptr[0];
1958

    
1959
segv_and_exit:
1960
        unlock_user_struct(sf, sf_addr, 0);
1961
        force_sig(TARGET_SIGSEGV);
1962
}
1963

    
1964
long do_rt_sigreturn(CPUState *env)
1965
{
1966
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1967
    return -TARGET_ENOSYS;
1968
}
1969

    
1970
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1971
#define MC_TSTATE 0
1972
#define MC_PC 1
1973
#define MC_NPC 2
1974
#define MC_Y 3
1975
#define MC_G1 4
1976
#define MC_G2 5
1977
#define MC_G3 6
1978
#define MC_G4 7
1979
#define MC_G5 8
1980
#define MC_G6 9
1981
#define MC_G7 10
1982
#define MC_O0 11
1983
#define MC_O1 12
1984
#define MC_O2 13
1985
#define MC_O3 14
1986
#define MC_O4 15
1987
#define MC_O5 16
1988
#define MC_O6 17
1989
#define MC_O7 18
1990
#define MC_NGREG 19
1991

    
1992
typedef abi_ulong target_mc_greg_t;
1993
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1994

    
1995
struct target_mc_fq {
1996
    abi_ulong *mcfq_addr;
1997
    uint32_t mcfq_insn;
1998
};
1999

    
2000
struct target_mc_fpu {
2001
    union {
2002
        uint32_t sregs[32];
2003
        uint64_t dregs[32];
2004
        //uint128_t qregs[16];
2005
    } mcfpu_fregs;
2006
    abi_ulong mcfpu_fsr;
2007
    abi_ulong mcfpu_fprs;
2008
    abi_ulong mcfpu_gsr;
2009
    struct target_mc_fq *mcfpu_fq;
2010
    unsigned char mcfpu_qcnt;
2011
    unsigned char mcfpu_qentsz;
2012
    unsigned char mcfpu_enab;
2013
};
2014
typedef struct target_mc_fpu target_mc_fpu_t;
2015

    
2016
typedef struct {
2017
    target_mc_gregset_t mc_gregs;
2018
    target_mc_greg_t mc_fp;
2019
    target_mc_greg_t mc_i7;
2020
    target_mc_fpu_t mc_fpregs;
2021
} target_mcontext_t;
2022

    
2023
struct target_ucontext {
2024
    struct target_ucontext *uc_link;
2025
    abi_ulong uc_flags;
2026
    target_sigset_t uc_sigmask;
2027
    target_mcontext_t uc_mcontext;
2028
};
2029

    
2030
/* A V9 register window */
2031
struct target_reg_window {
2032
    abi_ulong locals[8];
2033
    abi_ulong ins[8];
2034
};
2035

    
2036
#define TARGET_STACK_BIAS 2047
2037

    
2038
/* {set, get}context() needed for 64-bit SparcLinux userland. */
2039
void sparc64_set_context(CPUSPARCState *env)
2040
{
2041
    abi_ulong ucp_addr;
2042
    struct target_ucontext *ucp;
2043
    target_mc_gregset_t *grp;
2044
    abi_ulong pc, npc, tstate;
2045
    abi_ulong fp, i7, w_addr;
2046
    unsigned char fenab;
2047
    int err;
2048
    unsigned int i;
2049

    
2050
    ucp_addr = env->regwptr[UREG_I0];
2051
    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2052
        goto do_sigsegv;
2053
    grp  = &ucp->uc_mcontext.mc_gregs;
2054
    err  = __get_user(pc, &((*grp)[MC_PC]));
2055
    err |= __get_user(npc, &((*grp)[MC_NPC]));
2056
    if (err || ((pc | npc) & 3))
2057
        goto do_sigsegv;
2058
    if (env->regwptr[UREG_I1]) {
2059
        target_sigset_t target_set;
2060
        sigset_t set;
2061

    
2062
        if (TARGET_NSIG_WORDS == 1) {
2063
            if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2064
                goto do_sigsegv;
2065
        } else {
2066
            abi_ulong *src, *dst;
2067
            src = ucp->uc_sigmask.sig;
2068
            dst = target_set.sig;
2069
            for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2070
                 i++, dst++, src++)
2071
                err |= __get_user(*dst, src);
2072
            if (err)
2073
                goto do_sigsegv;
2074
        }
2075
        target_to_host_sigset_internal(&set, &target_set);
2076
        sigprocmask(SIG_SETMASK, &set, NULL);
2077
    }
2078
    env->pc = pc;
2079
    env->npc = npc;
2080
    err |= __get_user(env->y, &((*grp)[MC_Y]));
2081
    err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2082
    env->asi = (tstate >> 24) & 0xff;
2083
    PUT_CCR(env, tstate >> 32);
2084
    PUT_CWP64(env, tstate & 0x1f);
2085
    err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2086
    err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2087
    err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2088
    err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2089
    err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2090
    err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2091
    err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2092
    err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2093
    err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2094
    err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2095
    err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2096
    err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2097
    err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2098
    err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2099
    err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2100

    
2101
    err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2102
    err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2103

    
2104
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2105
    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2106
                 abi_ulong) != 0)
2107
        goto do_sigsegv;
2108
    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2109
                 abi_ulong) != 0)
2110
        goto do_sigsegv;
2111
    err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2112
    err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2113
    {
2114
        uint32_t *src, *dst;
2115
        src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2116
        dst = env->fpr;
2117
        /* XXX: check that the CPU storage is the same as user context */
2118
        for (i = 0; i < 64; i++, dst++, src++)
2119
            err |= __get_user(*dst, src);
2120
    }
2121
    err |= __get_user(env->fsr,
2122
                      &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2123
    err |= __get_user(env->gsr,
2124
                      &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2125
    if (err)
2126
        goto do_sigsegv;
2127
    unlock_user_struct(ucp, ucp_addr, 0);
2128
    return;
2129
 do_sigsegv:
2130
    unlock_user_struct(ucp, ucp_addr, 0);
2131
    force_sig(SIGSEGV);
2132
}
2133

    
2134
void sparc64_get_context(CPUSPARCState *env)
2135
{
2136
    abi_ulong ucp_addr;
2137
    struct target_ucontext *ucp;
2138
    target_mc_gregset_t *grp;
2139
    target_mcontext_t *mcp;
2140
    abi_ulong fp, i7, w_addr;
2141
    int err;
2142
    unsigned int i;
2143
    target_sigset_t target_set;
2144
    sigset_t set;
2145

    
2146
    ucp_addr = env->regwptr[UREG_I0];
2147
    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2148
        goto do_sigsegv;
2149
    
2150
    mcp = &ucp->uc_mcontext;
2151
    grp = &mcp->mc_gregs;
2152

    
2153
    /* Skip over the trap instruction, first. */
2154
    env->pc = env->npc;
2155
    env->npc += 4;
2156

    
2157
    err = 0;
2158

    
2159
    sigprocmask(0, NULL, &set);
2160
    host_to_target_sigset_internal(&target_set, &set);
2161
    if (TARGET_NSIG_WORDS == 1) {
2162
        err |= __put_user(target_set.sig[0],
2163
                          (abi_ulong *)&ucp->uc_sigmask);
2164
    } else {
2165
        abi_ulong *src, *dst;
2166
        src = target_set.sig;
2167
        dst = ucp->uc_sigmask.sig;
2168
        for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2169
             i++, dst++, src++)
2170
            err |= __put_user(*src, dst);
2171
        if (err)
2172
            goto do_sigsegv;
2173
    }
2174

    
2175
    /* XXX: tstate must be saved properly */
2176
    //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2177
    err |= __put_user(env->pc, &((*grp)[MC_PC]));
2178
    err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2179
    err |= __put_user(env->y, &((*grp)[MC_Y]));
2180
    err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2181
    err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2182
    err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2183
    err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2184
    err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2185
    err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2186
    err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2187
    err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2188
    err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2189
    err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2190
    err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2191
    err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2192
    err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2193
    err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2194
    err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2195

    
2196
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2197
    fp = i7 = 0;
2198
    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2199
                 abi_ulong) != 0)
2200
        goto do_sigsegv;
2201
    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2202
                 abi_ulong) != 0)
2203
        goto do_sigsegv;
2204
    err |= __put_user(fp, &(mcp->mc_fp));
2205
    err |= __put_user(i7, &(mcp->mc_i7));
2206

    
2207
    {
2208
        uint32_t *src, *dst;
2209
        src = env->fpr;
2210
        dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2211
        /* XXX: check that the CPU storage is the same as user context */
2212
        for (i = 0; i < 64; i++, dst++, src++)
2213
            err |= __put_user(*src, dst);
2214
    }
2215
    err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2216
    err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2217
    err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2218

    
2219
    if (err)
2220
        goto do_sigsegv;
2221
    unlock_user_struct(ucp, ucp_addr, 1);
2222
    return;
2223
 do_sigsegv:
2224
    unlock_user_struct(ucp, ucp_addr, 1);
2225
    force_sig(SIGSEGV);
2226
}
2227
#endif
2228
#elif defined(TARGET_ABI_MIPSN64)
2229

    
2230
# warning signal handling not implemented
2231

    
2232
static void setup_frame(int sig, struct target_sigaction *ka,
2233
                        target_sigset_t *set, CPUState *env)
2234
{
2235
    fprintf(stderr, "setup_frame: not implemented\n");
2236
}
2237

    
2238
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2239
                           target_siginfo_t *info,
2240
                           target_sigset_t *set, CPUState *env)
2241
{
2242
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2243
}
2244

    
2245
long do_sigreturn(CPUState *env)
2246
{
2247
    fprintf(stderr, "do_sigreturn: not implemented\n");
2248
    return -TARGET_ENOSYS;
2249
}
2250

    
2251
long do_rt_sigreturn(CPUState *env)
2252
{
2253
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2254
    return -TARGET_ENOSYS;
2255
}
2256

    
2257
#elif defined(TARGET_ABI_MIPSN32)
2258

    
2259
# warning signal handling not implemented
2260

    
2261
static void setup_frame(int sig, struct target_sigaction *ka,
2262
                        target_sigset_t *set, CPUState *env)
2263
{
2264
    fprintf(stderr, "setup_frame: not implemented\n");
2265
}
2266

    
2267
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2268
                           target_siginfo_t *info,
2269
                           target_sigset_t *set, CPUState *env)
2270
{
2271
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2272
}
2273

    
2274
long do_sigreturn(CPUState *env)
2275
{
2276
    fprintf(stderr, "do_sigreturn: not implemented\n");
2277
    return -TARGET_ENOSYS;
2278
}
2279

    
2280
long do_rt_sigreturn(CPUState *env)
2281
{
2282
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2283
    return -TARGET_ENOSYS;
2284
}
2285

    
2286
#elif defined(TARGET_ABI_MIPSO32)
2287

    
2288
struct target_sigcontext {
2289
    uint32_t   sc_regmask;     /* Unused */
2290
    uint32_t   sc_status;
2291
    uint64_t   sc_pc;
2292
    uint64_t   sc_regs[32];
2293
    uint64_t   sc_fpregs[32];
2294
    uint32_t   sc_ownedfp;     /* Unused */
2295
    uint32_t   sc_fpc_csr;
2296
    uint32_t   sc_fpc_eir;     /* Unused */
2297
    uint32_t   sc_used_math;
2298
    uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
2299
    uint64_t   sc_mdhi;
2300
    uint64_t   sc_mdlo;
2301
    target_ulong   sc_hi1;         /* Was sc_cause */
2302
    target_ulong   sc_lo1;         /* Was sc_badvaddr */
2303
    target_ulong   sc_hi2;         /* Was sc_sigset[4] */
2304
    target_ulong   sc_lo2;
2305
    target_ulong   sc_hi3;
2306
    target_ulong   sc_lo3;
2307
};
2308

    
2309
struct sigframe {
2310
    uint32_t sf_ass[4];                        /* argument save space for o32 */
2311
    uint32_t sf_code[2];                        /* signal trampoline */
2312
    struct target_sigcontext sf_sc;
2313
    target_sigset_t sf_mask;
2314
};
2315

    
2316
/* Install trampoline to jump back from signal handler */
2317
static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2318
{
2319
    int err;
2320

    
2321
    /*
2322
    * Set up the return code ...
2323
    *
2324
    *         li      v0, __NR__foo_sigreturn
2325
    *         syscall
2326
    */
2327

    
2328
    err = __put_user(0x24020000 + syscall, tramp + 0);
2329
    err |= __put_user(0x0000000c          , tramp + 1);
2330
    /* flush_cache_sigtramp((unsigned long) tramp); */
2331
    return err;
2332
}
2333

    
2334
static inline int
2335
setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2336
{
2337
    int err = 0;
2338

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

    
2341
#define save_gp_reg(i) do {                                                   \
2342
        err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);        \
2343
    } while(0)
2344
    __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2345
    save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2346
    save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2347
    save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2348
    save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2349
    save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2350
    save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2351
    save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2352
    save_gp_reg(31);
2353
#undef save_gp_reg
2354

    
2355
    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2356
    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2357

    
2358
    /* Not used yet, but might be useful if we ever have DSP suppport */
2359
#if 0
2360
    if (cpu_has_dsp) {
2361
        err |= __put_user(mfhi1(), &sc->sc_hi1);
2362
        err |= __put_user(mflo1(), &sc->sc_lo1);
2363
        err |= __put_user(mfhi2(), &sc->sc_hi2);
2364
        err |= __put_user(mflo2(), &sc->sc_lo2);
2365
        err |= __put_user(mfhi3(), &sc->sc_hi3);
2366
        err |= __put_user(mflo3(), &sc->sc_lo3);
2367
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2368
    }
2369
    /* same with 64 bit */
2370
#ifdef CONFIG_64BIT
2371
    err |= __put_user(regs->hi, &sc->sc_hi[0]);
2372
    err |= __put_user(regs->lo, &sc->sc_lo[0]);
2373
    if (cpu_has_dsp) {
2374
        err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2375
        err |= __put_user(mflo1(), &sc->sc_lo[1]);
2376
        err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2377
        err |= __put_user(mflo2(), &sc->sc_lo[2]);
2378
        err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2379
        err |= __put_user(mflo3(), &sc->sc_lo[3]);
2380
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2381
    }
2382
#endif
2383
#endif
2384

    
2385
#if 0
2386
    err |= __put_user(!!used_math(), &sc->sc_used_math);
2387

2388
    if (!used_math())
2389
        goto out;
2390

2391
    /*
2392
    * Save FPU state to signal context.  Signal handler will "inherit"
2393
    * current FPU state.
2394
    */
2395
    preempt_disable();
2396

2397
    if (!is_fpu_owner()) {
2398
        own_fpu();
2399
        restore_fp(current);
2400
    }
2401
    err |= save_fp_context(sc);
2402

2403
    preempt_enable();
2404
    out:
2405
#endif
2406
    return err;
2407
}
2408

    
2409
static inline int
2410
restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2411
{
2412
    int err = 0;
2413

    
2414
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2415

    
2416
    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2417
    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2418

    
2419
#define restore_gp_reg(i) do {                                                           \
2420
        err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);                \
2421
    } while(0)
2422
    restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2423
    restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2424
    restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2425
    restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2426
    restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2427
    restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2428
    restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2429
    restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2430
    restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2431
    restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2432
    restore_gp_reg(31);
2433
#undef restore_gp_reg
2434

    
2435
#if 0
2436
    if (cpu_has_dsp) {
2437
        err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2438
        err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2439
        err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2440
        err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2441
        err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2442
        err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2443
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2444
    }
2445
#ifdef CONFIG_64BIT
2446
    err |= __get_user(regs->hi, &sc->sc_hi[0]);
2447
    err |= __get_user(regs->lo, &sc->sc_lo[0]);
2448
    if (cpu_has_dsp) {
2449
        err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2450
        err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2451
        err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2452
        err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2453
        err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2454
        err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2455
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2456
    }
2457
#endif
2458

    
2459
    err |= __get_user(used_math, &sc->sc_used_math);
2460
    conditional_used_math(used_math);
2461

    
2462
    preempt_disable();
2463

    
2464
    if (used_math()) {
2465
        /* restore fpu context if we have used it before */
2466
        own_fpu();
2467
        err |= restore_fp_context(sc);
2468
    } else {
2469
        /* signal handler may have used FPU.  Give it up. */
2470
        lose_fpu();
2471
    }
2472

    
2473
    preempt_enable();
2474
#endif
2475
    return err;
2476
}
2477
/*
2478
 * Determine which stack to use..
2479
 */
2480
static inline abi_ulong
2481
get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2482
{
2483
    unsigned long sp;
2484

    
2485
    /* Default to using normal stack */
2486
    sp = regs->active_tc.gpr[29];
2487

    
2488
    /*
2489
     * FPU emulator may have it's own trampoline active just
2490
     * above the user stack, 16-bytes before the next lowest
2491
     * 16 byte boundary.  Try to avoid trashing it.
2492
     */
2493
    sp -= 32;
2494

    
2495
    /* This is the X/Open sanctioned signal stack switching.  */
2496
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2497
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2498
    }
2499

    
2500
    return (sp - frame_size) & ~7;
2501
}
2502

    
2503
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2504
static void setup_frame(int sig, struct target_sigaction * ka,
2505
                        target_sigset_t *set, CPUState *regs)
2506
{
2507
    struct sigframe *frame;
2508
    abi_ulong frame_addr;
2509
    int i;
2510

    
2511
    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2512
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2513
        goto give_sigsegv;
2514

    
2515
    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2516

    
2517
    if(setup_sigcontext(regs, &frame->sf_sc))
2518
        goto give_sigsegv;
2519

    
2520
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2521
        if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2522
            goto give_sigsegv;
2523
    }
2524

    
2525
    /*
2526
    * Arguments to signal handler:
2527
    *
2528
    *   a0 = signal number
2529
    *   a1 = 0 (should be cause)
2530
    *   a2 = pointer to struct sigcontext
2531
    *
2532
    * $25 and PC point to the signal handler, $29 points to the
2533
    * struct sigframe.
2534
    */
2535
    regs->active_tc.gpr[ 4] = sig;
2536
    regs->active_tc.gpr[ 5] = 0;
2537
    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2538
    regs->active_tc.gpr[29] = frame_addr;
2539
    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2540
    /* The original kernel code sets CP0_EPC to the handler
2541
    * since it returns to userland using eret
2542
    * we cannot do this here, and we must set PC directly */
2543
    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2544
    unlock_user_struct(frame, frame_addr, 1);
2545
    return;
2546

    
2547
give_sigsegv:
2548
    unlock_user_struct(frame, frame_addr, 1);
2549
    force_sig(TARGET_SIGSEGV/*, current*/);
2550
    return;
2551
}
2552

    
2553
long do_sigreturn(CPUState *regs)
2554
{
2555
    struct sigframe *frame;
2556
    abi_ulong frame_addr;
2557
    sigset_t blocked;
2558
    target_sigset_t target_set;
2559
    int i;
2560

    
2561
#if defined(DEBUG_SIGNAL)
2562
    fprintf(stderr, "do_sigreturn\n");
2563
#endif
2564
    frame_addr = regs->active_tc.gpr[29];
2565
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2566
           goto badframe;
2567

    
2568
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2569
           if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2570
            goto badframe;
2571
    }
2572

    
2573
    target_to_host_sigset_internal(&blocked, &target_set);
2574
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2575

    
2576
    if (restore_sigcontext(regs, &frame->sf_sc))
2577
           goto badframe;
2578

    
2579
#if 0
2580
    /*
2581
     * Don't let your children do this ...
2582
     */
2583
    __asm__ __volatile__(
2584
           "move\t$29, %0\n\t"
2585
           "j\tsyscall_exit"
2586
           :/* no outputs */
2587
           :"r" (&regs));
2588
    /* Unreached */
2589
#endif
2590

    
2591
    regs->active_tc.PC = regs->CP0_EPC;
2592
    /* I am not sure this is right, but it seems to work
2593
    * maybe a problem with nested signals ? */
2594
    regs->CP0_EPC = 0;
2595
    return 0;
2596

    
2597
badframe:
2598
    force_sig(TARGET_SIGSEGV/*, current*/);
2599
    return 0;
2600
}
2601

    
2602
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2603
                           target_siginfo_t *info,
2604
                           target_sigset_t *set, CPUState *env)
2605
{
2606
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2607
}
2608

    
2609
long do_rt_sigreturn(CPUState *env)
2610
{
2611
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2612
    return -TARGET_ENOSYS;
2613
}
2614

    
2615
#elif defined(TARGET_SH4)
2616

    
2617
/*
2618
 * code and data structures from linux kernel:
2619
 * include/asm-sh/sigcontext.h
2620
 * arch/sh/kernel/signal.c
2621
 */
2622

    
2623
struct target_sigcontext {
2624
    target_ulong  oldmask;
2625

    
2626
    /* CPU registers */
2627
    target_ulong  sc_gregs[16];
2628
    target_ulong  sc_pc;
2629
    target_ulong  sc_pr;
2630
    target_ulong  sc_sr;
2631
    target_ulong  sc_gbr;
2632
    target_ulong  sc_mach;
2633
    target_ulong  sc_macl;
2634

    
2635
    /* FPU registers */
2636
    target_ulong  sc_fpregs[16];
2637
    target_ulong  sc_xfpregs[16];
2638
    unsigned int sc_fpscr;
2639
    unsigned int sc_fpul;
2640
    unsigned int sc_ownedfp;
2641
};
2642

    
2643
struct target_sigframe
2644
{
2645
    struct target_sigcontext sc;
2646
    target_ulong extramask[TARGET_NSIG_WORDS-1];
2647
    uint16_t retcode[3];
2648
};
2649

    
2650

    
2651
struct target_ucontext {
2652
    target_ulong uc_flags;
2653
    struct target_ucontext *uc_link;
2654
    target_stack_t uc_stack;
2655
    struct target_sigcontext uc_mcontext;
2656
    target_sigset_t uc_sigmask;        /* mask last for extensibility */
2657
};
2658

    
2659
struct target_rt_sigframe
2660
{
2661
    struct target_siginfo info;
2662
    struct target_ucontext uc;
2663
    uint16_t retcode[3];
2664
};
2665

    
2666

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

    
2670
static abi_ulong get_sigframe(struct target_sigaction *ka,
2671
                         unsigned long sp, size_t frame_size)
2672
{
2673
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2674
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2675
    }
2676

    
2677
    return (sp - frame_size) & -8ul;
2678
}
2679

    
2680
static int setup_sigcontext(struct target_sigcontext *sc,
2681
                            CPUState *regs, unsigned long mask)
2682
{
2683
    int err = 0;
2684

    
2685
#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
2686
    COPY(gregs[0]); COPY(gregs[1]);
2687
    COPY(gregs[2]); COPY(gregs[3]);
2688
    COPY(gregs[4]); COPY(gregs[5]);
2689
    COPY(gregs[6]); COPY(gregs[7]);
2690
    COPY(gregs[8]); COPY(gregs[9]);
2691
    COPY(gregs[10]); COPY(gregs[11]);
2692
    COPY(gregs[12]); COPY(gregs[13]);
2693
    COPY(gregs[14]); COPY(gregs[15]);
2694
    COPY(gbr); COPY(mach);
2695
    COPY(macl); COPY(pr);
2696
    COPY(sr); COPY(pc);
2697
#undef COPY
2698

    
2699
    /* todo: save FPU registers here */
2700

    
2701
    /* non-iBCS2 extensions.. */
2702
    err |= __put_user(mask, &sc->oldmask);
2703

    
2704
    return err;
2705
}
2706

    
2707
static int restore_sigcontext(CPUState *regs,
2708
                              struct target_sigcontext *sc)
2709
{
2710
    unsigned int err = 0;
2711

    
2712
#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
2713
    COPY(gregs[1]);
2714
    COPY(gregs[2]); COPY(gregs[3]);
2715
    COPY(gregs[4]); COPY(gregs[5]);
2716
    COPY(gregs[6]); COPY(gregs[7]);
2717
    COPY(gregs[8]); COPY(gregs[9]);
2718
    COPY(gregs[10]); COPY(gregs[11]);
2719
    COPY(gregs[12]); COPY(gregs[13]);
2720
    COPY(gregs[14]); COPY(gregs[15]);
2721
    COPY(gbr); COPY(mach);
2722
    COPY(macl); COPY(pr);
2723
    COPY(sr); COPY(pc);
2724
#undef COPY
2725

    
2726
    /* todo: restore FPU registers here */
2727

    
2728
    regs->tra = -1;         /* disable syscall checks */
2729
    return err;
2730
}
2731

    
2732
static void setup_frame(int sig, struct target_sigaction *ka,
2733
                        target_sigset_t *set, CPUState *regs)
2734
{
2735
    struct target_sigframe *frame;
2736
    abi_ulong frame_addr;
2737
    int i;
2738
    int err = 0;
2739
    int signal;
2740

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

    
2745
    signal = current_exec_domain_sig(sig);
2746

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

    
2749
    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2750
        err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2751
    }
2752

    
2753
    /* Set up to return from userspace.  If provided, use a stub
2754
       already in userspace.  */
2755
    if (ka->sa_flags & TARGET_SA_RESTORER) {
2756
        regs->pr = (unsigned long) ka->sa_restorer;
2757
    } else {
2758
        /* Generate return code (system call to sigreturn) */
2759
        err |= __put_user(MOVW(2), &frame->retcode[0]);
2760
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2761
        err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2762
        regs->pr = (unsigned long) frame->retcode;
2763
    }
2764

    
2765
    if (err)
2766
        goto give_sigsegv;
2767

    
2768
    /* Set up registers for signal handler */
2769
    regs->gregs[15] = (unsigned long) frame;
2770
    regs->gregs[4] = signal; /* Arg for signal handler */
2771
    regs->gregs[5] = 0;
2772
    regs->gregs[6] = (unsigned long) &frame->sc;
2773
    regs->pc = (unsigned long) ka->_sa_handler;
2774

    
2775
    unlock_user_struct(frame, frame_addr, 1);
2776
    return;
2777

    
2778
give_sigsegv:
2779
    unlock_user_struct(frame, frame_addr, 1);
2780
    force_sig(SIGSEGV);
2781
}
2782

    
2783
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2784
                           target_siginfo_t *info,
2785
                           target_sigset_t *set, CPUState *regs)
2786
{
2787
    struct target_rt_sigframe *frame;
2788
    abi_ulong frame_addr;
2789
    int i;
2790
    int err = 0;
2791
    int signal;
2792

    
2793
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2794
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2795
        goto give_sigsegv;
2796

    
2797
    signal = current_exec_domain_sig(sig);
2798

    
2799
    err |= copy_siginfo_to_user(&frame->info, info);
2800

    
2801
    /* Create the ucontext.  */
2802
    err |= __put_user(0, &frame->uc.uc_flags);
2803
    err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2804
    err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2805
                      &frame->uc.uc_stack.ss_sp);
2806
    err |= __put_user(sas_ss_flags(regs->gregs[15]),
2807
                      &frame->uc.uc_stack.ss_flags);
2808
    err |= __put_user(target_sigaltstack_used.ss_size,
2809
                      &frame->uc.uc_stack.ss_size);
2810
    err |= setup_sigcontext(&frame->uc.uc_mcontext,
2811
                            regs, set->sig[0]);
2812
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2813
        err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2814
    }
2815

    
2816
    /* Set up to return from userspace.  If provided, use a stub
2817
       already in userspace.  */
2818
    if (ka->sa_flags & TARGET_SA_RESTORER) {
2819
        regs->pr = (unsigned long) ka->sa_restorer;
2820
    } else {
2821
        /* Generate return code (system call to sigreturn) */
2822
        err |= __put_user(MOVW(2), &frame->retcode[0]);
2823
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2824
        err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2825
        regs->pr = (unsigned long) frame->retcode;
2826
    }
2827

    
2828
    if (err)
2829
        goto give_sigsegv;
2830

    
2831
    /* Set up registers for signal handler */
2832
    regs->gregs[15] = (unsigned long) frame;
2833
    regs->gregs[4] = signal; /* Arg for signal handler */
2834
    regs->gregs[5] = (unsigned long) &frame->info;
2835
    regs->gregs[6] = (unsigned long) &frame->uc;
2836
    regs->pc = (unsigned long) ka->_sa_handler;
2837

    
2838
    unlock_user_struct(frame, frame_addr, 1);
2839
    return;
2840

    
2841
give_sigsegv:
2842
    unlock_user_struct(frame, frame_addr, 1);
2843
    force_sig(SIGSEGV);
2844
}
2845

    
2846
long do_sigreturn(CPUState *regs)
2847
{
2848
    struct target_sigframe *frame;
2849
    abi_ulong frame_addr;
2850
    sigset_t blocked;
2851
    target_sigset_t target_set;
2852
    int i;
2853
    int err = 0;
2854

    
2855
#if defined(DEBUG_SIGNAL)
2856
    fprintf(stderr, "do_sigreturn\n");
2857
#endif
2858
    frame_addr = regs->gregs[15];
2859
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2860
           goto badframe;
2861

    
2862
    err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2863
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2864
        err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2865
    }
2866

    
2867
    if (err)
2868
        goto badframe;
2869

    
2870
    target_to_host_sigset_internal(&blocked, &target_set);
2871
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2872

    
2873
    if (restore_sigcontext(regs, &frame->sc))
2874
        goto badframe;
2875

    
2876
    unlock_user_struct(frame, frame_addr, 0);
2877
    return regs->gregs[0];
2878

    
2879
badframe:
2880
    unlock_user_struct(frame, frame_addr, 0);
2881
    force_sig(TARGET_SIGSEGV);
2882
    return 0;
2883
}
2884

    
2885
long do_rt_sigreturn(CPUState *regs)
2886
{
2887
    struct target_rt_sigframe *frame;
2888
    abi_ulong frame_addr;
2889
    sigset_t blocked;
2890

    
2891
#if defined(DEBUG_SIGNAL)
2892
    fprintf(stderr, "do_rt_sigreturn\n");
2893
#endif
2894
    frame_addr = regs->gregs[15];
2895
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2896
           goto badframe;
2897

    
2898
    target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2899
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2900

    
2901
    if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2902
        goto badframe;
2903

    
2904
    if (do_sigaltstack(frame_addr +
2905
                       offsetof(struct target_rt_sigframe, uc.uc_stack),
2906
                       0, get_sp_from_cpustate(regs)) == -EFAULT)
2907
        goto badframe;
2908

    
2909
    unlock_user_struct(frame, frame_addr, 0);
2910
    return regs->gregs[0];
2911

    
2912
badframe:
2913
    unlock_user_struct(frame, frame_addr, 0);
2914
    force_sig(TARGET_SIGSEGV);
2915
    return 0;
2916
}
2917
#elif defined(TARGET_CRIS)
2918

    
2919
struct target_sigcontext {
2920
        struct target_pt_regs regs;  /* needs to be first */
2921
        uint32_t oldmask;
2922
        uint32_t usp;    /* usp before stacking this gunk on it */
2923
};
2924

    
2925
/* Signal frames. */
2926
struct target_signal_frame {
2927
        struct target_sigcontext sc;
2928
        uint32_t extramask[TARGET_NSIG_WORDS - 1];
2929
        uint8_t retcode[8];       /* Trampoline code. */
2930
};
2931

    
2932
struct rt_signal_frame {
2933
        struct siginfo *pinfo;
2934
        void *puc;
2935
        struct siginfo info;
2936
        struct ucontext uc;
2937
        uint8_t retcode[8];       /* Trampoline code. */
2938
};
2939

    
2940
static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2941
{
2942
        __put_user(env->regs[0], &sc->regs.r0);
2943
        __put_user(env->regs[1], &sc->regs.r1);
2944
        __put_user(env->regs[2], &sc->regs.r2);
2945
        __put_user(env->regs[3], &sc->regs.r3);
2946
        __put_user(env->regs[4], &sc->regs.r4);
2947
        __put_user(env->regs[5], &sc->regs.r5);
2948
        __put_user(env->regs[6], &sc->regs.r6);
2949
        __put_user(env->regs[7], &sc->regs.r7);
2950
        __put_user(env->regs[8], &sc->regs.r8);
2951
        __put_user(env->regs[9], &sc->regs.r9);
2952
        __put_user(env->regs[10], &sc->regs.r10);
2953
        __put_user(env->regs[11], &sc->regs.r11);
2954
        __put_user(env->regs[12], &sc->regs.r12);
2955
        __put_user(env->regs[13], &sc->regs.r13);
2956
        __put_user(env->regs[14], &sc->usp);
2957
        __put_user(env->regs[15], &sc->regs.acr);
2958
        __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2959
        __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2960
        __put_user(env->pc, &sc->regs.erp);
2961
}
2962

    
2963
static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2964
{
2965
        __get_user(env->regs[0], &sc->regs.r0);
2966
        __get_user(env->regs[1], &sc->regs.r1);
2967
        __get_user(env->regs[2], &sc->regs.r2);
2968
        __get_user(env->regs[3], &sc->regs.r3);
2969
        __get_user(env->regs[4], &sc->regs.r4);
2970
        __get_user(env->regs[5], &sc->regs.r5);
2971
        __get_user(env->regs[6], &sc->regs.r6);
2972
        __get_user(env->regs[7], &sc->regs.r7);
2973
        __get_user(env->regs[8], &sc->regs.r8);
2974
        __get_user(env->regs[9], &sc->regs.r9);
2975
        __get_user(env->regs[10], &sc->regs.r10);
2976
        __get_user(env->regs[11], &sc->regs.r11);
2977
        __get_user(env->regs[12], &sc->regs.r12);
2978
        __get_user(env->regs[13], &sc->regs.r13);
2979
        __get_user(env->regs[14], &sc->usp);
2980
        __get_user(env->regs[15], &sc->regs.acr);
2981
        __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2982
        __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2983
        __get_user(env->pc, &sc->regs.erp);
2984
}
2985

    
2986
static abi_ulong get_sigframe(CPUState *env, int framesize)
2987
{
2988
        abi_ulong sp;
2989
        /* Align the stack downwards to 4.  */
2990
        sp = (env->regs[R_SP] & ~3);
2991
        return sp - framesize;
2992
}
2993

    
2994
static void setup_frame(int sig, struct target_sigaction *ka,
2995
                        target_sigset_t *set, CPUState *env)
2996
{
2997
        struct target_signal_frame *frame;
2998
        abi_ulong frame_addr;
2999
        int err = 0;
3000
        int i;
3001

    
3002
        frame_addr = get_sigframe(env, sizeof *frame);
3003
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3004
                goto badframe;
3005

    
3006
        /*
3007
         * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3008
         * use this trampoline anymore but it sets it up for GDB.
3009
         * In QEMU, using the trampoline simplifies things a bit so we use it.
3010
         *
3011
         * This is movu.w __NR_sigreturn, r9; break 13;
3012
         */
3013
        err |= __put_user(0x9c5f, frame->retcode+0);
3014
        err |= __put_user(TARGET_NR_sigreturn, 
3015
                          frame->retcode+2);
3016
        err |= __put_user(0xe93d, frame->retcode+4);
3017

    
3018
        /* Save the mask.  */
3019
        err |= __put_user(set->sig[0], &frame->sc.oldmask);
3020
        if (err)
3021
                goto badframe;
3022

    
3023
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3024
                if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3025
                        goto badframe;
3026
        }
3027

    
3028
        setup_sigcontext(&frame->sc, env);
3029

    
3030
        /* Move the stack and setup the arguments for the handler.  */
3031
        env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3032
        env->regs[10] = sig;
3033
        env->pc = (unsigned long) ka->_sa_handler;
3034
        /* Link SRP so the guest returns through the trampoline.  */
3035
        env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3036

    
3037
        unlock_user_struct(frame, frame_addr, 1);
3038
        return;
3039
  badframe:
3040
        unlock_user_struct(frame, frame_addr, 1);
3041
        force_sig(TARGET_SIGSEGV);
3042
}
3043

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

    
3051
long do_sigreturn(CPUState *env)
3052
{
3053
        struct target_signal_frame *frame;
3054
        abi_ulong frame_addr;
3055
        target_sigset_t target_set;
3056
        sigset_t set;
3057
        int i;
3058

    
3059
        frame_addr = env->regs[R_SP];
3060
        /* Make sure the guest isn't playing games.  */
3061
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3062
                goto badframe;
3063

    
3064
        /* Restore blocked signals */
3065
        if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3066
                goto badframe;
3067
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3068
                if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3069
                        goto badframe;
3070
        }
3071
        target_to_host_sigset_internal(&set, &target_set);
3072
        sigprocmask(SIG_SETMASK, &set, NULL);
3073

    
3074
        restore_sigcontext(&frame->sc, env);
3075
        unlock_user_struct(frame, frame_addr, 0);
3076
        return env->regs[10];
3077
  badframe:
3078
        unlock_user_struct(frame, frame_addr, 0);
3079
        force_sig(TARGET_SIGSEGV);
3080
}
3081

    
3082
long do_rt_sigreturn(CPUState *env)
3083
{
3084
    fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3085
    return -TARGET_ENOSYS;
3086
}
3087

    
3088
#else
3089

    
3090
static void setup_frame(int sig, struct target_sigaction *ka,
3091
                        target_sigset_t *set, CPUState *env)
3092
{
3093
    fprintf(stderr, "setup_frame: not implemented\n");
3094
}
3095

    
3096
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3097
                           target_siginfo_t *info,
3098
                           target_sigset_t *set, CPUState *env)
3099
{
3100
    fprintf(stderr, "setup_rt_frame: not implemented\n");
3101
}
3102

    
3103
long do_sigreturn(CPUState *env)
3104
{
3105
    fprintf(stderr, "do_sigreturn: not implemented\n");
3106
    return -TARGET_ENOSYS;
3107
}
3108

    
3109
long do_rt_sigreturn(CPUState *env)
3110
{
3111
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3112
    return -TARGET_ENOSYS;
3113
}
3114

    
3115
#endif
3116

    
3117
void process_pending_signals(CPUState *cpu_env)
3118
{
3119
    int sig;
3120
    abi_ulong handler;
3121
    sigset_t set, old_set;
3122
    target_sigset_t target_old_set;
3123
    struct emulated_sigtable *k;
3124
    struct target_sigaction *sa;
3125
    struct sigqueue *q;
3126
    TaskState *ts = cpu_env->opaque;
3127

    
3128
    if (!ts->signal_pending)
3129
        return;
3130

    
3131
    /* FIXME: This is not threadsafe.  */
3132
    k = ts->sigtab;
3133
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
3134
        if (k->pending)
3135
            goto handle_signal;
3136
        k++;
3137
    }
3138
    /* if no signal is pending, just return */
3139
    ts->signal_pending = 0;
3140
    return;
3141

    
3142
 handle_signal:
3143
#ifdef DEBUG_SIGNAL
3144
    fprintf(stderr, "qemu: process signal %d\n", sig);
3145
#endif
3146
    /* dequeue signal */
3147
    q = k->first;
3148
    k->first = q->next;
3149
    if (!k->first)
3150
        k->pending = 0;
3151

    
3152
    sig = gdb_handlesig (cpu_env, sig);
3153
    if (!sig) {
3154
        sa = NULL;
3155
        handler = TARGET_SIG_IGN;
3156
    } else {
3157
        sa = &sigact_table[sig - 1];
3158
        handler = sa->_sa_handler;
3159
    }
3160

    
3161
    if (handler == TARGET_SIG_DFL) {
3162
        /* default handler : ignore some signal. The other are job control or fatal */
3163
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
3164
            kill(getpid(),SIGSTOP);
3165
        } else if (sig != TARGET_SIGCHLD &&
3166
                   sig != TARGET_SIGURG &&
3167
                   sig != TARGET_SIGWINCH &&
3168
                   sig != TARGET_SIGCONT) {
3169
            force_sig(sig);
3170
        }
3171
    } else if (handler == TARGET_SIG_IGN) {
3172
        /* ignore sig */
3173
    } else if (handler == TARGET_SIG_ERR) {
3174
        force_sig(sig);
3175
    } else {
3176
        /* compute the blocked signals during the handler execution */
3177
        target_to_host_sigset(&set, &sa->sa_mask);
3178
        /* SA_NODEFER indicates that the current signal should not be
3179
           blocked during the handler */
3180
        if (!(sa->sa_flags & TARGET_SA_NODEFER))
3181
            sigaddset(&set, target_to_host_signal(sig));
3182

    
3183
        /* block signals in the handler using Linux */
3184
        sigprocmask(SIG_BLOCK, &set, &old_set);
3185
        /* save the previous blocked signal state to restore it at the
3186
           end of the signal execution (see do_sigreturn) */
3187
        host_to_target_sigset_internal(&target_old_set, &old_set);
3188

    
3189
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
3190
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
3191
        {
3192
            CPUX86State *env = cpu_env;
3193
            if (env->eflags & VM_MASK)
3194
                save_v86_state(env);
3195
        }
3196
#endif
3197
        /* prepare the stack frame of the virtual CPU */
3198
        if (sa->sa_flags & TARGET_SA_SIGINFO)
3199
            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3200
        else
3201
            setup_frame(sig, sa, &target_old_set, cpu_env);
3202
        if (sa->sa_flags & TARGET_SA_RESETHAND)
3203
            sa->_sa_handler = TARGET_SIG_DFL;
3204
    }
3205
    if (q != &k->info)
3206
        free_sigqueue(cpu_env, q);
3207
}