Statistics
| Branch: | Revision:

root / linux-user / signal.c @ b2178704

History | View | Annotate | Download (139.9 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, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <stdlib.h>
20
#include <stdio.h>
21
#include <string.h>
22
#include <stdarg.h>
23
#include <unistd.h>
24
#include <signal.h>
25
#include <errno.h>
26
#include <assert.h>
27
#include <sys/ucontext.h>
28
#include <sys/resource.h>
29

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

    
34
//#define DEBUG_SIGNAL
35

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

    
42
static struct target_sigaction sigact_table[TARGET_NSIG];
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
201
/* siginfo conversion */
202

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

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

    
249

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

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

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

    
289
/* returns 1 if given signal should dump core if not handled */
290
static int core_dump_signal(int sig)
291
{
292
    switch (sig) {
293
    case TARGET_SIGABRT:
294
    case TARGET_SIGFPE:
295
    case TARGET_SIGILL:
296
    case TARGET_SIGQUIT:
297
    case TARGET_SIGSEGV:
298
    case TARGET_SIGTRAP:
299
    case TARGET_SIGBUS:
300
        return (1);
301
    default:
302
        return (0);
303
    }
304
}
305

    
306
void signal_init(void)
307
{
308
    struct sigaction act;
309
    struct sigaction oact;
310
    int i, j;
311
    int host_sig;
312

    
313
    /* generate signal conversion tables */
314
    for(i = 1; i < _NSIG; i++) {
315
        if (host_to_target_signal_table[i] == 0)
316
            host_to_target_signal_table[i] = i;
317
    }
318
    for(i = 1; i < _NSIG; i++) {
319
        j = host_to_target_signal_table[i];
320
        target_to_host_signal_table[j] = i;
321
    }
322

    
323
    /* set all host signal handlers. ALL signals are blocked during
324
       the handlers to serialize them. */
325
    memset(sigact_table, 0, sizeof(sigact_table));
326

    
327
    sigfillset(&act.sa_mask);
328
    act.sa_flags = SA_SIGINFO;
329
    act.sa_sigaction = host_signal_handler;
330
    for(i = 1; i <= TARGET_NSIG; i++) {
331
        host_sig = target_to_host_signal(i);
332
        sigaction(host_sig, NULL, &oact);
333
        if (oact.sa_sigaction == (void *)SIG_IGN) {
334
            sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
335
        } else if (oact.sa_sigaction == (void *)SIG_DFL) {
336
            sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
337
        }
338
        /* If there's already a handler installed then something has
339
           gone horribly wrong, so don't even try to handle that case.  */
340
        /* Install some handlers for our own use.  We need at least
341
           SIGSEGV and SIGBUS, to detect exceptions.  We can not just
342
           trap all signals because it affects syscall interrupt
343
           behavior.  But do trap all default-fatal signals.  */
344
        if (fatal_signal (i))
345
            sigaction(host_sig, &act, NULL);
346
    }
347
}
348

    
349
/* signal queue handling */
350

    
351
static inline struct sigqueue *alloc_sigqueue(CPUState *env)
352
{
353
    TaskState *ts = env->opaque;
354
    struct sigqueue *q = ts->first_free;
355
    if (!q)
356
        return NULL;
357
    ts->first_free = q->next;
358
    return q;
359
}
360

    
361
static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
362
{
363
    TaskState *ts = env->opaque;
364
    q->next = ts->first_free;
365
    ts->first_free = q;
366
}
367

    
368
/* abort execution with signal */
369
static void QEMU_NORETURN force_sig(int target_sig)
370
{
371
    TaskState *ts = (TaskState *)thread_env->opaque;
372
    int host_sig, core_dumped = 0;
373
    struct sigaction act;
374
    host_sig = target_to_host_signal(target_sig);
375
    gdb_signalled(thread_env, target_sig);
376

    
377
    /* dump core if supported by target binary format */
378
    if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
379
        stop_all_tasks();
380
        core_dumped =
381
            ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
382
    }
383
    if (core_dumped) {
384
        /* we already dumped the core of target process, we don't want
385
         * a coredump of qemu itself */
386
        struct rlimit nodump;
387
        getrlimit(RLIMIT_CORE, &nodump);
388
        nodump.rlim_cur=0;
389
        setrlimit(RLIMIT_CORE, &nodump);
390
        (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
391
            target_sig, strsignal(host_sig), "core dumped" );
392
    }
393

    
394
    /* The proper exit code for dieing from an uncaught signal is
395
     * -<signal>.  The kernel doesn't allow exit() or _exit() to pass
396
     * a negative value.  To get the proper exit code we need to
397
     * actually die from an uncaught signal.  Here the default signal
398
     * handler is installed, we send ourself a signal and we wait for
399
     * it to arrive. */
400
    sigfillset(&act.sa_mask);
401
    act.sa_handler = SIG_DFL;
402
    sigaction(host_sig, &act, NULL);
403

    
404
    /* For some reason raise(host_sig) doesn't send the signal when
405
     * statically linked on x86-64. */
406
    kill(getpid(), host_sig);
407

    
408
    /* Make sure the signal isn't masked (just reuse the mask inside
409
    of act) */
410
    sigdelset(&act.sa_mask, host_sig);
411
    sigsuspend(&act.sa_mask);
412

    
413
    /* unreachable */
414
    abort();
415
}
416

    
417
/* queue a signal so that it will be send to the virtual CPU as soon
418
   as possible */
419
int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
420
{
421
    TaskState *ts = env->opaque;
422
    struct emulated_sigtable *k;
423
    struct sigqueue *q, **pq;
424
    abi_ulong handler;
425
    int queue;
426

    
427
#if defined(DEBUG_SIGNAL)
428
    fprintf(stderr, "queue_signal: sig=%d\n",
429
            sig);
430
#endif
431
    k = &ts->sigtab[sig - 1];
432
    queue = gdb_queuesig ();
433
    handler = sigact_table[sig - 1]._sa_handler;
434
    if (!queue && handler == TARGET_SIG_DFL) {
435
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
436
            kill(getpid(),SIGSTOP);
437
            return 0;
438
        } else
439
        /* default handler : ignore some signal. The other are fatal */
440
        if (sig != TARGET_SIGCHLD &&
441
            sig != TARGET_SIGURG &&
442
            sig != TARGET_SIGWINCH &&
443
            sig != TARGET_SIGCONT) {
444
            force_sig(sig);
445
        } else {
446
            return 0; /* indicate ignored */
447
        }
448
    } else if (!queue && handler == TARGET_SIG_IGN) {
449
        /* ignore signal */
450
        return 0;
451
    } else if (!queue && handler == TARGET_SIG_ERR) {
452
        force_sig(sig);
453
    } else {
454
        pq = &k->first;
455
        if (sig < TARGET_SIGRTMIN) {
456
            /* if non real time signal, we queue exactly one signal */
457
            if (!k->pending)
458
                q = &k->info;
459
            else
460
                return 0;
461
        } else {
462
            if (!k->pending) {
463
                /* first signal */
464
                q = &k->info;
465
            } else {
466
                q = alloc_sigqueue(env);
467
                if (!q)
468
                    return -EAGAIN;
469
                while (*pq != NULL)
470
                    pq = &(*pq)->next;
471
            }
472
        }
473
        *pq = q;
474
        q->info = *info;
475
        q->next = NULL;
476
        k->pending = 1;
477
        /* signal that a new signal is pending */
478
        ts->signal_pending = 1;
479
        return 1; /* indicates that the signal was queued */
480
    }
481
}
482

    
483
static void host_signal_handler(int host_signum, siginfo_t *info,
484
                                void *puc)
485
{
486
    int sig;
487
    target_siginfo_t tinfo;
488

    
489
    /* the CPU emulator uses some host signals to detect exceptions,
490
       we forward to it some signals */
491
    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
492
        && info->si_code > 0) {
493
        if (cpu_signal_handler(host_signum, info, puc))
494
            return;
495
    }
496

    
497
    /* get target signal number */
498
    sig = host_to_target_signal(host_signum);
499
    if (sig < 1 || sig > TARGET_NSIG)
500
        return;
501
#if defined(DEBUG_SIGNAL)
502
    fprintf(stderr, "qemu: got signal %d\n", sig);
503
#endif
504
    host_to_target_siginfo_noswap(&tinfo, info);
505
    if (queue_signal(thread_env, sig, &tinfo) == 1) {
506
        /* interrupt the virtual CPU as soon as possible */
507
        cpu_exit(thread_env);
508
    }
509
}
510

    
511
/* do_sigaltstack() returns target values and errnos. */
512
/* compare linux/kernel/signal.c:do_sigaltstack() */
513
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
514
{
515
    int ret;
516
    struct target_sigaltstack oss;
517

    
518
    /* XXX: test errors */
519
    if(uoss_addr)
520
    {
521
        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
522
        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
523
        __put_user(sas_ss_flags(sp), &oss.ss_flags);
524
    }
525

    
526
    if(uss_addr)
527
    {
528
        struct target_sigaltstack *uss;
529
        struct target_sigaltstack ss;
530

    
531
        ret = -TARGET_EFAULT;
532
        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
533
            || __get_user(ss.ss_sp, &uss->ss_sp)
534
            || __get_user(ss.ss_size, &uss->ss_size)
535
            || __get_user(ss.ss_flags, &uss->ss_flags))
536
            goto out;
537
        unlock_user_struct(uss, uss_addr, 0);
538

    
539
        ret = -TARGET_EPERM;
540
        if (on_sig_stack(sp))
541
            goto out;
542

    
543
        ret = -TARGET_EINVAL;
544
        if (ss.ss_flags != TARGET_SS_DISABLE
545
            && ss.ss_flags != TARGET_SS_ONSTACK
546
            && ss.ss_flags != 0)
547
            goto out;
548

    
549
        if (ss.ss_flags == TARGET_SS_DISABLE) {
550
            ss.ss_size = 0;
551
            ss.ss_sp = 0;
552
        } else {
553
            ret = -TARGET_ENOMEM;
554
            if (ss.ss_size < MINSIGSTKSZ)
555
                goto out;
556
        }
557

    
558
        target_sigaltstack_used.ss_sp = ss.ss_sp;
559
        target_sigaltstack_used.ss_size = ss.ss_size;
560
    }
561

    
562
    if (uoss_addr) {
563
        ret = -TARGET_EFAULT;
564
        if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
565
            goto out;
566
    }
567

    
568
    ret = 0;
569
out:
570
    return ret;
571
}
572

    
573
/* do_sigaction() return host values and errnos */
574
int do_sigaction(int sig, const struct target_sigaction *act,
575
                 struct target_sigaction *oact)
576
{
577
    struct target_sigaction *k;
578
    struct sigaction act1;
579
    int host_sig;
580
    int ret = 0;
581

    
582
    if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
583
        return -EINVAL;
584
    k = &sigact_table[sig - 1];
585
#if defined(DEBUG_SIGNAL)
586
    fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
587
            sig, act, oact);
588
#endif
589
    if (oact) {
590
        oact->_sa_handler = tswapl(k->_sa_handler);
591
        oact->sa_flags = tswapl(k->sa_flags);
592
#if !defined(TARGET_MIPS)
593
        oact->sa_restorer = tswapl(k->sa_restorer);
594
#endif
595
        oact->sa_mask = k->sa_mask;
596
    }
597
    if (act) {
598
        /* FIXME: This is not threadsafe.  */
599
        k->_sa_handler = tswapl(act->_sa_handler);
600
        k->sa_flags = tswapl(act->sa_flags);
601
#if !defined(TARGET_MIPS)
602
        k->sa_restorer = tswapl(act->sa_restorer);
603
#endif
604
        k->sa_mask = act->sa_mask;
605

    
606
        /* we update the host linux signal state */
607
        host_sig = target_to_host_signal(sig);
608
        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
609
            sigfillset(&act1.sa_mask);
610
            act1.sa_flags = SA_SIGINFO;
611
            if (k->sa_flags & TARGET_SA_RESTART)
612
                act1.sa_flags |= SA_RESTART;
613
            /* NOTE: it is important to update the host kernel signal
614
               ignore state to avoid getting unexpected interrupted
615
               syscalls */
616
            if (k->_sa_handler == TARGET_SIG_IGN) {
617
                act1.sa_sigaction = (void *)SIG_IGN;
618
            } else if (k->_sa_handler == TARGET_SIG_DFL) {
619
                if (fatal_signal (sig))
620
                    act1.sa_sigaction = host_signal_handler;
621
                else
622
                    act1.sa_sigaction = (void *)SIG_DFL;
623
            } else {
624
                act1.sa_sigaction = host_signal_handler;
625
            }
626
            ret = sigaction(host_sig, &act1, NULL);
627
        }
628
    }
629
    return ret;
630
}
631

    
632
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
633
                                       const target_siginfo_t *info)
634
{
635
    tswap_siginfo(tinfo, info);
636
    return 0;
637
}
638

    
639
static inline int current_exec_domain_sig(int sig)
640
{
641
    return /* current->exec_domain && current->exec_domain->signal_invmap
642
              && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
643
}
644

    
645
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
646

    
647
/* from the Linux kernel */
648

    
649
struct target_fpreg {
650
        uint16_t significand[4];
651
        uint16_t exponent;
652
};
653

    
654
struct target_fpxreg {
655
        uint16_t significand[4];
656
        uint16_t exponent;
657
        uint16_t padding[3];
658
};
659

    
660
struct target_xmmreg {
661
        abi_ulong element[4];
662
};
663

    
664
struct target_fpstate {
665
        /* Regular FPU environment */
666
        abi_ulong       cw;
667
        abi_ulong       sw;
668
        abi_ulong       tag;
669
        abi_ulong       ipoff;
670
        abi_ulong       cssel;
671
        abi_ulong       dataoff;
672
        abi_ulong       datasel;
673
        struct target_fpreg        _st[8];
674
        uint16_t        status;
675
        uint16_t        magic;                /* 0xffff = regular FPU data only */
676

    
677
        /* FXSR FPU environment */
678
        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
679
        abi_ulong       mxcsr;
680
        abi_ulong       reserved;
681
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
682
        struct target_xmmreg        _xmm[8];
683
        abi_ulong       padding[56];
684
};
685

    
686
#define X86_FXSR_MAGIC                0x0000
687

    
688
struct target_sigcontext {
689
        uint16_t gs, __gsh;
690
        uint16_t fs, __fsh;
691
        uint16_t es, __esh;
692
        uint16_t ds, __dsh;
693
        abi_ulong edi;
694
        abi_ulong esi;
695
        abi_ulong ebp;
696
        abi_ulong esp;
697
        abi_ulong ebx;
698
        abi_ulong edx;
699
        abi_ulong ecx;
700
        abi_ulong eax;
701
        abi_ulong trapno;
702
        abi_ulong err;
703
        abi_ulong eip;
704
        uint16_t cs, __csh;
705
        abi_ulong eflags;
706
        abi_ulong esp_at_signal;
707
        uint16_t ss, __ssh;
708
        abi_ulong fpstate; /* pointer */
709
        abi_ulong oldmask;
710
        abi_ulong cr2;
711
};
712

    
713
struct target_ucontext {
714
        abi_ulong         tuc_flags;
715
        abi_ulong         tuc_link;
716
        target_stack_t          tuc_stack;
717
        struct target_sigcontext tuc_mcontext;
718
        target_sigset_t          tuc_sigmask;        /* mask last for extensibility */
719
};
720

    
721
struct sigframe
722
{
723
    abi_ulong pretcode;
724
    int sig;
725
    struct target_sigcontext sc;
726
    struct target_fpstate fpstate;
727
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
728
    char retcode[8];
729
};
730

    
731
struct rt_sigframe
732
{
733
    abi_ulong pretcode;
734
    int sig;
735
    abi_ulong pinfo;
736
    abi_ulong puc;
737
    struct target_siginfo info;
738
    struct target_ucontext uc;
739
    struct target_fpstate fpstate;
740
    char retcode[8];
741
};
742

    
743
/*
744
 * Set up a signal frame.
745
 */
746

    
747
/* XXX: save x87 state */
748
static int
749
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
750
                 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
751
{
752
        int err = 0;
753
        uint16_t magic;
754

    
755
        /* already locked in setup_frame() */
756
        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
757
        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
758
        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
759
        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
760
        err |= __put_user(env->regs[R_EDI], &sc->edi);
761
        err |= __put_user(env->regs[R_ESI], &sc->esi);
762
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
763
        err |= __put_user(env->regs[R_ESP], &sc->esp);
764
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
765
        err |= __put_user(env->regs[R_EDX], &sc->edx);
766
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
767
        err |= __put_user(env->regs[R_EAX], &sc->eax);
768
        err |= __put_user(env->exception_index, &sc->trapno);
769
        err |= __put_user(env->error_code, &sc->err);
770
        err |= __put_user(env->eip, &sc->eip);
771
        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
772
        err |= __put_user(env->eflags, &sc->eflags);
773
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
774
        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
775

    
776
        cpu_x86_fsave(env, fpstate_addr, 1);
777
        fpstate->status = fpstate->sw;
778
        magic = 0xffff;
779
        err |= __put_user(magic, &fpstate->magic);
780
        err |= __put_user(fpstate_addr, &sc->fpstate);
781

    
782
        /* non-iBCS2 extensions.. */
783
        err |= __put_user(mask, &sc->oldmask);
784
        err |= __put_user(env->cr[2], &sc->cr2);
785
        return err;
786
}
787

    
788
/*
789
 * Determine which stack to use..
790
 */
791

    
792
static inline abi_ulong
793
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
794
{
795
        unsigned long esp;
796

    
797
        /* Default to using normal stack */
798
        esp = env->regs[R_ESP];
799
        /* This is the X/Open sanctioned signal stack switching.  */
800
        if (ka->sa_flags & TARGET_SA_ONSTACK) {
801
            if (sas_ss_flags(esp) == 0)
802
                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
803
        }
804

    
805
        /* This is the legacy signal stack switching. */
806
        else
807
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
808
            !(ka->sa_flags & TARGET_SA_RESTORER) &&
809
            ka->sa_restorer) {
810
            esp = (unsigned long) ka->sa_restorer;
811
        }
812
        return (esp - frame_size) & -8ul;
813
}
814

    
815
/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
816
static void setup_frame(int sig, struct target_sigaction *ka,
817
                        target_sigset_t *set, CPUX86State *env)
818
{
819
        abi_ulong frame_addr;
820
        struct sigframe *frame;
821
        int i, err = 0;
822

    
823
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
824

    
825
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
826
                goto give_sigsegv;
827

    
828
        err |= __put_user(current_exec_domain_sig(sig),
829
                          &frame->sig);
830
        if (err)
831
                goto give_sigsegv;
832

    
833
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
834
                         frame_addr + offsetof(struct sigframe, fpstate));
835
        if (err)
836
                goto give_sigsegv;
837

    
838
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
839
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
840
                goto give_sigsegv;
841
        }
842

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

    
860
        if (err)
861
                goto give_sigsegv;
862

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

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

    
873
        unlock_user_struct(frame, frame_addr, 1);
874

    
875
        return;
876

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

    
884
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
885
static void setup_rt_frame(int sig, struct target_sigaction *ka,
886
                           target_siginfo_t *info,
887
                           target_sigset_t *set, CPUX86State *env)
888
{
889
        abi_ulong frame_addr, addr;
890
        struct rt_sigframe *frame;
891
        int i, err = 0;
892

    
893
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
894

    
895
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
896
                goto give_sigsegv;
897

    
898
        err |= __put_user(current_exec_domain_sig(sig),
899
                          &frame->sig);
900
        addr = frame_addr + offsetof(struct rt_sigframe, info);
901
        err |= __put_user(addr, &frame->pinfo);
902
        addr = frame_addr + offsetof(struct rt_sigframe, uc);
903
        err |= __put_user(addr, &frame->puc);
904
        err |= copy_siginfo_to_user(&frame->info, info);
905
        if (err)
906
                goto give_sigsegv;
907

    
908
        /* Create the ucontext.  */
909
        err |= __put_user(0, &frame->uc.tuc_flags);
910
        err |= __put_user(0, &frame->uc.tuc_link);
911
        err |= __put_user(target_sigaltstack_used.ss_sp,
912
                          &frame->uc.tuc_stack.ss_sp);
913
        err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
914
                          &frame->uc.tuc_stack.ss_flags);
915
        err |= __put_user(target_sigaltstack_used.ss_size,
916
                          &frame->uc.tuc_stack.ss_size);
917
        err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
918
                                env, set->sig[0], 
919
                                frame_addr + offsetof(struct rt_sigframe, fpstate));
920
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
921
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
922
                goto give_sigsegv;
923
        }
924

    
925
        /* Set up to return from userspace.  If provided, use a stub
926
           already in userspace.  */
927
        if (ka->sa_flags & TARGET_SA_RESTORER) {
928
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
929
        } else {
930
                uint16_t val16;
931
                addr = frame_addr + offsetof(struct rt_sigframe, retcode);
932
                err |= __put_user(addr, &frame->pretcode);
933
                /* This is movl $,%eax ; int $0x80 */
934
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
935
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
936
                val16 = 0x80cd;
937
                err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
938
        }
939

    
940
        if (err)
941
                goto give_sigsegv;
942

    
943
        /* Set up registers for signal handler */
944
        env->regs[R_ESP] = frame_addr;
945
        env->eip = ka->_sa_handler;
946

    
947
        cpu_x86_load_seg(env, R_DS, __USER_DS);
948
        cpu_x86_load_seg(env, R_ES, __USER_DS);
949
        cpu_x86_load_seg(env, R_SS, __USER_DS);
950
        cpu_x86_load_seg(env, R_CS, __USER_CS);
951
        env->eflags &= ~TF_MASK;
952

    
953
        unlock_user_struct(frame, frame_addr, 1);
954

    
955
        return;
956

    
957
give_sigsegv:
958
        unlock_user_struct(frame, frame_addr, 1);
959
        if (sig == TARGET_SIGSEGV)
960
                ka->_sa_handler = TARGET_SIG_DFL;
961
        force_sig(TARGET_SIGSEGV /* , current */);
962
}
963

    
964
static int
965
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
966
{
967
        unsigned int err = 0;
968
        abi_ulong fpstate_addr;
969
        unsigned int tmpflags;
970

    
971
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
972
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
973
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
974
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
975

    
976
        env->regs[R_EDI] = tswapl(sc->edi);
977
        env->regs[R_ESI] = tswapl(sc->esi);
978
        env->regs[R_EBP] = tswapl(sc->ebp);
979
        env->regs[R_ESP] = tswapl(sc->esp);
980
        env->regs[R_EBX] = tswapl(sc->ebx);
981
        env->regs[R_EDX] = tswapl(sc->edx);
982
        env->regs[R_ECX] = tswapl(sc->ecx);
983
        env->eip = tswapl(sc->eip);
984

    
985
        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
986
        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
987

    
988
        tmpflags = tswapl(sc->eflags);
989
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
990
        //                regs->orig_eax = -1;                /* disable syscall checks */
991

    
992
        fpstate_addr = tswapl(sc->fpstate);
993
        if (fpstate_addr != 0) {
994
                if (!access_ok(VERIFY_READ, fpstate_addr, 
995
                               sizeof(struct target_fpstate)))
996
                        goto badframe;
997
                cpu_x86_frstor(env, fpstate_addr, 1);
998
        }
999

    
1000
        *peax = tswapl(sc->eax);
1001
        return err;
1002
badframe:
1003
        return 1;
1004
}
1005

    
1006
long do_sigreturn(CPUX86State *env)
1007
{
1008
    struct sigframe *frame;
1009
    abi_ulong frame_addr = env->regs[R_ESP] - 8;
1010
    target_sigset_t target_set;
1011
    sigset_t set;
1012
    int eax, i;
1013

    
1014
#if defined(DEBUG_SIGNAL)
1015
    fprintf(stderr, "do_sigreturn\n");
1016
#endif
1017
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1018
        goto badframe;
1019
    /* set blocked signals */
1020
    if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1021
        goto badframe;
1022
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1023
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1024
            goto badframe;
1025
    }
1026

    
1027
    target_to_host_sigset_internal(&set, &target_set);
1028
    sigprocmask(SIG_SETMASK, &set, NULL);
1029

    
1030
    /* restore registers */
1031
    if (restore_sigcontext(env, &frame->sc, &eax))
1032
        goto badframe;
1033
    unlock_user_struct(frame, frame_addr, 0);
1034
    return eax;
1035

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

    
1042
long do_rt_sigreturn(CPUX86State *env)
1043
{
1044
        abi_ulong frame_addr;
1045
        struct rt_sigframe *frame;
1046
        sigset_t set;
1047
        int eax;
1048

    
1049
        frame_addr = env->regs[R_ESP] - 4;
1050
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1051
                goto badframe;
1052
        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1053
        sigprocmask(SIG_SETMASK, &set, NULL);
1054

    
1055
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1056
                goto badframe;
1057

    
1058
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
1059
                           get_sp_from_cpustate(env)) == -EFAULT)
1060
                goto badframe;
1061

    
1062
        unlock_user_struct(frame, frame_addr, 0);
1063
        return eax;
1064

    
1065
badframe:
1066
        unlock_user_struct(frame, frame_addr, 0);
1067
        force_sig(TARGET_SIGSEGV);
1068
        return 0;
1069
}
1070

    
1071
#elif defined(TARGET_ARM)
1072

    
1073
struct target_sigcontext {
1074
        abi_ulong trap_no;
1075
        abi_ulong error_code;
1076
        abi_ulong oldmask;
1077
        abi_ulong arm_r0;
1078
        abi_ulong arm_r1;
1079
        abi_ulong arm_r2;
1080
        abi_ulong arm_r3;
1081
        abi_ulong arm_r4;
1082
        abi_ulong arm_r5;
1083
        abi_ulong arm_r6;
1084
        abi_ulong arm_r7;
1085
        abi_ulong arm_r8;
1086
        abi_ulong arm_r9;
1087
        abi_ulong arm_r10;
1088
        abi_ulong arm_fp;
1089
        abi_ulong arm_ip;
1090
        abi_ulong arm_sp;
1091
        abi_ulong arm_lr;
1092
        abi_ulong arm_pc;
1093
        abi_ulong arm_cpsr;
1094
        abi_ulong fault_address;
1095
};
1096

    
1097
struct target_ucontext_v1 {
1098
    abi_ulong tuc_flags;
1099
    abi_ulong tuc_link;
1100
    target_stack_t tuc_stack;
1101
    struct target_sigcontext tuc_mcontext;
1102
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1103
};
1104

    
1105
struct target_ucontext_v2 {
1106
    abi_ulong tuc_flags;
1107
    abi_ulong tuc_link;
1108
    target_stack_t tuc_stack;
1109
    struct target_sigcontext tuc_mcontext;
1110
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1111
    char __unused[128 - sizeof(sigset_t)];
1112
    abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1113
};
1114

    
1115
struct sigframe_v1
1116
{
1117
    struct target_sigcontext sc;
1118
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
1119
    abi_ulong retcode;
1120
};
1121

    
1122
struct sigframe_v2
1123
{
1124
    struct target_ucontext_v2 uc;
1125
    abi_ulong retcode;
1126
};
1127

    
1128
struct rt_sigframe_v1
1129
{
1130
    abi_ulong pinfo;
1131
    abi_ulong puc;
1132
    struct target_siginfo info;
1133
    struct target_ucontext_v1 uc;
1134
    abi_ulong retcode;
1135
};
1136

    
1137
struct rt_sigframe_v2
1138
{
1139
    struct target_siginfo info;
1140
    struct target_ucontext_v2 uc;
1141
    abi_ulong retcode;
1142
};
1143

    
1144
#define TARGET_CONFIG_CPU_32 1
1145

    
1146
/*
1147
 * For ARM syscalls, we encode the syscall number into the instruction.
1148
 */
1149
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1150
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1151

    
1152
/*
1153
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
1154
 * need two 16-bit instructions.
1155
 */
1156
#define SWI_THUMB_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1157
#define SWI_THUMB_RT_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1158

    
1159
static const abi_ulong retcodes[4] = {
1160
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
1161
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
1162
};
1163

    
1164

    
1165
#define __get_user_error(x,p,e) __get_user(x, p)
1166

    
1167
static inline int valid_user_regs(CPUState *regs)
1168
{
1169
    return 1;
1170
}
1171

    
1172
static void
1173
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1174
                 CPUState *env, abi_ulong mask)
1175
{
1176
        __put_user(env->regs[0], &sc->arm_r0);
1177
        __put_user(env->regs[1], &sc->arm_r1);
1178
        __put_user(env->regs[2], &sc->arm_r2);
1179
        __put_user(env->regs[3], &sc->arm_r3);
1180
        __put_user(env->regs[4], &sc->arm_r4);
1181
        __put_user(env->regs[5], &sc->arm_r5);
1182
        __put_user(env->regs[6], &sc->arm_r6);
1183
        __put_user(env->regs[7], &sc->arm_r7);
1184
        __put_user(env->regs[8], &sc->arm_r8);
1185
        __put_user(env->regs[9], &sc->arm_r9);
1186
        __put_user(env->regs[10], &sc->arm_r10);
1187
        __put_user(env->regs[11], &sc->arm_fp);
1188
        __put_user(env->regs[12], &sc->arm_ip);
1189
        __put_user(env->regs[13], &sc->arm_sp);
1190
        __put_user(env->regs[14], &sc->arm_lr);
1191
        __put_user(env->regs[15], &sc->arm_pc);
1192
#ifdef TARGET_CONFIG_CPU_32
1193
        __put_user(cpsr_read(env), &sc->arm_cpsr);
1194
#endif
1195

    
1196
        __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1197
        __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1198
        __put_user(/* current->thread.address */ 0, &sc->fault_address);
1199
        __put_user(mask, &sc->oldmask);
1200
}
1201

    
1202
static inline abi_ulong
1203
get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1204
{
1205
        unsigned long sp = regs->regs[13];
1206

    
1207
        /*
1208
         * This is the X/Open sanctioned signal stack switching.
1209
         */
1210
        if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1211
            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1212
        /*
1213
         * ATPCS B01 mandates 8-byte alignment
1214
         */
1215
        return (sp - framesize) & ~7;
1216
}
1217

    
1218
static int
1219
setup_return(CPUState *env, struct target_sigaction *ka,
1220
             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1221
{
1222
        abi_ulong handler = ka->_sa_handler;
1223
        abi_ulong retcode;
1224
        int thumb = handler & 1;
1225

    
1226
        if (ka->sa_flags & TARGET_SA_RESTORER) {
1227
                retcode = ka->sa_restorer;
1228
        } else {
1229
                unsigned int idx = thumb;
1230

    
1231
                if (ka->sa_flags & TARGET_SA_SIGINFO)
1232
                        idx += 2;
1233

    
1234
                if (__put_user(retcodes[idx], rc))
1235
                        return 1;
1236
#if 0
1237
                flush_icache_range((abi_ulong)rc,
1238
                                   (abi_ulong)(rc + 1));
1239
#endif
1240
                retcode = rc_addr + thumb;
1241
        }
1242

    
1243
        env->regs[0] = usig;
1244
        env->regs[13] = frame_addr;
1245
        env->regs[14] = retcode;
1246
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1247
        env->thumb = thumb;
1248

    
1249
#if 0
1250
#ifdef TARGET_CONFIG_CPU_32
1251
        env->cpsr = cpsr;
1252
#endif
1253
#endif
1254

    
1255
        return 0;
1256
}
1257

    
1258
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1259
                              target_sigset_t *set, CPUState *env)
1260
{
1261
    struct target_sigaltstack stack;
1262
    int i;
1263

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

    
1267
    memset(&stack, 0, sizeof(stack));
1268
    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1269
    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1270
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1271
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1272

    
1273
    setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1274
    /* FIXME: Save coprocessor signal frame.  */
1275
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1276
        __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1277
    }
1278
}
1279

    
1280
/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1281
static void setup_frame_v1(int usig, struct target_sigaction *ka,
1282
                           target_sigset_t *set, CPUState *regs)
1283
{
1284
        struct sigframe_v1 *frame;
1285
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1286
        int i;
1287

    
1288
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1289
                return;
1290

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

    
1293
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1294
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1295
                goto end;
1296
        }
1297

    
1298
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1299
                     frame_addr + offsetof(struct sigframe_v1, retcode));
1300

    
1301
end:
1302
        unlock_user_struct(frame, frame_addr, 1);
1303
}
1304

    
1305
static void setup_frame_v2(int usig, struct target_sigaction *ka,
1306
                           target_sigset_t *set, CPUState *regs)
1307
{
1308
        struct sigframe_v2 *frame;
1309
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1310

    
1311
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1312
                return;
1313

    
1314
        setup_sigframe_v2(&frame->uc, set, regs);
1315

    
1316
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1317
                     frame_addr + offsetof(struct sigframe_v2, retcode));
1318

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

    
1322
static void setup_frame(int usig, struct target_sigaction *ka,
1323
                        target_sigset_t *set, CPUState *regs)
1324
{
1325
    if (get_osversion() >= 0x020612) {
1326
        setup_frame_v2(usig, ka, set, regs);
1327
    } else {
1328
        setup_frame_v1(usig, ka, set, regs);
1329
    }
1330
}
1331

    
1332
/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1333
static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1334
                              target_siginfo_t *info,
1335
                              target_sigset_t *set, CPUState *env)
1336
{
1337
        struct rt_sigframe_v1 *frame;
1338
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1339
        struct target_sigaltstack stack;
1340
        int i;
1341
        abi_ulong info_addr, uc_addr;
1342

    
1343
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1344
            return /* 1 */;
1345

    
1346
        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1347
        __put_user(info_addr, &frame->pinfo);
1348
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1349
        __put_user(uc_addr, &frame->puc);
1350
        copy_siginfo_to_user(&frame->info, info);
1351

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

    
1355
        memset(&stack, 0, sizeof(stack));
1356
        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1357
        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1358
        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1359
        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1360

    
1361
        setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1362
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1363
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1364
                goto end;
1365
        }
1366

    
1367
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1368
                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1369

    
1370
        env->regs[1] = info_addr;
1371
        env->regs[2] = uc_addr;
1372

    
1373
end:
1374
        unlock_user_struct(frame, frame_addr, 1);
1375
}
1376

    
1377
static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1378
                              target_siginfo_t *info,
1379
                              target_sigset_t *set, CPUState *env)
1380
{
1381
        struct rt_sigframe_v2 *frame;
1382
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1383
        abi_ulong info_addr, uc_addr;
1384

    
1385
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1386
            return /* 1 */;
1387

    
1388
        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1389
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1390
        copy_siginfo_to_user(&frame->info, info);
1391

    
1392
        setup_sigframe_v2(&frame->uc, set, env);
1393

    
1394
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1395
                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1396

    
1397
        env->regs[1] = info_addr;
1398
        env->regs[2] = uc_addr;
1399

    
1400
        unlock_user_struct(frame, frame_addr, 1);
1401
}
1402

    
1403
static void setup_rt_frame(int usig, struct target_sigaction *ka,
1404
                           target_siginfo_t *info,
1405
                           target_sigset_t *set, CPUState *env)
1406
{
1407
    if (get_osversion() >= 0x020612) {
1408
        setup_rt_frame_v2(usig, ka, info, set, env);
1409
    } else {
1410
        setup_rt_frame_v1(usig, ka, info, set, env);
1411
    }
1412
}
1413

    
1414
static int
1415
restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1416
{
1417
        int err = 0;
1418
        uint32_t cpsr;
1419

    
1420
        __get_user_error(env->regs[0], &sc->arm_r0, err);
1421
        __get_user_error(env->regs[1], &sc->arm_r1, err);
1422
        __get_user_error(env->regs[2], &sc->arm_r2, err);
1423
        __get_user_error(env->regs[3], &sc->arm_r3, err);
1424
        __get_user_error(env->regs[4], &sc->arm_r4, err);
1425
        __get_user_error(env->regs[5], &sc->arm_r5, err);
1426
        __get_user_error(env->regs[6], &sc->arm_r6, err);
1427
        __get_user_error(env->regs[7], &sc->arm_r7, err);
1428
        __get_user_error(env->regs[8], &sc->arm_r8, err);
1429
        __get_user_error(env->regs[9], &sc->arm_r9, err);
1430
        __get_user_error(env->regs[10], &sc->arm_r10, err);
1431
        __get_user_error(env->regs[11], &sc->arm_fp, err);
1432
        __get_user_error(env->regs[12], &sc->arm_ip, err);
1433
        __get_user_error(env->regs[13], &sc->arm_sp, err);
1434
        __get_user_error(env->regs[14], &sc->arm_lr, err);
1435
        __get_user_error(env->regs[15], &sc->arm_pc, err);
1436
#ifdef TARGET_CONFIG_CPU_32
1437
        __get_user_error(cpsr, &sc->arm_cpsr, err);
1438
        cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1439
#endif
1440

    
1441
        err |= !valid_user_regs(env);
1442

    
1443
        return err;
1444
}
1445

    
1446
static long do_sigreturn_v1(CPUState *env)
1447
{
1448
        abi_ulong frame_addr;
1449
        struct sigframe_v1 *frame;
1450
        target_sigset_t set;
1451
        sigset_t host_set;
1452
        int i;
1453

    
1454
        /*
1455
         * Since we stacked the signal on a 64-bit boundary,
1456
         * then 'sp' should be word aligned here.  If it's
1457
         * not, then the user is trying to mess with us.
1458
         */
1459
        if (env->regs[13] & 7)
1460
                goto badframe;
1461

    
1462
        frame_addr = env->regs[13];
1463
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1464
                goto badframe;
1465

    
1466
        if (__get_user(set.sig[0], &frame->sc.oldmask))
1467
            goto badframe;
1468
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1469
            if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1470
                goto badframe;
1471
        }
1472

    
1473
        target_to_host_sigset_internal(&host_set, &set);
1474
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1475

    
1476
        if (restore_sigcontext(env, &frame->sc))
1477
                goto badframe;
1478

    
1479
#if 0
1480
        /* Send SIGTRAP if we're single-stepping */
1481
        if (ptrace_cancel_bpt(current))
1482
                send_sig(SIGTRAP, current, 1);
1483
#endif
1484
        unlock_user_struct(frame, frame_addr, 0);
1485
        return env->regs[0];
1486

    
1487
badframe:
1488
        unlock_user_struct(frame, frame_addr, 0);
1489
        force_sig(TARGET_SIGSEGV /* , current */);
1490
        return 0;
1491
}
1492

    
1493
static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1494
                                 struct target_ucontext_v2 *uc)
1495
{
1496
    sigset_t host_set;
1497

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

    
1501
    if (restore_sigcontext(env, &uc->tuc_mcontext))
1502
        return 1;
1503

    
1504
    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1505
        return 1;
1506

    
1507
#if 0
1508
    /* Send SIGTRAP if we're single-stepping */
1509
    if (ptrace_cancel_bpt(current))
1510
            send_sig(SIGTRAP, current, 1);
1511
#endif
1512

    
1513
    return 0;
1514
}
1515

    
1516
static long do_sigreturn_v2(CPUState *env)
1517
{
1518
        abi_ulong frame_addr;
1519
        struct sigframe_v2 *frame;
1520

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

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

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

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

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

    
1545
long do_sigreturn(CPUState *env)
1546
{
1547
    if (get_osversion() >= 0x020612) {
1548
        return do_sigreturn_v2(env);
1549
    } else {
1550
        return do_sigreturn_v1(env);
1551
    }
1552
}
1553

    
1554
static long do_rt_sigreturn_v1(CPUState *env)
1555
{
1556
        abi_ulong frame_addr;
1557
        struct rt_sigframe_v1 *frame;
1558
        sigset_t host_set;
1559

    
1560
        /*
1561
         * Since we stacked the signal on a 64-bit boundary,
1562
         * then 'sp' should be word aligned here.  If it's
1563
         * not, then the user is trying to mess with us.
1564
         */
1565
        if (env->regs[13] & 7)
1566
                goto badframe;
1567

    
1568
        frame_addr = env->regs[13];
1569
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1570
                goto badframe;
1571

    
1572
        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1573
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1574

    
1575
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1576
                goto badframe;
1577

    
1578
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1579
                goto badframe;
1580

    
1581
#if 0
1582
        /* Send SIGTRAP if we're single-stepping */
1583
        if (ptrace_cancel_bpt(current))
1584
                send_sig(SIGTRAP, current, 1);
1585
#endif
1586
        unlock_user_struct(frame, frame_addr, 0);
1587
        return env->regs[0];
1588

    
1589
badframe:
1590
        unlock_user_struct(frame, frame_addr, 0);
1591
        force_sig(TARGET_SIGSEGV /* , current */);
1592
        return 0;
1593
}
1594

    
1595
static long do_rt_sigreturn_v2(CPUState *env)
1596
{
1597
        abi_ulong frame_addr;
1598
        struct rt_sigframe_v2 *frame;
1599

    
1600
        /*
1601
         * Since we stacked the signal on a 64-bit boundary,
1602
         * then 'sp' should be word aligned here.  If it's
1603
         * not, then the user is trying to mess with us.
1604
         */
1605
        if (env->regs[13] & 7)
1606
                goto badframe;
1607

    
1608
        frame_addr = env->regs[13];
1609
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1610
                goto badframe;
1611

    
1612
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1613
                goto badframe;
1614

    
1615
        unlock_user_struct(frame, frame_addr, 0);
1616
        return env->regs[0];
1617

    
1618
badframe:
1619
        unlock_user_struct(frame, frame_addr, 0);
1620
        force_sig(TARGET_SIGSEGV /* , current */);
1621
        return 0;
1622
}
1623

    
1624
long do_rt_sigreturn(CPUState *env)
1625
{
1626
    if (get_osversion() >= 0x020612) {
1627
        return do_rt_sigreturn_v2(env);
1628
    } else {
1629
        return do_rt_sigreturn_v1(env);
1630
    }
1631
}
1632

    
1633
#elif defined(TARGET_SPARC)
1634

    
1635
#define __SUNOS_MAXWIN   31
1636

    
1637
/* This is what SunOS does, so shall I. */
1638
struct target_sigcontext {
1639
        abi_ulong sigc_onstack;      /* state to restore */
1640

    
1641
        abi_ulong sigc_mask;         /* sigmask to restore */
1642
        abi_ulong sigc_sp;           /* stack pointer */
1643
        abi_ulong sigc_pc;           /* program counter */
1644
        abi_ulong sigc_npc;          /* next program counter */
1645
        abi_ulong sigc_psr;          /* for condition codes etc */
1646
        abi_ulong sigc_g1;           /* User uses these two registers */
1647
        abi_ulong sigc_o0;           /* within the trampoline code. */
1648

    
1649
        /* Now comes information regarding the users window set
1650
         * at the time of the signal.
1651
         */
1652
        abi_ulong sigc_oswins;       /* outstanding windows */
1653

    
1654
        /* stack ptrs for each regwin buf */
1655
        char *sigc_spbuf[__SUNOS_MAXWIN];
1656

    
1657
        /* Windows to restore after signal */
1658
        struct {
1659
                abi_ulong locals[8];
1660
                abi_ulong ins[8];
1661
        } sigc_wbuf[__SUNOS_MAXWIN];
1662
};
1663
/* A Sparc stack frame */
1664
struct sparc_stackf {
1665
        abi_ulong locals[8];
1666
        abi_ulong ins[6];
1667
        struct sparc_stackf *fp;
1668
        abi_ulong callers_pc;
1669
        char *structptr;
1670
        abi_ulong xargs[6];
1671
        abi_ulong xxargs[1];
1672
};
1673

    
1674
typedef struct {
1675
        struct {
1676
                abi_ulong psr;
1677
                abi_ulong pc;
1678
                abi_ulong npc;
1679
                abi_ulong y;
1680
                abi_ulong u_regs[16]; /* globals and ins */
1681
        }               si_regs;
1682
        int             si_mask;
1683
} __siginfo_t;
1684

    
1685
typedef struct {
1686
        unsigned   long si_float_regs [32];
1687
        unsigned   long si_fsr;
1688
        unsigned   long si_fpqdepth;
1689
        struct {
1690
                unsigned long *insn_addr;
1691
                unsigned long insn;
1692
        } si_fpqueue [16];
1693
} qemu_siginfo_fpu_t;
1694

    
1695

    
1696
struct target_signal_frame {
1697
        struct sparc_stackf        ss;
1698
        __siginfo_t                info;
1699
        abi_ulong               fpu_save;
1700
        abi_ulong                insns[2] __attribute__ ((aligned (8)));
1701
        abi_ulong                extramask[TARGET_NSIG_WORDS - 1];
1702
        abi_ulong                extra_size; /* Should be 0 */
1703
        qemu_siginfo_fpu_t        fpu_state;
1704
};
1705
struct target_rt_signal_frame {
1706
        struct sparc_stackf        ss;
1707
        siginfo_t                info;
1708
        abi_ulong                regs[20];
1709
        sigset_t                mask;
1710
        abi_ulong               fpu_save;
1711
        unsigned int                insns[2];
1712
        stack_t                        stack;
1713
        unsigned int                extra_size; /* Should be 0 */
1714
        qemu_siginfo_fpu_t        fpu_state;
1715
};
1716

    
1717
#define UREG_O0        16
1718
#define UREG_O6        22
1719
#define UREG_I0        0
1720
#define UREG_I1        1
1721
#define UREG_I2        2
1722
#define UREG_I3        3
1723
#define UREG_I4        4
1724
#define UREG_I5        5
1725
#define UREG_I6        6
1726
#define UREG_I7        7
1727
#define UREG_L0               8
1728
#define UREG_FP        UREG_I6
1729
#define UREG_SP        UREG_O6
1730

    
1731
static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
1732
                                     CPUState *env, unsigned long framesize)
1733
{
1734
        abi_ulong sp;
1735

    
1736
        sp = env->regwptr[UREG_FP];
1737

    
1738
        /* This is the X/Open sanctioned signal stack switching.  */
1739
        if (sa->sa_flags & TARGET_SA_ONSTACK) {
1740
            if (!on_sig_stack(sp)
1741
                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1742
                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1743
        }
1744
        return sp - framesize;
1745
}
1746

    
1747
static int
1748
setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1749
{
1750
        int err = 0, i;
1751

    
1752
        err |= __put_user(env->psr, &si->si_regs.psr);
1753
        err |= __put_user(env->pc, &si->si_regs.pc);
1754
        err |= __put_user(env->npc, &si->si_regs.npc);
1755
        err |= __put_user(env->y, &si->si_regs.y);
1756
        for (i=0; i < 8; i++) {
1757
                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1758
        }
1759
        for (i=0; i < 8; i++) {
1760
                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1761
        }
1762
        err |= __put_user(mask, &si->si_mask);
1763
        return err;
1764
}
1765

    
1766
#if 0
1767
static int
1768
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1769
                 CPUState *env, unsigned long mask)
1770
{
1771
        int err = 0;
1772

1773
        err |= __put_user(mask, &sc->sigc_mask);
1774
        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1775
        err |= __put_user(env->pc, &sc->sigc_pc);
1776
        err |= __put_user(env->npc, &sc->sigc_npc);
1777
        err |= __put_user(env->psr, &sc->sigc_psr);
1778
        err |= __put_user(env->gregs[1], &sc->sigc_g1);
1779
        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1780

1781
        return err;
1782
}
1783
#endif
1784
#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1785

    
1786
static void setup_frame(int sig, struct target_sigaction *ka,
1787
                        target_sigset_t *set, CPUState *env)
1788
{
1789
        abi_ulong sf_addr;
1790
        struct target_signal_frame *sf;
1791
        int sigframe_size, err, i;
1792

    
1793
        /* 1. Make sure everything is clean */
1794
        //synchronize_user_stack();
1795

    
1796
        sigframe_size = NF_ALIGNEDSZ;
1797
        sf_addr = get_sigframe(ka, env, sigframe_size);
1798

    
1799
        sf = lock_user(VERIFY_WRITE, sf_addr, 
1800
                       sizeof(struct target_signal_frame), 0);
1801
        if (!sf)
1802
                goto sigsegv;
1803
                
1804
        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1805
#if 0
1806
        if (invalid_frame_pointer(sf, sigframe_size))
1807
                goto sigill_and_return;
1808
#endif
1809
        /* 2. Save the current process state */
1810
        err = setup___siginfo(&sf->info, env, set->sig[0]);
1811
        err |= __put_user(0, &sf->extra_size);
1812

    
1813
        //err |= save_fpu_state(regs, &sf->fpu_state);
1814
        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1815

    
1816
        err |= __put_user(set->sig[0], &sf->info.si_mask);
1817
        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1818
                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1819
        }
1820

    
1821
        for (i = 0; i < 8; i++) {
1822
                  err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1823
        }
1824
        for (i = 0; i < 8; i++) {
1825
                  err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1826
        }
1827
        if (err)
1828
                goto sigsegv;
1829

    
1830
        /* 3. signal handler back-trampoline and parameters */
1831
        env->regwptr[UREG_FP] = sf_addr;
1832
        env->regwptr[UREG_I0] = sig;
1833
        env->regwptr[UREG_I1] = sf_addr + 
1834
                offsetof(struct target_signal_frame, info);
1835
        env->regwptr[UREG_I2] = sf_addr + 
1836
                offsetof(struct target_signal_frame, info);
1837

    
1838
        /* 4. signal handler */
1839
        env->pc = ka->_sa_handler;
1840
        env->npc = (env->pc + 4);
1841
        /* 5. return to kernel instructions */
1842
        if (ka->sa_restorer)
1843
                env->regwptr[UREG_I7] = ka->sa_restorer;
1844
        else {
1845
                uint32_t val32;
1846

    
1847
                env->regwptr[UREG_I7] = sf_addr + 
1848
                        offsetof(struct target_signal_frame, insns) - 2 * 4;
1849

    
1850
                /* mov __NR_sigreturn, %g1 */
1851
                val32 = 0x821020d8;
1852
                err |= __put_user(val32, &sf->insns[0]);
1853

    
1854
                /* t 0x10 */
1855
                val32 = 0x91d02010;
1856
                err |= __put_user(val32, &sf->insns[1]);
1857
                if (err)
1858
                        goto sigsegv;
1859

    
1860
                /* Flush instruction space. */
1861
                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1862
                //                tb_flush(env);
1863
        }
1864
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1865
        return;
1866
#if 0
1867
sigill_and_return:
1868
        force_sig(TARGET_SIGILL);
1869
#endif
1870
sigsegv:
1871
        //fprintf(stderr, "force_sig\n");
1872
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1873
        force_sig(TARGET_SIGSEGV);
1874
}
1875
static inline int
1876
restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1877
{
1878
        int err;
1879
#if 0
1880
#ifdef CONFIG_SMP
1881
        if (current->flags & PF_USEDFPU)
1882
                regs->psr &= ~PSR_EF;
1883
#else
1884
        if (current == last_task_used_math) {
1885
                last_task_used_math = 0;
1886
                regs->psr &= ~PSR_EF;
1887
        }
1888
#endif
1889
        current->used_math = 1;
1890
        current->flags &= ~PF_USEDFPU;
1891
#endif
1892
#if 0
1893
        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1894
                return -EFAULT;
1895
#endif
1896

    
1897
#if 0
1898
        /* XXX: incorrect */
1899
        err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1900
                                     (sizeof(unsigned long) * 32));
1901
#endif
1902
        err |= __get_user(env->fsr, &fpu->si_fsr);
1903
#if 0
1904
        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1905
        if (current->thread.fpqdepth != 0)
1906
                err |= __copy_from_user(&current->thread.fpqueue[0],
1907
                                        &fpu->si_fpqueue[0],
1908
                                        ((sizeof(unsigned long) +
1909
                                        (sizeof(unsigned long *)))*16));
1910
#endif
1911
        return err;
1912
}
1913

    
1914

    
1915
static void setup_rt_frame(int sig, struct target_sigaction *ka,
1916
                           target_siginfo_t *info,
1917
                           target_sigset_t *set, CPUState *env)
1918
{
1919
    fprintf(stderr, "setup_rt_frame: not implemented\n");
1920
}
1921

    
1922
long do_sigreturn(CPUState *env)
1923
{
1924
        abi_ulong sf_addr;
1925
        struct target_signal_frame *sf;
1926
        uint32_t up_psr, pc, npc;
1927
        target_sigset_t set;
1928
        sigset_t host_set;
1929
        abi_ulong fpu_save_addr;
1930
        int err, i;
1931

    
1932
        sf_addr = env->regwptr[UREG_FP];
1933
        if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1934
                goto segv_and_exit;
1935
#if 0
1936
        fprintf(stderr, "sigreturn\n");
1937
        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1938
#endif
1939
        //cpu_dump_state(env, stderr, fprintf, 0);
1940

    
1941
        /* 1. Make sure we are not getting garbage from the user */
1942

    
1943
        if (sf_addr & 3)
1944
                goto segv_and_exit;
1945

    
1946
        err = __get_user(pc,  &sf->info.si_regs.pc);
1947
        err |= __get_user(npc, &sf->info.si_regs.npc);
1948

    
1949
        if ((pc | npc) & 3)
1950
                goto segv_and_exit;
1951

    
1952
        /* 2. Restore the state */
1953
        err |= __get_user(up_psr, &sf->info.si_regs.psr);
1954

    
1955
        /* User can only change condition codes and FPU enabling in %psr. */
1956
        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1957
                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1958

    
1959
        env->pc = pc;
1960
        env->npc = npc;
1961
        err |= __get_user(env->y, &sf->info.si_regs.y);
1962
        for (i=0; i < 8; i++) {
1963
                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1964
        }
1965
        for (i=0; i < 8; i++) {
1966
                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1967
        }
1968

    
1969
        err |= __get_user(fpu_save_addr, &sf->fpu_save);
1970

    
1971
        //if (fpu_save)
1972
        //        err |= restore_fpu_state(env, fpu_save);
1973

    
1974
        /* This is pretty much atomic, no amount locking would prevent
1975
         * the races which exist anyways.
1976
         */
1977
        err |= __get_user(set.sig[0], &sf->info.si_mask);
1978
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1979
            err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1980
        }
1981

    
1982
        target_to_host_sigset_internal(&host_set, &set);
1983
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1984

    
1985
        if (err)
1986
                goto segv_and_exit;
1987
        unlock_user_struct(sf, sf_addr, 0);
1988
        return env->regwptr[0];
1989

    
1990
segv_and_exit:
1991
        unlock_user_struct(sf, sf_addr, 0);
1992
        force_sig(TARGET_SIGSEGV);
1993
}
1994

    
1995
long do_rt_sigreturn(CPUState *env)
1996
{
1997
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1998
    return -TARGET_ENOSYS;
1999
}
2000

    
2001
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2002
#define MC_TSTATE 0
2003
#define MC_PC 1
2004
#define MC_NPC 2
2005
#define MC_Y 3
2006
#define MC_G1 4
2007
#define MC_G2 5
2008
#define MC_G3 6
2009
#define MC_G4 7
2010
#define MC_G5 8
2011
#define MC_G6 9
2012
#define MC_G7 10
2013
#define MC_O0 11
2014
#define MC_O1 12
2015
#define MC_O2 13
2016
#define MC_O3 14
2017
#define MC_O4 15
2018
#define MC_O5 16
2019
#define MC_O6 17
2020
#define MC_O7 18
2021
#define MC_NGREG 19
2022

    
2023
typedef abi_ulong target_mc_greg_t;
2024
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2025

    
2026
struct target_mc_fq {
2027
    abi_ulong *mcfq_addr;
2028
    uint32_t mcfq_insn;
2029
};
2030

    
2031
struct target_mc_fpu {
2032
    union {
2033
        uint32_t sregs[32];
2034
        uint64_t dregs[32];
2035
        //uint128_t qregs[16];
2036
    } mcfpu_fregs;
2037
    abi_ulong mcfpu_fsr;
2038
    abi_ulong mcfpu_fprs;
2039
    abi_ulong mcfpu_gsr;
2040
    struct target_mc_fq *mcfpu_fq;
2041
    unsigned char mcfpu_qcnt;
2042
    unsigned char mcfpu_qentsz;
2043
    unsigned char mcfpu_enab;
2044
};
2045
typedef struct target_mc_fpu target_mc_fpu_t;
2046

    
2047
typedef struct {
2048
    target_mc_gregset_t mc_gregs;
2049
    target_mc_greg_t mc_fp;
2050
    target_mc_greg_t mc_i7;
2051
    target_mc_fpu_t mc_fpregs;
2052
} target_mcontext_t;
2053

    
2054
struct target_ucontext {
2055
    struct target_ucontext *tuc_link;
2056
    abi_ulong tuc_flags;
2057
    target_sigset_t tuc_sigmask;
2058
    target_mcontext_t tuc_mcontext;
2059
};
2060

    
2061
/* A V9 register window */
2062
struct target_reg_window {
2063
    abi_ulong locals[8];
2064
    abi_ulong ins[8];
2065
};
2066

    
2067
#define TARGET_STACK_BIAS 2047
2068

    
2069
/* {set, get}context() needed for 64-bit SparcLinux userland. */
2070
void sparc64_set_context(CPUSPARCState *env)
2071
{
2072
    abi_ulong ucp_addr;
2073
    struct target_ucontext *ucp;
2074
    target_mc_gregset_t *grp;
2075
    abi_ulong pc, npc, tstate;
2076
    abi_ulong fp, i7, w_addr;
2077
    unsigned char fenab;
2078
    int err;
2079
    unsigned int i;
2080

    
2081
    ucp_addr = env->regwptr[UREG_I0];
2082
    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2083
        goto do_sigsegv;
2084
    grp  = &ucp->tuc_mcontext.mc_gregs;
2085
    err  = __get_user(pc, &((*grp)[MC_PC]));
2086
    err |= __get_user(npc, &((*grp)[MC_NPC]));
2087
    if (err || ((pc | npc) & 3))
2088
        goto do_sigsegv;
2089
    if (env->regwptr[UREG_I1]) {
2090
        target_sigset_t target_set;
2091
        sigset_t set;
2092

    
2093
        if (TARGET_NSIG_WORDS == 1) {
2094
            if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2095
                goto do_sigsegv;
2096
        } else {
2097
            abi_ulong *src, *dst;
2098
            src = ucp->tuc_sigmask.sig;
2099
            dst = target_set.sig;
2100
            for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2101
                 i++, dst++, src++)
2102
                err |= __get_user(*dst, src);
2103
            if (err)
2104
                goto do_sigsegv;
2105
        }
2106
        target_to_host_sigset_internal(&set, &target_set);
2107
        sigprocmask(SIG_SETMASK, &set, NULL);
2108
    }
2109
    env->pc = pc;
2110
    env->npc = npc;
2111
    err |= __get_user(env->y, &((*grp)[MC_Y]));
2112
    err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2113
    env->asi = (tstate >> 24) & 0xff;
2114
    cpu_put_ccr(env, tstate >> 32);
2115
    cpu_put_cwp64(env, tstate & 0x1f);
2116
    err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2117
    err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2118
    err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2119
    err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2120
    err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2121
    err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2122
    err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2123
    err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2124
    err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2125
    err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2126
    err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2127
    err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2128
    err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2129
    err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2130
    err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2131

    
2132
    err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2133
    err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2134

    
2135
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2136
    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2137
                 abi_ulong) != 0)
2138
        goto do_sigsegv;
2139
    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2140
                 abi_ulong) != 0)
2141
        goto do_sigsegv;
2142
    err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2143
    err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2144
    {
2145
        uint32_t *src, *dst;
2146
        src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2147
        dst = env->fpr;
2148
        /* XXX: check that the CPU storage is the same as user context */
2149
        for (i = 0; i < 64; i++, dst++, src++)
2150
            err |= __get_user(*dst, src);
2151
    }
2152
    err |= __get_user(env->fsr,
2153
                      &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2154
    err |= __get_user(env->gsr,
2155
                      &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2156
    if (err)
2157
        goto do_sigsegv;
2158
    unlock_user_struct(ucp, ucp_addr, 0);
2159
    return;
2160
 do_sigsegv:
2161
    unlock_user_struct(ucp, ucp_addr, 0);
2162
    force_sig(TARGET_SIGSEGV);
2163
}
2164

    
2165
void sparc64_get_context(CPUSPARCState *env)
2166
{
2167
    abi_ulong ucp_addr;
2168
    struct target_ucontext *ucp;
2169
    target_mc_gregset_t *grp;
2170
    target_mcontext_t *mcp;
2171
    abi_ulong fp, i7, w_addr;
2172
    int err;
2173
    unsigned int i;
2174
    target_sigset_t target_set;
2175
    sigset_t set;
2176

    
2177
    ucp_addr = env->regwptr[UREG_I0];
2178
    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2179
        goto do_sigsegv;
2180
    
2181
    mcp = &ucp->tuc_mcontext;
2182
    grp = &mcp->mc_gregs;
2183

    
2184
    /* Skip over the trap instruction, first. */
2185
    env->pc = env->npc;
2186
    env->npc += 4;
2187

    
2188
    err = 0;
2189

    
2190
    sigprocmask(0, NULL, &set);
2191
    host_to_target_sigset_internal(&target_set, &set);
2192
    if (TARGET_NSIG_WORDS == 1) {
2193
        err |= __put_user(target_set.sig[0],
2194
                          (abi_ulong *)&ucp->tuc_sigmask);
2195
    } else {
2196
        abi_ulong *src, *dst;
2197
        src = target_set.sig;
2198
        dst = ucp->tuc_sigmask.sig;
2199
        for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2200
             i++, dst++, src++)
2201
            err |= __put_user(*src, dst);
2202
        if (err)
2203
            goto do_sigsegv;
2204
    }
2205

    
2206
    /* XXX: tstate must be saved properly */
2207
    //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2208
    err |= __put_user(env->pc, &((*grp)[MC_PC]));
2209
    err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2210
    err |= __put_user(env->y, &((*grp)[MC_Y]));
2211
    err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2212
    err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2213
    err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2214
    err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2215
    err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2216
    err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2217
    err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2218
    err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2219
    err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2220
    err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2221
    err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2222
    err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2223
    err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2224
    err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2225
    err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2226

    
2227
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2228
    fp = i7 = 0;
2229
    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2230
                 abi_ulong) != 0)
2231
        goto do_sigsegv;
2232
    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2233
                 abi_ulong) != 0)
2234
        goto do_sigsegv;
2235
    err |= __put_user(fp, &(mcp->mc_fp));
2236
    err |= __put_user(i7, &(mcp->mc_i7));
2237

    
2238
    {
2239
        uint32_t *src, *dst;
2240
        src = env->fpr;
2241
        dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2242
        /* XXX: check that the CPU storage is the same as user context */
2243
        for (i = 0; i < 64; i++, dst++, src++)
2244
            err |= __put_user(*src, dst);
2245
    }
2246
    err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2247
    err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2248
    err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2249

    
2250
    if (err)
2251
        goto do_sigsegv;
2252
    unlock_user_struct(ucp, ucp_addr, 1);
2253
    return;
2254
 do_sigsegv:
2255
    unlock_user_struct(ucp, ucp_addr, 1);
2256
    force_sig(TARGET_SIGSEGV);
2257
}
2258
#endif
2259
#elif defined(TARGET_ABI_MIPSN64)
2260

    
2261
# warning signal handling not implemented
2262

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

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

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

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

    
2288
#elif defined(TARGET_ABI_MIPSN32)
2289

    
2290
# warning signal handling not implemented
2291

    
2292
static void setup_frame(int sig, struct target_sigaction *ka,
2293
                        target_sigset_t *set, CPUState *env)
2294
{
2295
    fprintf(stderr, "setup_frame: not implemented\n");
2296
}
2297

    
2298
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2299
                           target_siginfo_t *info,
2300
                           target_sigset_t *set, CPUState *env)
2301
{
2302
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2303
}
2304

    
2305
long do_sigreturn(CPUState *env)
2306
{
2307
    fprintf(stderr, "do_sigreturn: not implemented\n");
2308
    return -TARGET_ENOSYS;
2309
}
2310

    
2311
long do_rt_sigreturn(CPUState *env)
2312
{
2313
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2314
    return -TARGET_ENOSYS;
2315
}
2316

    
2317
#elif defined(TARGET_ABI_MIPSO32)
2318

    
2319
struct target_sigcontext {
2320
    uint32_t   sc_regmask;     /* Unused */
2321
    uint32_t   sc_status;
2322
    uint64_t   sc_pc;
2323
    uint64_t   sc_regs[32];
2324
    uint64_t   sc_fpregs[32];
2325
    uint32_t   sc_ownedfp;     /* Unused */
2326
    uint32_t   sc_fpc_csr;
2327
    uint32_t   sc_fpc_eir;     /* Unused */
2328
    uint32_t   sc_used_math;
2329
    uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
2330
    uint32_t   pad0;
2331
    uint64_t   sc_mdhi;
2332
    uint64_t   sc_mdlo;
2333
    target_ulong   sc_hi1;         /* Was sc_cause */
2334
    target_ulong   sc_lo1;         /* Was sc_badvaddr */
2335
    target_ulong   sc_hi2;         /* Was sc_sigset[4] */
2336
    target_ulong   sc_lo2;
2337
    target_ulong   sc_hi3;
2338
    target_ulong   sc_lo3;
2339
};
2340

    
2341
struct sigframe {
2342
    uint32_t sf_ass[4];                        /* argument save space for o32 */
2343
    uint32_t sf_code[2];                        /* signal trampoline */
2344
    struct target_sigcontext sf_sc;
2345
    target_sigset_t sf_mask;
2346
};
2347

    
2348
struct target_ucontext {
2349
    target_ulong tuc_flags;
2350
    target_ulong tuc_link;
2351
    target_stack_t tuc_stack;
2352
    target_ulong pad0;
2353
    struct target_sigcontext tuc_mcontext;
2354
    target_sigset_t tuc_sigmask;
2355
};
2356

    
2357
struct target_rt_sigframe {
2358
    uint32_t rs_ass[4];               /* argument save space for o32 */
2359
    uint32_t rs_code[2];              /* signal trampoline */
2360
    struct target_siginfo rs_info;
2361
    struct target_ucontext rs_uc;
2362
};
2363

    
2364
/* Install trampoline to jump back from signal handler */
2365
static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2366
{
2367
    int err;
2368

    
2369
    /*
2370
    * Set up the return code ...
2371
    *
2372
    *         li      v0, __NR__foo_sigreturn
2373
    *         syscall
2374
    */
2375

    
2376
    err = __put_user(0x24020000 + syscall, tramp + 0);
2377
    err |= __put_user(0x0000000c          , tramp + 1);
2378
    /* flush_cache_sigtramp((unsigned long) tramp); */
2379
    return err;
2380
}
2381

    
2382
static inline int
2383
setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2384
{
2385
    int err = 0;
2386

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

    
2389
#define save_gp_reg(i) do {                                                   \
2390
        err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);        \
2391
    } while(0)
2392
    __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2393
    save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2394
    save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2395
    save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2396
    save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2397
    save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2398
    save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2399
    save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2400
    save_gp_reg(31);
2401
#undef save_gp_reg
2402

    
2403
    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2404
    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2405

    
2406
    /* Not used yet, but might be useful if we ever have DSP suppport */
2407
#if 0
2408
    if (cpu_has_dsp) {
2409
        err |= __put_user(mfhi1(), &sc->sc_hi1);
2410
        err |= __put_user(mflo1(), &sc->sc_lo1);
2411
        err |= __put_user(mfhi2(), &sc->sc_hi2);
2412
        err |= __put_user(mflo2(), &sc->sc_lo2);
2413
        err |= __put_user(mfhi3(), &sc->sc_hi3);
2414
        err |= __put_user(mflo3(), &sc->sc_lo3);
2415
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2416
    }
2417
    /* same with 64 bit */
2418
#ifdef CONFIG_64BIT
2419
    err |= __put_user(regs->hi, &sc->sc_hi[0]);
2420
    err |= __put_user(regs->lo, &sc->sc_lo[0]);
2421
    if (cpu_has_dsp) {
2422
        err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2423
        err |= __put_user(mflo1(), &sc->sc_lo[1]);
2424
        err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2425
        err |= __put_user(mflo2(), &sc->sc_lo[2]);
2426
        err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2427
        err |= __put_user(mflo3(), &sc->sc_lo[3]);
2428
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2429
    }
2430
#endif
2431
#endif
2432

    
2433
#if 0
2434
    err |= __put_user(!!used_math(), &sc->sc_used_math);
2435

2436
    if (!used_math())
2437
        goto out;
2438

2439
    /*
2440
    * Save FPU state to signal context.  Signal handler will "inherit"
2441
    * current FPU state.
2442
    */
2443
    preempt_disable();
2444

2445
    if (!is_fpu_owner()) {
2446
        own_fpu();
2447
        restore_fp(current);
2448
    }
2449
    err |= save_fp_context(sc);
2450

2451
    preempt_enable();
2452
    out:
2453
#endif
2454
    return err;
2455
}
2456

    
2457
static inline int
2458
restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2459
{
2460
    int err = 0;
2461

    
2462
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2463

    
2464
    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2465
    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2466

    
2467
#define restore_gp_reg(i) do {                                                           \
2468
        err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);                \
2469
    } while(0)
2470
    restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2471
    restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2472
    restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2473
    restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2474
    restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2475
    restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2476
    restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2477
    restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2478
    restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2479
    restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2480
    restore_gp_reg(31);
2481
#undef restore_gp_reg
2482

    
2483
#if 0
2484
    if (cpu_has_dsp) {
2485
        err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2486
        err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2487
        err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2488
        err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2489
        err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2490
        err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2491
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2492
    }
2493
#ifdef CONFIG_64BIT
2494
    err |= __get_user(regs->hi, &sc->sc_hi[0]);
2495
    err |= __get_user(regs->lo, &sc->sc_lo[0]);
2496
    if (cpu_has_dsp) {
2497
        err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2498
        err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2499
        err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2500
        err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2501
        err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2502
        err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2503
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2504
    }
2505
#endif
2506

    
2507
    err |= __get_user(used_math, &sc->sc_used_math);
2508
    conditional_used_math(used_math);
2509

    
2510
    preempt_disable();
2511

    
2512
    if (used_math()) {
2513
        /* restore fpu context if we have used it before */
2514
        own_fpu();
2515
        err |= restore_fp_context(sc);
2516
    } else {
2517
        /* signal handler may have used FPU.  Give it up. */
2518
        lose_fpu();
2519
    }
2520

    
2521
    preempt_enable();
2522
#endif
2523
    return err;
2524
}
2525
/*
2526
 * Determine which stack to use..
2527
 */
2528
static inline abi_ulong
2529
get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2530
{
2531
    unsigned long sp;
2532

    
2533
    /* Default to using normal stack */
2534
    sp = regs->active_tc.gpr[29];
2535

    
2536
    /*
2537
     * FPU emulator may have it's own trampoline active just
2538
     * above the user stack, 16-bytes before the next lowest
2539
     * 16 byte boundary.  Try to avoid trashing it.
2540
     */
2541
    sp -= 32;
2542

    
2543
    /* This is the X/Open sanctioned signal stack switching.  */
2544
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2545
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2546
    }
2547

    
2548
    return (sp - frame_size) & ~7;
2549
}
2550

    
2551
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2552
static void setup_frame(int sig, struct target_sigaction * ka,
2553
                        target_sigset_t *set, CPUState *regs)
2554
{
2555
    struct sigframe *frame;
2556
    abi_ulong frame_addr;
2557
    int i;
2558

    
2559
    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2560
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2561
        goto give_sigsegv;
2562

    
2563
    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2564

    
2565
    if(setup_sigcontext(regs, &frame->sf_sc))
2566
        goto give_sigsegv;
2567

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

    
2573
    /*
2574
    * Arguments to signal handler:
2575
    *
2576
    *   a0 = signal number
2577
    *   a1 = 0 (should be cause)
2578
    *   a2 = pointer to struct sigcontext
2579
    *
2580
    * $25 and PC point to the signal handler, $29 points to the
2581
    * struct sigframe.
2582
    */
2583
    regs->active_tc.gpr[ 4] = sig;
2584
    regs->active_tc.gpr[ 5] = 0;
2585
    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2586
    regs->active_tc.gpr[29] = frame_addr;
2587
    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2588
    /* The original kernel code sets CP0_EPC to the handler
2589
    * since it returns to userland using eret
2590
    * we cannot do this here, and we must set PC directly */
2591
    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2592
    unlock_user_struct(frame, frame_addr, 1);
2593
    return;
2594

    
2595
give_sigsegv:
2596
    unlock_user_struct(frame, frame_addr, 1);
2597
    force_sig(TARGET_SIGSEGV/*, current*/);
2598
    return;
2599
}
2600

    
2601
long do_sigreturn(CPUState *regs)
2602
{
2603
    struct sigframe *frame;
2604
    abi_ulong frame_addr;
2605
    sigset_t blocked;
2606
    target_sigset_t target_set;
2607
    int i;
2608

    
2609
#if defined(DEBUG_SIGNAL)
2610
    fprintf(stderr, "do_sigreturn\n");
2611
#endif
2612
    frame_addr = regs->active_tc.gpr[29];
2613
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2614
           goto badframe;
2615

    
2616
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2617
           if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2618
            goto badframe;
2619
    }
2620

    
2621
    target_to_host_sigset_internal(&blocked, &target_set);
2622
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2623

    
2624
    if (restore_sigcontext(regs, &frame->sf_sc))
2625
           goto badframe;
2626

    
2627
#if 0
2628
    /*
2629
     * Don't let your children do this ...
2630
     */
2631
    __asm__ __volatile__(
2632
           "move\t$29, %0\n\t"
2633
           "j\tsyscall_exit"
2634
           :/* no outputs */
2635
           :"r" (&regs));
2636
    /* Unreached */
2637
#endif
2638

    
2639
    regs->active_tc.PC = regs->CP0_EPC;
2640
    /* I am not sure this is right, but it seems to work
2641
    * maybe a problem with nested signals ? */
2642
    regs->CP0_EPC = 0;
2643
    return -TARGET_QEMU_ESIGRETURN;
2644

    
2645
badframe:
2646
    force_sig(TARGET_SIGSEGV/*, current*/);
2647
    return 0;
2648
}
2649

    
2650
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2651
                           target_siginfo_t *info,
2652
                           target_sigset_t *set, CPUState *env)
2653
{
2654
    struct target_rt_sigframe *frame;
2655
    abi_ulong frame_addr;
2656
    int i;
2657

    
2658
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
2659
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2660
        goto give_sigsegv;
2661

    
2662
    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
2663

    
2664
    copy_siginfo_to_user(&frame->rs_info, info);
2665

    
2666
    __put_user(0, &frame->rs_uc.tuc_flags);
2667
    __put_user(0, &frame->rs_uc.tuc_link);
2668
    __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
2669
    __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
2670
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
2671
               &frame->rs_uc.tuc_stack.ss_flags);
2672

    
2673
    setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
2674

    
2675
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2676
        __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
2677
    }
2678

    
2679
    /*
2680
    * Arguments to signal handler:
2681
    *
2682
    *   a0 = signal number
2683
    *   a1 = pointer to struct siginfo
2684
    *   a2 = pointer to struct ucontext
2685
    *
2686
    * $25 and PC point to the signal handler, $29 points to the
2687
    * struct sigframe.
2688
    */
2689
    env->active_tc.gpr[ 4] = sig;
2690
    env->active_tc.gpr[ 5] = frame_addr
2691
                             + offsetof(struct target_rt_sigframe, rs_info);
2692
    env->active_tc.gpr[ 6] = frame_addr
2693
                             + offsetof(struct target_rt_sigframe, rs_uc);
2694
    env->active_tc.gpr[29] = frame_addr;
2695
    env->active_tc.gpr[31] = frame_addr
2696
                             + offsetof(struct target_rt_sigframe, rs_code);
2697
    /* The original kernel code sets CP0_EPC to the handler
2698
    * since it returns to userland using eret
2699
    * we cannot do this here, and we must set PC directly */
2700
    env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
2701
    unlock_user_struct(frame, frame_addr, 1);
2702
    return;
2703

    
2704
give_sigsegv:
2705
    unlock_user_struct(frame, frame_addr, 1);
2706
    force_sig(TARGET_SIGSEGV/*, current*/);
2707
    return;
2708
}
2709

    
2710
long do_rt_sigreturn(CPUState *env)
2711
{
2712
    struct target_rt_sigframe *frame;
2713
    abi_ulong frame_addr;
2714
    sigset_t blocked;
2715

    
2716
#if defined(DEBUG_SIGNAL)
2717
    fprintf(stderr, "do_rt_sigreturn\n");
2718
#endif
2719
    frame_addr = env->active_tc.gpr[29];
2720
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2721
           goto badframe;
2722

    
2723
    target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
2724
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2725

    
2726
    if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
2727
        goto badframe;
2728

    
2729
    if (do_sigaltstack(frame_addr +
2730
                       offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
2731
                       0, get_sp_from_cpustate(env)) == -EFAULT)
2732
        goto badframe;
2733

    
2734
    env->active_tc.PC = env->CP0_EPC;
2735
    /* I am not sure this is right, but it seems to work
2736
    * maybe a problem with nested signals ? */
2737
    env->CP0_EPC = 0;
2738
    return -TARGET_QEMU_ESIGRETURN;
2739

    
2740
badframe:
2741
    force_sig(TARGET_SIGSEGV/*, current*/);
2742
    return 0;
2743
}
2744

    
2745
#elif defined(TARGET_SH4)
2746

    
2747
/*
2748
 * code and data structures from linux kernel:
2749
 * include/asm-sh/sigcontext.h
2750
 * arch/sh/kernel/signal.c
2751
 */
2752

    
2753
struct target_sigcontext {
2754
    target_ulong  oldmask;
2755

    
2756
    /* CPU registers */
2757
    target_ulong  sc_gregs[16];
2758
    target_ulong  sc_pc;
2759
    target_ulong  sc_pr;
2760
    target_ulong  sc_sr;
2761
    target_ulong  sc_gbr;
2762
    target_ulong  sc_mach;
2763
    target_ulong  sc_macl;
2764

    
2765
    /* FPU registers */
2766
    target_ulong  sc_fpregs[16];
2767
    target_ulong  sc_xfpregs[16];
2768
    unsigned int sc_fpscr;
2769
    unsigned int sc_fpul;
2770
    unsigned int sc_ownedfp;
2771
};
2772

    
2773
struct target_sigframe
2774
{
2775
    struct target_sigcontext sc;
2776
    target_ulong extramask[TARGET_NSIG_WORDS-1];
2777
    uint16_t retcode[3];
2778
};
2779

    
2780

    
2781
struct target_ucontext {
2782
    target_ulong tuc_flags;
2783
    struct target_ucontext *tuc_link;
2784
    target_stack_t tuc_stack;
2785
    struct target_sigcontext tuc_mcontext;
2786
    target_sigset_t tuc_sigmask;        /* mask last for extensibility */
2787
};
2788

    
2789
struct target_rt_sigframe
2790
{
2791
    struct target_siginfo info;
2792
    struct target_ucontext uc;
2793
    uint16_t retcode[3];
2794
};
2795

    
2796

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

    
2800
static abi_ulong get_sigframe(struct target_sigaction *ka,
2801
                         unsigned long sp, size_t frame_size)
2802
{
2803
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2804
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2805
    }
2806

    
2807
    return (sp - frame_size) & -8ul;
2808
}
2809

    
2810
static int setup_sigcontext(struct target_sigcontext *sc,
2811
                            CPUState *regs, unsigned long mask)
2812
{
2813
    int err = 0;
2814
    int i;
2815

    
2816
#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
2817
    COPY(gregs[0]); COPY(gregs[1]);
2818
    COPY(gregs[2]); COPY(gregs[3]);
2819
    COPY(gregs[4]); COPY(gregs[5]);
2820
    COPY(gregs[6]); COPY(gregs[7]);
2821
    COPY(gregs[8]); COPY(gregs[9]);
2822
    COPY(gregs[10]); COPY(gregs[11]);
2823
    COPY(gregs[12]); COPY(gregs[13]);
2824
    COPY(gregs[14]); COPY(gregs[15]);
2825
    COPY(gbr); COPY(mach);
2826
    COPY(macl); COPY(pr);
2827
    COPY(sr); COPY(pc);
2828
#undef COPY
2829

    
2830
    for (i=0; i<16; i++) {
2831
        err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
2832
    }
2833
    err |= __put_user(regs->fpscr, &sc->sc_fpscr);
2834
    err |= __put_user(regs->fpul, &sc->sc_fpul);
2835

    
2836
    /* non-iBCS2 extensions.. */
2837
    err |= __put_user(mask, &sc->oldmask);
2838

    
2839
    return err;
2840
}
2841

    
2842
static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
2843
                              target_ulong *r0_p)
2844
{
2845
    unsigned int err = 0;
2846
    int i;
2847

    
2848
#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
2849
    COPY(gregs[1]);
2850
    COPY(gregs[2]); COPY(gregs[3]);
2851
    COPY(gregs[4]); COPY(gregs[5]);
2852
    COPY(gregs[6]); COPY(gregs[7]);
2853
    COPY(gregs[8]); COPY(gregs[9]);
2854
    COPY(gregs[10]); COPY(gregs[11]);
2855
    COPY(gregs[12]); COPY(gregs[13]);
2856
    COPY(gregs[14]); COPY(gregs[15]);
2857
    COPY(gbr); COPY(mach);
2858
    COPY(macl); COPY(pr);
2859
    COPY(sr); COPY(pc);
2860
#undef COPY
2861

    
2862
    for (i=0; i<16; i++) {
2863
        err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
2864
    }
2865
    err |= __get_user(regs->fpscr, &sc->sc_fpscr);
2866
    err |= __get_user(regs->fpul, &sc->sc_fpul);
2867

    
2868
    regs->tra = -1;         /* disable syscall checks */
2869
    err |= __get_user(*r0_p, &sc->sc_gregs[0]);
2870
    return err;
2871
}
2872

    
2873
static void setup_frame(int sig, struct target_sigaction *ka,
2874
                        target_sigset_t *set, CPUState *regs)
2875
{
2876
    struct target_sigframe *frame;
2877
    abi_ulong frame_addr;
2878
    int i;
2879
    int err = 0;
2880
    int signal;
2881

    
2882
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2883
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2884
        goto give_sigsegv;
2885

    
2886
    signal = current_exec_domain_sig(sig);
2887

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

    
2890
    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2891
        err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2892
    }
2893

    
2894
    /* Set up to return from userspace.  If provided, use a stub
2895
       already in userspace.  */
2896
    if (ka->sa_flags & TARGET_SA_RESTORER) {
2897
        regs->pr = (unsigned long) ka->sa_restorer;
2898
    } else {
2899
        /* Generate return code (system call to sigreturn) */
2900
        err |= __put_user(MOVW(2), &frame->retcode[0]);
2901
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2902
        err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2903
        regs->pr = (unsigned long) frame->retcode;
2904
    }
2905

    
2906
    if (err)
2907
        goto give_sigsegv;
2908

    
2909
    /* Set up registers for signal handler */
2910
    regs->gregs[15] = (unsigned long) frame;
2911
    regs->gregs[4] = signal; /* Arg for signal handler */
2912
    regs->gregs[5] = 0;
2913
    regs->gregs[6] = (unsigned long) &frame->sc;
2914
    regs->pc = (unsigned long) ka->_sa_handler;
2915

    
2916
    unlock_user_struct(frame, frame_addr, 1);
2917
    return;
2918

    
2919
give_sigsegv:
2920
    unlock_user_struct(frame, frame_addr, 1);
2921
    force_sig(TARGET_SIGSEGV);
2922
}
2923

    
2924
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2925
                           target_siginfo_t *info,
2926
                           target_sigset_t *set, CPUState *regs)
2927
{
2928
    struct target_rt_sigframe *frame;
2929
    abi_ulong frame_addr;
2930
    int i;
2931
    int err = 0;
2932
    int signal;
2933

    
2934
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2935
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2936
        goto give_sigsegv;
2937

    
2938
    signal = current_exec_domain_sig(sig);
2939

    
2940
    err |= copy_siginfo_to_user(&frame->info, info);
2941

    
2942
    /* Create the ucontext.  */
2943
    err |= __put_user(0, &frame->uc.tuc_flags);
2944
    err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
2945
    err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2946
                      &frame->uc.tuc_stack.ss_sp);
2947
    err |= __put_user(sas_ss_flags(regs->gregs[15]),
2948
                      &frame->uc.tuc_stack.ss_flags);
2949
    err |= __put_user(target_sigaltstack_used.ss_size,
2950
                      &frame->uc.tuc_stack.ss_size);
2951
    err |= setup_sigcontext(&frame->uc.tuc_mcontext,
2952
                            regs, set->sig[0]);
2953
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2954
        err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
2955
    }
2956

    
2957
    /* Set up to return from userspace.  If provided, use a stub
2958
       already in userspace.  */
2959
    if (ka->sa_flags & TARGET_SA_RESTORER) {
2960
        regs->pr = (unsigned long) ka->sa_restorer;
2961
    } else {
2962
        /* Generate return code (system call to sigreturn) */
2963
        err |= __put_user(MOVW(2), &frame->retcode[0]);
2964
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2965
        err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2966
        regs->pr = (unsigned long) frame->retcode;
2967
    }
2968

    
2969
    if (err)
2970
        goto give_sigsegv;
2971

    
2972
    /* Set up registers for signal handler */
2973
    regs->gregs[15] = (unsigned long) frame;
2974
    regs->gregs[4] = signal; /* Arg for signal handler */
2975
    regs->gregs[5] = (unsigned long) &frame->info;
2976
    regs->gregs[6] = (unsigned long) &frame->uc;
2977
    regs->pc = (unsigned long) ka->_sa_handler;
2978

    
2979
    unlock_user_struct(frame, frame_addr, 1);
2980
    return;
2981

    
2982
give_sigsegv:
2983
    unlock_user_struct(frame, frame_addr, 1);
2984
    force_sig(TARGET_SIGSEGV);
2985
}
2986

    
2987
long do_sigreturn(CPUState *regs)
2988
{
2989
    struct target_sigframe *frame;
2990
    abi_ulong frame_addr;
2991
    sigset_t blocked;
2992
    target_sigset_t target_set;
2993
    target_ulong r0;
2994
    int i;
2995
    int err = 0;
2996

    
2997
#if defined(DEBUG_SIGNAL)
2998
    fprintf(stderr, "do_sigreturn\n");
2999
#endif
3000
    frame_addr = regs->gregs[15];
3001
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3002
           goto badframe;
3003

    
3004
    err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3005
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3006
        err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3007
    }
3008

    
3009
    if (err)
3010
        goto badframe;
3011

    
3012
    target_to_host_sigset_internal(&blocked, &target_set);
3013
    sigprocmask(SIG_SETMASK, &blocked, NULL);
3014

    
3015
    if (restore_sigcontext(regs, &frame->sc, &r0))
3016
        goto badframe;
3017

    
3018
    unlock_user_struct(frame, frame_addr, 0);
3019
    return r0;
3020

    
3021
badframe:
3022
    unlock_user_struct(frame, frame_addr, 0);
3023
    force_sig(TARGET_SIGSEGV);
3024
    return 0;
3025
}
3026

    
3027
long do_rt_sigreturn(CPUState *regs)
3028
{
3029
    struct target_rt_sigframe *frame;
3030
    abi_ulong frame_addr;
3031
    sigset_t blocked;
3032
    target_ulong r0;
3033

    
3034
#if defined(DEBUG_SIGNAL)
3035
    fprintf(stderr, "do_rt_sigreturn\n");
3036
#endif
3037
    frame_addr = regs->gregs[15];
3038
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3039
           goto badframe;
3040

    
3041
    target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3042
    sigprocmask(SIG_SETMASK, &blocked, NULL);
3043

    
3044
    if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3045
        goto badframe;
3046

    
3047
    if (do_sigaltstack(frame_addr +
3048
                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
3049
                       0, get_sp_from_cpustate(regs)) == -EFAULT)
3050
        goto badframe;
3051

    
3052
    unlock_user_struct(frame, frame_addr, 0);
3053
    return r0;
3054

    
3055
badframe:
3056
    unlock_user_struct(frame, frame_addr, 0);
3057
    force_sig(TARGET_SIGSEGV);
3058
    return 0;
3059
}
3060
#elif defined(TARGET_MICROBLAZE)
3061

    
3062
struct target_sigcontext {
3063
    struct target_pt_regs regs;  /* needs to be first */
3064
    uint32_t oldmask;
3065
};
3066

    
3067
struct target_stack_t {
3068
    abi_ulong ss_sp;
3069
    int ss_flags;
3070
    unsigned int ss_size;
3071
};
3072

    
3073
struct target_ucontext {
3074
    abi_ulong uc_flags;
3075
    abi_ulong uc_link;
3076
    struct target_stack_t uc_stack;
3077
    struct target_sigcontext sc;
3078
    uint32_t extramask[TARGET_NSIG_WORDS - 1];
3079
};
3080

    
3081
/* Signal frames. */
3082
struct target_signal_frame {
3083
    struct target_ucontext uc;
3084
    uint32_t extramask[TARGET_NSIG_WORDS - 1];
3085
    uint32_t tramp[2];
3086
};
3087

    
3088
struct rt_signal_frame {
3089
    struct siginfo info;
3090
    struct ucontext uc;
3091
    uint32_t tramp[2];
3092
};
3093

    
3094
static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3095
{
3096
    __put_user(env->regs[0], &sc->regs.r0);
3097
    __put_user(env->regs[1], &sc->regs.r1);
3098
    __put_user(env->regs[2], &sc->regs.r2);
3099
    __put_user(env->regs[3], &sc->regs.r3);
3100
    __put_user(env->regs[4], &sc->regs.r4);
3101
    __put_user(env->regs[5], &sc->regs.r5);
3102
    __put_user(env->regs[6], &sc->regs.r6);
3103
    __put_user(env->regs[7], &sc->regs.r7);
3104
    __put_user(env->regs[8], &sc->regs.r8);
3105
    __put_user(env->regs[9], &sc->regs.r9);
3106
    __put_user(env->regs[10], &sc->regs.r10);
3107
    __put_user(env->regs[11], &sc->regs.r11);
3108
    __put_user(env->regs[12], &sc->regs.r12);
3109
    __put_user(env->regs[13], &sc->regs.r13);
3110
    __put_user(env->regs[14], &sc->regs.r14);
3111
    __put_user(env->regs[15], &sc->regs.r15);
3112
    __put_user(env->regs[16], &sc->regs.r16);
3113
    __put_user(env->regs[17], &sc->regs.r17);
3114
    __put_user(env->regs[18], &sc->regs.r18);
3115
    __put_user(env->regs[19], &sc->regs.r19);
3116
    __put_user(env->regs[20], &sc->regs.r20);
3117
    __put_user(env->regs[21], &sc->regs.r21);
3118
    __put_user(env->regs[22], &sc->regs.r22);
3119
    __put_user(env->regs[23], &sc->regs.r23);
3120
    __put_user(env->regs[24], &sc->regs.r24);
3121
    __put_user(env->regs[25], &sc->regs.r25);
3122
    __put_user(env->regs[26], &sc->regs.r26);
3123
    __put_user(env->regs[27], &sc->regs.r27);
3124
    __put_user(env->regs[28], &sc->regs.r28);
3125
    __put_user(env->regs[29], &sc->regs.r29);
3126
    __put_user(env->regs[30], &sc->regs.r30);
3127
    __put_user(env->regs[31], &sc->regs.r31);
3128
    __put_user(env->sregs[SR_PC], &sc->regs.pc);
3129
}
3130

    
3131
static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3132
{
3133
    __get_user(env->regs[0], &sc->regs.r0);
3134
    __get_user(env->regs[1], &sc->regs.r1);
3135
    __get_user(env->regs[2], &sc->regs.r2);
3136
    __get_user(env->regs[3], &sc->regs.r3);
3137
    __get_user(env->regs[4], &sc->regs.r4);
3138
    __get_user(env->regs[5], &sc->regs.r5);
3139
    __get_user(env->regs[6], &sc->regs.r6);
3140
    __get_user(env->regs[7], &sc->regs.r7);
3141
    __get_user(env->regs[8], &sc->regs.r8);
3142
    __get_user(env->regs[9], &sc->regs.r9);
3143
    __get_user(env->regs[10], &sc->regs.r10);
3144
    __get_user(env->regs[11], &sc->regs.r11);
3145
    __get_user(env->regs[12], &sc->regs.r12);
3146
    __get_user(env->regs[13], &sc->regs.r13);
3147
    __get_user(env->regs[14], &sc->regs.r14);
3148
    __get_user(env->regs[15], &sc->regs.r15);
3149
    __get_user(env->regs[16], &sc->regs.r16);
3150
    __get_user(env->regs[17], &sc->regs.r17);
3151
    __get_user(env->regs[18], &sc->regs.r18);
3152
    __get_user(env->regs[19], &sc->regs.r19);
3153
    __get_user(env->regs[20], &sc->regs.r20);
3154
    __get_user(env->regs[21], &sc->regs.r21);
3155
    __get_user(env->regs[22], &sc->regs.r22);
3156
    __get_user(env->regs[23], &sc->regs.r23);
3157
    __get_user(env->regs[24], &sc->regs.r24);
3158
    __get_user(env->regs[25], &sc->regs.r25);
3159
    __get_user(env->regs[26], &sc->regs.r26);
3160
    __get_user(env->regs[27], &sc->regs.r27);
3161
    __get_user(env->regs[28], &sc->regs.r28);
3162
    __get_user(env->regs[29], &sc->regs.r29);
3163
    __get_user(env->regs[30], &sc->regs.r30);
3164
    __get_user(env->regs[31], &sc->regs.r31);
3165
    __get_user(env->sregs[SR_PC], &sc->regs.pc);
3166
}
3167

    
3168
static abi_ulong get_sigframe(struct target_sigaction *ka,
3169
                              CPUState *env, int frame_size)
3170
{
3171
    abi_ulong sp = env->regs[1];
3172

    
3173
    if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3174
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3175

    
3176
    return ((sp - frame_size) & -8UL);
3177
}
3178

    
3179
static void setup_frame(int sig, struct target_sigaction *ka,
3180
                        target_sigset_t *set, CPUState *env)
3181
{
3182
    struct target_signal_frame *frame;
3183
    abi_ulong frame_addr;
3184
    int err = 0;
3185
    int i;
3186

    
3187
    frame_addr = get_sigframe(ka, env, sizeof *frame);
3188
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3189
        goto badframe;
3190

    
3191
    /* Save the mask.  */
3192
    err |= __put_user(set->sig[0], &frame->uc.sc.oldmask);
3193
    if (err)
3194
        goto badframe;
3195

    
3196
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3197
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3198
            goto badframe;
3199
    }
3200

    
3201
    setup_sigcontext(&frame->uc.sc, env);
3202

    
3203
    /* Set up to return from userspace. If provided, use a stub
3204
       already in userspace. */
3205
    /* minus 8 is offset to cater for "rtsd r15,8" offset */
3206
    if (ka->sa_flags & TARGET_SA_RESTORER) {
3207
        env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3208
    } else {
3209
        uint32_t t;
3210
        /* Note, these encodings are _big endian_! */
3211
        /* addi r12, r0, __NR_sigreturn */
3212
        t = 0x31800000UL | TARGET_NR_sigreturn;
3213
        err |= __put_user(t, frame->tramp + 0);
3214
        /* brki r14, 0x8 */
3215
        t = 0xb9cc0008UL;
3216
        err |= __put_user(t, frame->tramp + 1);
3217

    
3218
        /* Return from sighandler will jump to the tramp.
3219
           Negative 8 offset because return is rtsd r15, 8 */
3220
        env->regs[15] = ((unsigned long)frame->tramp) - 8;
3221
    }
3222

    
3223
    if (err)
3224
        goto badframe;
3225

    
3226
    /* Set up registers for signal handler */
3227
    env->regs[1] = (unsigned long) frame;
3228
    /* Signal handler args: */
3229
    env->regs[5] = sig; /* Arg 0: signum */
3230
    env->regs[6] = 0;
3231
    env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
3232

    
3233
    /* Offset of 4 to handle microblaze rtid r14, 0 */
3234
    env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3235

    
3236
    unlock_user_struct(frame, frame_addr, 1);
3237
    return;
3238
  badframe:
3239
    unlock_user_struct(frame, frame_addr, 1);
3240
    force_sig(TARGET_SIGSEGV);
3241
}
3242

    
3243
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3244
                           target_siginfo_t *info,
3245
                           target_sigset_t *set, CPUState *env)
3246
{
3247
    fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3248
}
3249

    
3250
long do_sigreturn(CPUState *env)
3251
{
3252
    struct target_signal_frame *frame;
3253
    abi_ulong frame_addr;
3254
    target_sigset_t target_set;
3255
    sigset_t set;
3256
    int i;
3257

    
3258
    frame_addr = env->regs[R_SP];
3259
    /* Make sure the guest isn't playing games.  */
3260
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3261
        goto badframe;
3262

    
3263
    /* Restore blocked signals */
3264
    if (__get_user(target_set.sig[0], &frame->uc.sc.oldmask))
3265
        goto badframe;
3266
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3267
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3268
            goto badframe;
3269
    }
3270
    target_to_host_sigset_internal(&set, &target_set);
3271
    sigprocmask(SIG_SETMASK, &set, NULL);
3272

    
3273
    restore_sigcontext(&frame->uc.sc, env);
3274
    /* We got here through a sigreturn syscall, our path back is via an
3275
       rtb insn so setup r14 for that.  */
3276
    env->regs[14] = env->sregs[SR_PC];
3277
 
3278
    unlock_user_struct(frame, frame_addr, 0);
3279
    return env->regs[10];
3280
  badframe:
3281
    unlock_user_struct(frame, frame_addr, 0);
3282
    force_sig(TARGET_SIGSEGV);
3283
}
3284

    
3285
long do_rt_sigreturn(CPUState *env)
3286
{
3287
    fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3288
    return -TARGET_ENOSYS;
3289
}
3290

    
3291
#elif defined(TARGET_CRIS)
3292

    
3293
struct target_sigcontext {
3294
        struct target_pt_regs regs;  /* needs to be first */
3295
        uint32_t oldmask;
3296
        uint32_t usp;    /* usp before stacking this gunk on it */
3297
};
3298

    
3299
/* Signal frames. */
3300
struct target_signal_frame {
3301
        struct target_sigcontext sc;
3302
        uint32_t extramask[TARGET_NSIG_WORDS - 1];
3303
        uint8_t retcode[8];       /* Trampoline code. */
3304
};
3305

    
3306
struct rt_signal_frame {
3307
        struct siginfo *pinfo;
3308
        void *puc;
3309
        struct siginfo info;
3310
        struct ucontext uc;
3311
        uint8_t retcode[8];       /* Trampoline code. */
3312
};
3313

    
3314
static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3315
{
3316
        __put_user(env->regs[0], &sc->regs.r0);
3317
        __put_user(env->regs[1], &sc->regs.r1);
3318
        __put_user(env->regs[2], &sc->regs.r2);
3319
        __put_user(env->regs[3], &sc->regs.r3);
3320
        __put_user(env->regs[4], &sc->regs.r4);
3321
        __put_user(env->regs[5], &sc->regs.r5);
3322
        __put_user(env->regs[6], &sc->regs.r6);
3323
        __put_user(env->regs[7], &sc->regs.r7);
3324
        __put_user(env->regs[8], &sc->regs.r8);
3325
        __put_user(env->regs[9], &sc->regs.r9);
3326
        __put_user(env->regs[10], &sc->regs.r10);
3327
        __put_user(env->regs[11], &sc->regs.r11);
3328
        __put_user(env->regs[12], &sc->regs.r12);
3329
        __put_user(env->regs[13], &sc->regs.r13);
3330
        __put_user(env->regs[14], &sc->usp);
3331
        __put_user(env->regs[15], &sc->regs.acr);
3332
        __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3333
        __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3334
        __put_user(env->pc, &sc->regs.erp);
3335
}
3336

    
3337
static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3338
{
3339
        __get_user(env->regs[0], &sc->regs.r0);
3340
        __get_user(env->regs[1], &sc->regs.r1);
3341
        __get_user(env->regs[2], &sc->regs.r2);
3342
        __get_user(env->regs[3], &sc->regs.r3);
3343
        __get_user(env->regs[4], &sc->regs.r4);
3344
        __get_user(env->regs[5], &sc->regs.r5);
3345
        __get_user(env->regs[6], &sc->regs.r6);
3346
        __get_user(env->regs[7], &sc->regs.r7);
3347
        __get_user(env->regs[8], &sc->regs.r8);
3348
        __get_user(env->regs[9], &sc->regs.r9);
3349
        __get_user(env->regs[10], &sc->regs.r10);
3350
        __get_user(env->regs[11], &sc->regs.r11);
3351
        __get_user(env->regs[12], &sc->regs.r12);
3352
        __get_user(env->regs[13], &sc->regs.r13);
3353
        __get_user(env->regs[14], &sc->usp);
3354
        __get_user(env->regs[15], &sc->regs.acr);
3355
        __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3356
        __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3357
        __get_user(env->pc, &sc->regs.erp);
3358
}
3359

    
3360
static abi_ulong get_sigframe(CPUState *env, int framesize)
3361
{
3362
        abi_ulong sp;
3363
        /* Align the stack downwards to 4.  */
3364
        sp = (env->regs[R_SP] & ~3);
3365
        return sp - framesize;
3366
}
3367

    
3368
static void setup_frame(int sig, struct target_sigaction *ka,
3369
                        target_sigset_t *set, CPUState *env)
3370
{
3371
        struct target_signal_frame *frame;
3372
        abi_ulong frame_addr;
3373
        int err = 0;
3374
        int i;
3375

    
3376
        frame_addr = get_sigframe(env, sizeof *frame);
3377
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3378
                goto badframe;
3379

    
3380
        /*
3381
         * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3382
         * use this trampoline anymore but it sets it up for GDB.
3383
         * In QEMU, using the trampoline simplifies things a bit so we use it.
3384
         *
3385
         * This is movu.w __NR_sigreturn, r9; break 13;
3386
         */
3387
        err |= __put_user(0x9c5f, frame->retcode+0);
3388
        err |= __put_user(TARGET_NR_sigreturn, 
3389
                          frame->retcode+2);
3390
        err |= __put_user(0xe93d, frame->retcode+4);
3391

    
3392
        /* Save the mask.  */
3393
        err |= __put_user(set->sig[0], &frame->sc.oldmask);
3394
        if (err)
3395
                goto badframe;
3396

    
3397
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3398
                if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3399
                        goto badframe;
3400
        }
3401

    
3402
        setup_sigcontext(&frame->sc, env);
3403

    
3404
        /* Move the stack and setup the arguments for the handler.  */
3405
        env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3406
        env->regs[10] = sig;
3407
        env->pc = (unsigned long) ka->_sa_handler;
3408
        /* Link SRP so the guest returns through the trampoline.  */
3409
        env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3410

    
3411
        unlock_user_struct(frame, frame_addr, 1);
3412
        return;
3413
  badframe:
3414
        unlock_user_struct(frame, frame_addr, 1);
3415
        force_sig(TARGET_SIGSEGV);
3416
}
3417

    
3418
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3419
                           target_siginfo_t *info,
3420
                           target_sigset_t *set, CPUState *env)
3421
{
3422
    fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3423
}
3424

    
3425
long do_sigreturn(CPUState *env)
3426
{
3427
        struct target_signal_frame *frame;
3428
        abi_ulong frame_addr;
3429
        target_sigset_t target_set;
3430
        sigset_t set;
3431
        int i;
3432

    
3433
        frame_addr = env->regs[R_SP];
3434
        /* Make sure the guest isn't playing games.  */
3435
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3436
                goto badframe;
3437

    
3438
        /* Restore blocked signals */
3439
        if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3440
                goto badframe;
3441
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3442
                if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3443
                        goto badframe;
3444
        }
3445
        target_to_host_sigset_internal(&set, &target_set);
3446
        sigprocmask(SIG_SETMASK, &set, NULL);
3447

    
3448
        restore_sigcontext(&frame->sc, env);
3449
        unlock_user_struct(frame, frame_addr, 0);
3450
        return env->regs[10];
3451
  badframe:
3452
        unlock_user_struct(frame, frame_addr, 0);
3453
        force_sig(TARGET_SIGSEGV);
3454
}
3455

    
3456
long do_rt_sigreturn(CPUState *env)
3457
{
3458
    fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3459
    return -TARGET_ENOSYS;
3460
}
3461

    
3462
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3463

    
3464
/* FIXME: Many of the structures are defined for both PPC and PPC64, but
3465
   the signal handling is different enough that we haven't implemented
3466
   support for PPC64 yet.  Hence the restriction above.
3467

3468
   There are various #if'd blocks for code for TARGET_PPC64.  These
3469
   blocks should go away so that we can successfully run 32-bit and
3470
   64-bit binaries on a QEMU configured for PPC64.  */
3471

    
3472
/* Size of dummy stack frame allocated when calling signal handler.
3473
   See arch/powerpc/include/asm/ptrace.h.  */
3474
#if defined(TARGET_PPC64)
3475
#define SIGNAL_FRAMESIZE 128
3476
#else
3477
#define SIGNAL_FRAMESIZE 64
3478
#endif
3479

    
3480
/* See arch/powerpc/include/asm/sigcontext.h.  */
3481
struct target_sigcontext {
3482
    target_ulong _unused[4];
3483
    int32_t signal;
3484
#if defined(TARGET_PPC64)
3485
    int32_t pad0;
3486
#endif
3487
    target_ulong handler;
3488
    target_ulong oldmask;
3489
    target_ulong regs;      /* struct pt_regs __user * */
3490
    /* TODO: PPC64 includes extra bits here.  */
3491
};
3492

    
3493
/* Indices for target_mcontext.mc_gregs, below.
3494
   See arch/powerpc/include/asm/ptrace.h for details.  */
3495
enum {
3496
    TARGET_PT_R0 = 0,
3497
    TARGET_PT_R1 = 1,
3498
    TARGET_PT_R2 = 2,
3499
    TARGET_PT_R3 = 3,
3500
    TARGET_PT_R4 = 4,
3501
    TARGET_PT_R5 = 5,
3502
    TARGET_PT_R6 = 6,
3503
    TARGET_PT_R7 = 7,
3504
    TARGET_PT_R8 = 8,
3505
    TARGET_PT_R9 = 9,
3506
    TARGET_PT_R10 = 10,
3507
    TARGET_PT_R11 = 11,
3508
    TARGET_PT_R12 = 12,
3509
    TARGET_PT_R13 = 13,
3510
    TARGET_PT_R14 = 14,
3511
    TARGET_PT_R15 = 15,
3512
    TARGET_PT_R16 = 16,
3513
    TARGET_PT_R17 = 17,
3514
    TARGET_PT_R18 = 18,
3515
    TARGET_PT_R19 = 19,
3516
    TARGET_PT_R20 = 20,
3517
    TARGET_PT_R21 = 21,
3518
    TARGET_PT_R22 = 22,
3519
    TARGET_PT_R23 = 23,
3520
    TARGET_PT_R24 = 24,
3521
    TARGET_PT_R25 = 25,
3522
    TARGET_PT_R26 = 26,
3523
    TARGET_PT_R27 = 27,
3524
    TARGET_PT_R28 = 28,
3525
    TARGET_PT_R29 = 29,
3526
    TARGET_PT_R30 = 30,
3527
    TARGET_PT_R31 = 31,
3528
    TARGET_PT_NIP = 32,
3529
    TARGET_PT_MSR = 33,
3530
    TARGET_PT_ORIG_R3 = 34,
3531
    TARGET_PT_CTR = 35,
3532
    TARGET_PT_LNK = 36,
3533
    TARGET_PT_XER = 37,
3534
    TARGET_PT_CCR = 38,
3535
    /* Yes, there are two registers with #39.  One is 64-bit only.  */
3536
    TARGET_PT_MQ = 39,
3537
    TARGET_PT_SOFTE = 39,
3538
    TARGET_PT_TRAP = 40,
3539
    TARGET_PT_DAR = 41,
3540
    TARGET_PT_DSISR = 42,
3541
    TARGET_PT_RESULT = 43,
3542
    TARGET_PT_REGS_COUNT = 44
3543
};
3544

    
3545
/* See arch/powerpc/include/asm/ucontext.h.  Only used for 32-bit PPC;
3546
   on 64-bit PPC, sigcontext and mcontext are one and the same.  */
3547
struct target_mcontext {
3548
    target_ulong mc_gregs[48];
3549
    /* Includes fpscr.  */
3550
    uint64_t mc_fregs[33];
3551
    target_ulong mc_pad[2];
3552
    /* We need to handle Altivec and SPE at the same time, which no
3553
       kernel needs to do.  Fortunately, the kernel defines this bit to
3554
       be Altivec-register-large all the time, rather than trying to
3555
       twiddle it based on the specific platform.  */
3556
    union {
3557
        /* SPE vector registers.  One extra for SPEFSCR.  */
3558
        uint32_t spe[33];
3559
        /* Altivec vector registers.  The packing of VSCR and VRSAVE
3560
           varies depending on whether we're PPC64 or not: PPC64 splits
3561
           them apart; PPC32 stuffs them together.  */
3562
#if defined(TARGET_PPC64)
3563
#define QEMU_NVRREG 34
3564
#else
3565
#define QEMU_NVRREG 33
3566
#endif
3567
        ppc_avr_t altivec[QEMU_NVRREG];
3568
#undef QEMU_NVRREG
3569
    } mc_vregs __attribute__((__aligned__(16)));
3570
};
3571

    
3572
struct target_ucontext {
3573
    target_ulong tuc_flags;
3574
    target_ulong tuc_link;    /* struct ucontext __user * */
3575
    struct target_sigaltstack tuc_stack;
3576
#if !defined(TARGET_PPC64)
3577
    int32_t tuc_pad[7];
3578
    target_ulong tuc_regs;    /* struct mcontext __user *
3579
                                points to uc_mcontext field */
3580
#endif
3581
    target_sigset_t tuc_sigmask;
3582
#if defined(TARGET_PPC64)
3583
    target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
3584
    struct target_sigcontext tuc_mcontext;
3585
#else
3586
    int32_t tuc_maskext[30];
3587
    int32_t tuc_pad2[3];
3588
    struct target_mcontext tuc_mcontext;
3589
#endif
3590
};
3591

    
3592
/* See arch/powerpc/kernel/signal_32.c.  */
3593
struct target_sigframe {
3594
    struct target_sigcontext sctx;
3595
    struct target_mcontext mctx;
3596
    int32_t abigap[56];
3597
};
3598

    
3599
struct target_rt_sigframe {
3600
    struct target_siginfo info;
3601
    struct target_ucontext uc;
3602
    int32_t abigap[56];
3603
};
3604

    
3605
/* We use the mc_pad field for the signal return trampoline.  */
3606
#define tramp mc_pad
3607

    
3608
/* See arch/powerpc/kernel/signal.c.  */
3609
static target_ulong get_sigframe(struct target_sigaction *ka,
3610
                                 CPUState *env,
3611
                                 int frame_size)
3612
{
3613
    target_ulong oldsp, newsp;
3614

    
3615
    oldsp = env->gpr[1];
3616

    
3617
    if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
3618
        (sas_ss_flags(oldsp))) {
3619
        oldsp = (target_sigaltstack_used.ss_sp
3620
                 + target_sigaltstack_used.ss_size);
3621
    }
3622

    
3623
    newsp = (oldsp - frame_size) & ~0xFUL;
3624

    
3625
    return newsp;
3626
}
3627

    
3628
static int save_user_regs(CPUState *env, struct target_mcontext *frame,
3629
                          int sigret)
3630
{
3631
    target_ulong msr = env->msr;
3632
    int i;
3633
    target_ulong ccr = 0;
3634

    
3635
    /* In general, the kernel attempts to be intelligent about what it
3636
       needs to save for Altivec/FP/SPE registers.  We don't care that
3637
       much, so we just go ahead and save everything.  */
3638

    
3639
    /* Save general registers.  */
3640
    for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3641
        if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
3642
            return 1;
3643
        }
3644
    }
3645
    if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3646
        || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3647
        || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3648
        || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3649
        return 1;
3650

    
3651
    for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3652
        ccr |= env->crf[i] << (32 - ((i + 1) * 4));
3653
    }
3654
    if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3655
        return 1;
3656

    
3657
    /* Save Altivec registers if necessary.  */
3658
    if (env->insns_flags & PPC_ALTIVEC) {
3659
        for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3660
            ppc_avr_t *avr = &env->avr[i];
3661
            ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3662

    
3663
            if (__put_user(avr->u64[0], &vreg->u64[0]) ||
3664
                __put_user(avr->u64[1], &vreg->u64[1])) {
3665
                return 1;
3666
            }
3667
        }
3668
        /* Set MSR_VR in the saved MSR value to indicate that
3669
           frame->mc_vregs contains valid data.  */
3670
        msr |= MSR_VR;
3671
        if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
3672
                       &frame->mc_vregs.altivec[32].u32[3]))
3673
            return 1;
3674
    }
3675

    
3676
    /* Save floating point registers.  */
3677
    if (env->insns_flags & PPC_FLOAT) {
3678
        for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3679
            if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
3680
                return 1;
3681
            }
3682
        }
3683
        if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
3684
            return 1;
3685
    }
3686

    
3687
    /* Save SPE registers.  The kernel only saves the high half.  */
3688
    if (env->insns_flags & PPC_SPE) {
3689
#if defined(TARGET_PPC64)
3690
        for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3691
            if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
3692
                return 1;
3693
            }
3694
        }
3695
#else
3696
        for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3697
            if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3698
                return 1;
3699
            }
3700
        }
3701
#endif
3702
        /* Set MSR_SPE in the saved MSR value to indicate that
3703
           frame->mc_vregs contains valid data.  */
3704
        msr |= MSR_SPE;
3705
        if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3706
            return 1;
3707
    }
3708

    
3709
    /* Store MSR.  */
3710
    if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3711
        return 1;
3712

    
3713
    /* Set up the sigreturn trampoline: li r0,sigret; sc.  */
3714
    if (sigret) {
3715
        if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
3716
            __put_user(0x44000002UL, &frame->tramp[1])) {
3717
            return 1;
3718
        }
3719
    }
3720

    
3721
    return 0;
3722
}
3723

    
3724
static int restore_user_regs(CPUState *env,
3725
                             struct target_mcontext *frame, int sig)
3726
{
3727
    target_ulong save_r2 = 0;
3728
    target_ulong msr;
3729
    target_ulong ccr;
3730

    
3731
    int i;
3732

    
3733
    if (!sig) {
3734
        save_r2 = env->gpr[2];
3735
    }
3736

    
3737
    /* Restore general registers.  */
3738
    for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3739
        if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
3740
            return 1;
3741
        }
3742
    }
3743
    if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3744
        || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3745
        || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3746
        || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3747
        return 1;
3748
    if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3749
        return 1;
3750

    
3751
    for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3752
        env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
3753
    }
3754

    
3755
    if (!sig) {
3756
        env->gpr[2] = save_r2;
3757
    }
3758
    /* Restore MSR.  */
3759
    if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3760
        return 1;
3761

    
3762
    /* If doing signal return, restore the previous little-endian mode.  */
3763
    if (sig)
3764
        env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
3765

    
3766
    /* Restore Altivec registers if necessary.  */
3767
    if (env->insns_flags & PPC_ALTIVEC) {
3768
        for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3769
            ppc_avr_t *avr = &env->avr[i];
3770
            ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3771

    
3772
            if (__get_user(avr->u64[0], &vreg->u64[0]) ||
3773
                __get_user(avr->u64[1], &vreg->u64[1])) {
3774
                return 1;
3775
            }
3776
        }
3777
        /* Set MSR_VEC in the saved MSR value to indicate that
3778
           frame->mc_vregs contains valid data.  */
3779
        if (__get_user(env->spr[SPR_VRSAVE],
3780
                       (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
3781
            return 1;
3782
    }
3783

    
3784
    /* Restore floating point registers.  */
3785
    if (env->insns_flags & PPC_FLOAT) {
3786
        uint64_t fpscr;
3787
        for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3788
            if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
3789
                return 1;
3790
            }
3791
        }
3792
        if (__get_user(fpscr, &frame->mc_fregs[32]))
3793
            return 1;
3794
        env->fpscr = (uint32_t) fpscr;
3795
    }
3796

    
3797
    /* Save SPE registers.  The kernel only saves the high half.  */
3798
    if (env->insns_flags & PPC_SPE) {
3799
#if defined(TARGET_PPC64)
3800
        for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3801
            uint32_t hi;
3802

    
3803
            if (__get_user(hi, &frame->mc_vregs.spe[i])) {
3804
                return 1;
3805
            }
3806
            env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
3807
        }
3808
#else
3809
        for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3810
            if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3811
                return 1;
3812
            }
3813
        }
3814
#endif
3815
        if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3816
            return 1;
3817
    }
3818

    
3819
    return 0;
3820
}
3821

    
3822
static void setup_frame(int sig, struct target_sigaction *ka,
3823
                        target_sigset_t *set, CPUState *env)
3824
{
3825
    struct target_sigframe *frame;
3826
    struct target_sigcontext *sc;
3827
    target_ulong frame_addr, newsp;
3828
    int err = 0;
3829
    int signal;
3830

    
3831
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
3832
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3833
        goto sigsegv;
3834
    sc = &frame->sctx;
3835

    
3836
    signal = current_exec_domain_sig(sig);
3837

    
3838
    err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
3839
    err |= __put_user(set->sig[0], &sc->oldmask);
3840
#if defined(TARGET_PPC64)
3841
    err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
3842
#else
3843
    err |= __put_user(set->sig[1], &sc->_unused[3]);
3844
#endif
3845
    err |= __put_user(h2g(&frame->mctx), &sc->regs);
3846
    err |= __put_user(sig, &sc->signal);
3847

    
3848
    /* Save user regs.  */
3849
    err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
3850

    
3851
    /* The kernel checks for the presence of a VDSO here.  We don't
3852
       emulate a vdso, so use a sigreturn system call.  */
3853
    env->lr = (target_ulong) h2g(frame->mctx.tramp);
3854

    
3855
    /* Turn off all fp exceptions.  */
3856
    env->fpscr = 0;
3857

    
3858
    /* Create a stack frame for the caller of the handler.  */
3859
    newsp = frame_addr - SIGNAL_FRAMESIZE;
3860
    err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
3861

    
3862
    if (err)
3863
        goto sigsegv;
3864

    
3865
    /* Set up registers for signal handler.  */
3866
    env->gpr[1] = newsp;
3867
    env->gpr[3] = signal;
3868
    env->gpr[4] = (target_ulong) h2g(sc);
3869
    env->nip = (target_ulong) ka->_sa_handler;
3870
    /* Signal handlers are entered in big-endian mode.  */
3871
    env->msr &= ~MSR_LE;
3872

    
3873
    unlock_user_struct(frame, frame_addr, 1);
3874
    return;
3875

    
3876
sigsegv:
3877
    unlock_user_struct(frame, frame_addr, 1);
3878
    if (logfile)
3879
        fprintf (logfile, "segfaulting from setup_frame\n");
3880
    force_sig(TARGET_SIGSEGV);
3881
}
3882

    
3883
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3884
                           target_siginfo_t *info,
3885
                           target_sigset_t *set, CPUState *env)
3886
{
3887
    struct target_rt_sigframe *rt_sf;
3888
    struct target_mcontext *frame;
3889
    target_ulong rt_sf_addr, newsp = 0;
3890
    int i, err = 0;
3891
    int signal;
3892

    
3893
    rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
3894
    if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
3895
        goto sigsegv;
3896

    
3897
    signal = current_exec_domain_sig(sig);
3898

    
3899
    err |= copy_siginfo_to_user(&rt_sf->info, info);
3900

    
3901
    err |= __put_user(0, &rt_sf->uc.tuc_flags);
3902
    err |= __put_user(0, &rt_sf->uc.tuc_link);
3903
    err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
3904
                      &rt_sf->uc.tuc_stack.ss_sp);
3905
    err |= __put_user(sas_ss_flags(env->gpr[1]),
3906
                      &rt_sf->uc.tuc_stack.ss_flags);
3907
    err |= __put_user(target_sigaltstack_used.ss_size,
3908
                      &rt_sf->uc.tuc_stack.ss_size);
3909
    err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
3910
                      &rt_sf->uc.tuc_regs);
3911
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3912
        err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
3913
    }
3914

    
3915
    frame = &rt_sf->uc.tuc_mcontext;
3916
    err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
3917

    
3918
    /* The kernel checks for the presence of a VDSO here.  We don't
3919
       emulate a vdso, so use a sigreturn system call.  */
3920
    env->lr = (target_ulong) h2g(frame->tramp);
3921

    
3922
    /* Turn off all fp exceptions.  */
3923
    env->fpscr = 0;
3924

    
3925
    /* Create a stack frame for the caller of the handler.  */
3926
    newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
3927
    err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
3928

    
3929
    if (err)
3930
        goto sigsegv;
3931

    
3932
    /* Set up registers for signal handler.  */
3933
    env->gpr[1] = newsp;
3934
    env->gpr[3] = (target_ulong) signal;
3935
    env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
3936
    env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
3937
    env->gpr[6] = (target_ulong) h2g(rt_sf);
3938
    env->nip = (target_ulong) ka->_sa_handler;
3939
    /* Signal handlers are entered in big-endian mode.  */
3940
    env->msr &= ~MSR_LE;
3941

    
3942
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
3943
    return;
3944

    
3945
sigsegv:
3946
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
3947
    if (logfile)
3948
        fprintf (logfile, "segfaulting from setup_rt_frame\n");
3949
    force_sig(TARGET_SIGSEGV);
3950

    
3951
}
3952

    
3953
long do_sigreturn(CPUState *env)
3954
{
3955
    struct target_sigcontext *sc = NULL;
3956
    struct target_mcontext *sr = NULL;
3957
    target_ulong sr_addr, sc_addr;
3958
    sigset_t blocked;
3959
    target_sigset_t set;
3960

    
3961
    sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
3962
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
3963
        goto sigsegv;
3964

    
3965
#if defined(TARGET_PPC64)
3966
    set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
3967
#else
3968
    if(__get_user(set.sig[0], &sc->oldmask) ||
3969
       __get_user(set.sig[1], &sc->_unused[3]))
3970
       goto sigsegv;
3971
#endif
3972
    target_to_host_sigset_internal(&blocked, &set);
3973
    sigprocmask(SIG_SETMASK, &blocked, NULL);
3974

    
3975
    if (__get_user(sr_addr, &sc->regs))
3976
        goto sigsegv;
3977
    if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
3978
        goto sigsegv;
3979
    if (restore_user_regs(env, sr, 1))
3980
        goto sigsegv;
3981

    
3982
    unlock_user_struct(sr, sr_addr, 1);
3983
    unlock_user_struct(sc, sc_addr, 1);
3984
    return -TARGET_QEMU_ESIGRETURN;
3985

    
3986
sigsegv:
3987
    unlock_user_struct(sr, sr_addr, 1);
3988
    unlock_user_struct(sc, sc_addr, 1);
3989
    if (logfile)
3990
        fprintf (logfile, "segfaulting from do_sigreturn\n");
3991
    force_sig(TARGET_SIGSEGV);
3992
    return 0;
3993
}
3994

    
3995
/* See arch/powerpc/kernel/signal_32.c.  */
3996
static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
3997
{
3998
    struct target_mcontext *mcp;
3999
    target_ulong mcp_addr;
4000
    sigset_t blocked;
4001
    target_sigset_t set;
4002

    
4003
    if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4004
                       sizeof (set)))
4005
        return 1;
4006

    
4007
#if defined(TARGET_PPC64)
4008
    fprintf (stderr, "do_setcontext: not implemented\n");
4009
    return 0;
4010
#else
4011
    if (__get_user(mcp_addr, &ucp->tuc_regs))
4012
        return 1;
4013

    
4014
    if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4015
        return 1;
4016

    
4017
    target_to_host_sigset_internal(&blocked, &set);
4018
    sigprocmask(SIG_SETMASK, &blocked, NULL);
4019
    if (restore_user_regs(env, mcp, sig))
4020
        goto sigsegv;
4021

    
4022
    unlock_user_struct(mcp, mcp_addr, 1);
4023
    return 0;
4024

    
4025
sigsegv:
4026
    unlock_user_struct(mcp, mcp_addr, 1);
4027
    return 1;
4028
#endif
4029
}
4030

    
4031
long do_rt_sigreturn(CPUState *env)
4032
{
4033
    struct target_rt_sigframe *rt_sf = NULL;
4034
    target_ulong rt_sf_addr;
4035

    
4036
    rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4037
    if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4038
        goto sigsegv;
4039

    
4040
    if (do_setcontext(&rt_sf->uc, env, 1))
4041
        goto sigsegv;
4042

    
4043
    do_sigaltstack(rt_sf_addr
4044
                   + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4045
                   0, env->gpr[1]);
4046

    
4047
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
4048
    return -TARGET_QEMU_ESIGRETURN;
4049

    
4050
sigsegv:
4051
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
4052
    if (logfile)
4053
        fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
4054
    force_sig(TARGET_SIGSEGV);
4055
    return 0;
4056
}
4057

    
4058
#elif defined(TARGET_M68K)
4059

    
4060
struct target_sigcontext {
4061
    abi_ulong  sc_mask;
4062
    abi_ulong  sc_usp;
4063
    abi_ulong  sc_d0;
4064
    abi_ulong  sc_d1;
4065
    abi_ulong  sc_a0;
4066
    abi_ulong  sc_a1;
4067
    unsigned short sc_sr;
4068
    abi_ulong  sc_pc;
4069
};
4070

    
4071
struct target_sigframe
4072
{
4073
    abi_ulong pretcode;
4074
    int sig;
4075
    int code;
4076
    abi_ulong psc;
4077
    char retcode[8];
4078
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
4079
    struct target_sigcontext sc;
4080
};
4081
 
4082
typedef int target_greg_t;
4083
#define TARGET_NGREG 18
4084
typedef target_greg_t target_gregset_t[TARGET_NGREG];
4085

    
4086
typedef struct target_fpregset {
4087
    int f_fpcntl[3];
4088
    int f_fpregs[8*3];
4089
} target_fpregset_t;
4090

    
4091
struct target_mcontext {
4092
    int version;
4093
    target_gregset_t gregs;
4094
    target_fpregset_t fpregs;
4095
};
4096

    
4097
#define TARGET_MCONTEXT_VERSION 2
4098

    
4099
struct target_ucontext {
4100
    abi_ulong tuc_flags;
4101
    abi_ulong tuc_link;
4102
    target_stack_t tuc_stack;
4103
    struct target_mcontext tuc_mcontext;
4104
    abi_long tuc_filler[80];
4105
    target_sigset_t tuc_sigmask;
4106
};
4107

    
4108
struct target_rt_sigframe
4109
{
4110
    abi_ulong pretcode;
4111
    int sig;
4112
    abi_ulong pinfo;
4113
    abi_ulong puc;
4114
    char retcode[8];
4115
    struct target_siginfo info;
4116
    struct target_ucontext uc;
4117
};
4118

    
4119
static int
4120
setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask)
4121
{
4122
    int err = 0;
4123

    
4124
    err |= __put_user(mask, &sc->sc_mask);
4125
    err |= __put_user(env->aregs[7], &sc->sc_usp);
4126
    err |= __put_user(env->dregs[0], &sc->sc_d0);
4127
    err |= __put_user(env->dregs[1], &sc->sc_d1);
4128
    err |= __put_user(env->aregs[0], &sc->sc_a0);
4129
    err |= __put_user(env->aregs[1], &sc->sc_a1);
4130
    err |= __put_user(env->sr, &sc->sc_sr);
4131
    err |= __put_user(env->pc, &sc->sc_pc);
4132

    
4133
    return err;
4134
}
4135

    
4136
static int
4137
restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0)
4138
{
4139
    int err = 0;
4140
    int temp;
4141

    
4142
    err |= __get_user(env->aregs[7], &sc->sc_usp);
4143
    err |= __get_user(env->dregs[1], &sc->sc_d1);
4144
    err |= __get_user(env->aregs[0], &sc->sc_a0);
4145
    err |= __get_user(env->aregs[1], &sc->sc_a1);
4146
    err |= __get_user(env->pc, &sc->sc_pc);
4147
    err |= __get_user(temp, &sc->sc_sr);
4148
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
4149

    
4150
    *pd0 = tswapl(sc->sc_d0);
4151

    
4152
    return err;
4153
}
4154

    
4155
/*
4156
 * Determine which stack to use..
4157
 */
4158
static inline abi_ulong
4159
get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
4160
{
4161
    unsigned long sp;
4162

    
4163
    sp = regs->aregs[7];
4164

    
4165
    /* This is the X/Open sanctioned signal stack switching.  */
4166
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4167
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4168
    }
4169

    
4170
    return ((sp - frame_size) & -8UL);
4171
}
4172

    
4173
static void setup_frame(int sig, struct target_sigaction *ka,
4174
                        target_sigset_t *set, CPUState *env)
4175
{
4176
    struct target_sigframe *frame;
4177
    abi_ulong frame_addr;
4178
    abi_ulong retcode_addr;
4179
    abi_ulong sc_addr;
4180
    int err = 0;
4181
    int i;
4182

    
4183
    frame_addr = get_sigframe(ka, env, sizeof *frame);
4184
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4185
        goto give_sigsegv;
4186

    
4187
    err |= __put_user(sig, &frame->sig);
4188

    
4189
    sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4190
    err |= __put_user(sc_addr, &frame->psc);
4191

    
4192
    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4193
    if (err)
4194
        goto give_sigsegv;
4195

    
4196
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4197
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4198
            goto give_sigsegv;
4199
    }
4200

    
4201
    /* Set up to return from userspace.  */
4202

    
4203
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4204
    err |= __put_user(retcode_addr, &frame->pretcode);
4205

    
4206
    /* moveq #,d0; trap #0 */
4207

    
4208
    err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4209
                      (long *)(frame->retcode));
4210

    
4211
    if (err)
4212
        goto give_sigsegv;
4213

    
4214
    /* Set up to return from userspace */
4215

    
4216
    env->aregs[7] = frame_addr;
4217
    env->pc = ka->_sa_handler;
4218

    
4219
    unlock_user_struct(frame, frame_addr, 1);
4220
    return;
4221

    
4222
give_sigsegv:
4223
    unlock_user_struct(frame, frame_addr, 1);
4224
    force_sig(TARGET_SIGSEGV);
4225
}
4226

    
4227
static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
4228
                                           CPUState *env)
4229
{
4230
    target_greg_t *gregs = uc->tuc_mcontext.gregs;
4231
    int err;
4232

    
4233
    err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
4234
    err |= __put_user(env->dregs[0], &gregs[0]);
4235
    err |= __put_user(env->dregs[1], &gregs[1]);
4236
    err |= __put_user(env->dregs[2], &gregs[2]);
4237
    err |= __put_user(env->dregs[3], &gregs[3]);
4238
    err |= __put_user(env->dregs[4], &gregs[4]);
4239
    err |= __put_user(env->dregs[5], &gregs[5]);
4240
    err |= __put_user(env->dregs[6], &gregs[6]);
4241
    err |= __put_user(env->dregs[7], &gregs[7]);
4242
    err |= __put_user(env->aregs[0], &gregs[8]);
4243
    err |= __put_user(env->aregs[1], &gregs[9]);
4244
    err |= __put_user(env->aregs[2], &gregs[10]);
4245
    err |= __put_user(env->aregs[3], &gregs[11]);
4246
    err |= __put_user(env->aregs[4], &gregs[12]);
4247
    err |= __put_user(env->aregs[5], &gregs[13]);
4248
    err |= __put_user(env->aregs[6], &gregs[14]);
4249
    err |= __put_user(env->aregs[7], &gregs[15]);
4250
    err |= __put_user(env->pc, &gregs[16]);
4251
    err |= __put_user(env->sr, &gregs[17]);
4252

    
4253
    return err;
4254
}
4255
 
4256
static inline int target_rt_restore_ucontext(CPUState *env,
4257
                                             struct target_ucontext *uc,
4258
                                             int *pd0)
4259
{
4260
    int temp;
4261
    int err;
4262
    target_greg_t *gregs = uc->tuc_mcontext.gregs;
4263
    
4264
    err = __get_user(temp, &uc->tuc_mcontext.version);
4265
    if (temp != TARGET_MCONTEXT_VERSION)
4266
        goto badframe;
4267

    
4268
    /* restore passed registers */
4269
    err |= __get_user(env->dregs[0], &gregs[0]);
4270
    err |= __get_user(env->dregs[1], &gregs[1]);
4271
    err |= __get_user(env->dregs[2], &gregs[2]);
4272
    err |= __get_user(env->dregs[3], &gregs[3]);
4273
    err |= __get_user(env->dregs[4], &gregs[4]);
4274
    err |= __get_user(env->dregs[5], &gregs[5]);
4275
    err |= __get_user(env->dregs[6], &gregs[6]);
4276
    err |= __get_user(env->dregs[7], &gregs[7]);
4277
    err |= __get_user(env->aregs[0], &gregs[8]);
4278
    err |= __get_user(env->aregs[1], &gregs[9]);
4279
    err |= __get_user(env->aregs[2], &gregs[10]);
4280
    err |= __get_user(env->aregs[3], &gregs[11]);
4281
    err |= __get_user(env->aregs[4], &gregs[12]);
4282
    err |= __get_user(env->aregs[5], &gregs[13]);
4283
    err |= __get_user(env->aregs[6], &gregs[14]);
4284
    err |= __get_user(env->aregs[7], &gregs[15]);
4285
    err |= __get_user(env->pc, &gregs[16]);
4286
    err |= __get_user(temp, &gregs[17]);
4287
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
4288

    
4289
    *pd0 = env->dregs[0];
4290
    return err;
4291

    
4292
badframe:
4293
    return 1;
4294
}
4295

    
4296
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4297
                           target_siginfo_t *info,
4298
                           target_sigset_t *set, CPUState *env)
4299
{
4300
    struct target_rt_sigframe *frame;
4301
    abi_ulong frame_addr;
4302
    abi_ulong retcode_addr;
4303
    abi_ulong info_addr;
4304
    abi_ulong uc_addr;
4305
    int err = 0;
4306
    int i;
4307

    
4308
    frame_addr = get_sigframe(ka, env, sizeof *frame);
4309
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4310
        goto give_sigsegv;
4311

    
4312
    err |= __put_user(sig, &frame->sig);
4313

    
4314
    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4315
    err |= __put_user(info_addr, &frame->pinfo);
4316

    
4317
    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4318
    err |= __put_user(uc_addr, &frame->puc);
4319

    
4320
    err |= copy_siginfo_to_user(&frame->info, info);
4321

    
4322
    /* Create the ucontext */
4323

    
4324
    err |= __put_user(0, &frame->uc.tuc_flags);
4325
    err |= __put_user(0, &frame->uc.tuc_link);
4326
    err |= __put_user(target_sigaltstack_used.ss_sp,
4327
                      &frame->uc.tuc_stack.ss_sp);
4328
    err |= __put_user(sas_ss_flags(env->aregs[7]),
4329
                      &frame->uc.tuc_stack.ss_flags);
4330
    err |= __put_user(target_sigaltstack_used.ss_size,
4331
                      &frame->uc.tuc_stack.ss_size);
4332
    err |= target_rt_setup_ucontext(&frame->uc, env);
4333

    
4334
    if (err)
4335
            goto give_sigsegv;
4336

    
4337
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4338
        if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
4339
            goto give_sigsegv;
4340
    }
4341

    
4342
    /* Set up to return from userspace.  */
4343

    
4344
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4345
    err |= __put_user(retcode_addr, &frame->pretcode);
4346

    
4347
    /* moveq #,d0; notb d0; trap #0 */
4348

    
4349
    err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
4350
                      (long *)(frame->retcode + 0));
4351
    err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
4352

    
4353
    if (err)
4354
        goto give_sigsegv;
4355

    
4356
    /* Set up to return from userspace */
4357

    
4358
    env->aregs[7] = frame_addr;
4359
    env->pc = ka->_sa_handler;
4360

    
4361
    unlock_user_struct(frame, frame_addr, 1);
4362
    return;
4363

    
4364
give_sigsegv:
4365
    unlock_user_struct(frame, frame_addr, 1);
4366
    force_sig(TARGET_SIGSEGV);
4367
}
4368

    
4369
long do_sigreturn(CPUState *env)
4370
{
4371
    struct target_sigframe *frame;
4372
    abi_ulong frame_addr = env->aregs[7] - 4;
4373
    target_sigset_t target_set;
4374
    sigset_t set;
4375
    int d0, i;
4376

    
4377
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4378
        goto badframe;
4379

    
4380
    /* set blocked signals */
4381

    
4382
    if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4383
        goto badframe;
4384

    
4385
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4386
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4387
            goto badframe;
4388
    }
4389

    
4390
    target_to_host_sigset_internal(&set, &target_set);
4391
    sigprocmask(SIG_SETMASK, &set, NULL);
4392

    
4393
    /* restore registers */
4394

    
4395
    if (restore_sigcontext(env, &frame->sc, &d0))
4396
        goto badframe;
4397

    
4398
    unlock_user_struct(frame, frame_addr, 0);
4399
    return d0;
4400

    
4401
badframe:
4402
    unlock_user_struct(frame, frame_addr, 0);
4403
    force_sig(TARGET_SIGSEGV);
4404
    return 0;
4405
}
4406

    
4407
long do_rt_sigreturn(CPUState *env)
4408
{
4409
    struct target_rt_sigframe *frame;
4410
    abi_ulong frame_addr = env->aregs[7] - 4;
4411
    target_sigset_t target_set;
4412
    sigset_t set;
4413
    int d0;
4414

    
4415
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4416
        goto badframe;
4417

    
4418
    target_to_host_sigset_internal(&set, &target_set);
4419
    sigprocmask(SIG_SETMASK, &set, NULL);
4420

    
4421
    /* restore registers */
4422

    
4423
    if (target_rt_restore_ucontext(env, &frame->uc, &d0))
4424
        goto badframe;
4425

    
4426
    if (do_sigaltstack(frame_addr +
4427
                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
4428
                       0, get_sp_from_cpustate(env)) == -EFAULT)
4429
        goto badframe;
4430

    
4431
    unlock_user_struct(frame, frame_addr, 0);
4432
    return d0;
4433

    
4434
badframe:
4435
    unlock_user_struct(frame, frame_addr, 0);
4436
    force_sig(TARGET_SIGSEGV);
4437
    return 0;
4438
}
4439

    
4440
#elif defined(TARGET_ALPHA)
4441

    
4442
struct target_sigcontext {
4443
    abi_long sc_onstack;
4444
    abi_long sc_mask;
4445
    abi_long sc_pc;
4446
    abi_long sc_ps;
4447
    abi_long sc_regs[32];
4448
    abi_long sc_ownedfp;
4449
    abi_long sc_fpregs[32];
4450
    abi_ulong sc_fpcr;
4451
    abi_ulong sc_fp_control;
4452
    abi_ulong sc_reserved1;
4453
    abi_ulong sc_reserved2;
4454
    abi_ulong sc_ssize;
4455
    abi_ulong sc_sbase;
4456
    abi_ulong sc_traparg_a0;
4457
    abi_ulong sc_traparg_a1;
4458
    abi_ulong sc_traparg_a2;
4459
    abi_ulong sc_fp_trap_pc;
4460
    abi_ulong sc_fp_trigger_sum;
4461
    abi_ulong sc_fp_trigger_inst;
4462
};
4463

    
4464
struct target_ucontext {
4465
    abi_ulong tuc_flags;
4466
    abi_ulong tuc_link;
4467
    abi_ulong tuc_osf_sigmask;
4468
    target_stack_t tuc_stack;
4469
    struct target_sigcontext tuc_mcontext;
4470
    target_sigset_t tuc_sigmask;
4471
};
4472

    
4473
struct target_sigframe {
4474
    struct target_sigcontext sc;
4475
    unsigned int retcode[3];
4476
};
4477

    
4478
struct target_rt_sigframe {
4479
    target_siginfo_t info;
4480
    struct target_ucontext uc;
4481
    unsigned int retcode[3];
4482
};
4483

    
4484
#define INSN_MOV_R30_R16        0x47fe0410
4485
#define INSN_LDI_R0             0x201f0000
4486
#define INSN_CALLSYS            0x00000083
4487

    
4488
static int setup_sigcontext(struct target_sigcontext *sc, CPUState *env,
4489
                            abi_ulong frame_addr, target_sigset_t *set)
4490
{
4491
    int i, err = 0;
4492

    
4493
    err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4494
    err |= __put_user(set->sig[0], &sc->sc_mask);
4495
    err |= __put_user(env->pc, &sc->sc_pc);
4496
    err |= __put_user(8, &sc->sc_ps);
4497

    
4498
    for (i = 0; i < 31; ++i) {
4499
        err |= __put_user(env->ir[i], &sc->sc_regs[i]);
4500
    }
4501
    err |= __put_user(0, &sc->sc_regs[31]);
4502

    
4503
    for (i = 0; i < 31; ++i) {
4504
        err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
4505
    }
4506
    err |= __put_user(0, &sc->sc_fpregs[31]);
4507
    err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
4508

    
4509
    err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
4510
    err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
4511
    err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
4512

    
4513
    return err;
4514
}
4515

    
4516
static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
4517
{
4518
    uint64_t fpcr;
4519
    int i, err = 0;
4520

    
4521
    err |= __get_user(env->pc, &sc->sc_pc);
4522

    
4523
    for (i = 0; i < 31; ++i) {
4524
        err |= __get_user(env->ir[i], &sc->sc_regs[i]);
4525
    }
4526
    for (i = 0; i < 31; ++i) {
4527
        err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
4528
    }
4529

    
4530
    err |= __get_user(fpcr, &sc->sc_fpcr);
4531
    cpu_alpha_store_fpcr(env, fpcr);
4532

    
4533
    return err;
4534
}
4535

    
4536
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
4537
                                     CPUState *env, unsigned long framesize)
4538
{
4539
    abi_ulong sp = env->ir[IR_SP];
4540

    
4541
    /* This is the X/Open sanctioned signal stack switching.  */
4542
    if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
4543
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4544
    }
4545
    return (sp - framesize) & -32;
4546
}
4547

    
4548
static void setup_frame(int sig, struct target_sigaction *ka,
4549
                        target_sigset_t *set, CPUState *env)
4550
{
4551
    abi_ulong frame_addr, r26;
4552
    struct target_sigframe *frame;
4553
    int err = 0;
4554

    
4555
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
4556
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4557
        goto give_sigsegv;
4558
    }
4559

    
4560
    err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
4561

    
4562
    if (ka->sa_restorer) {
4563
        r26 = ka->sa_restorer;
4564
    } else {
4565
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4566
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
4567
                          &frame->retcode[1]);
4568
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4569
        /* imb() */
4570
        r26 = frame_addr;
4571
    }
4572

    
4573
    unlock_user_struct(frame, frame_addr, 1);
4574

    
4575
    if (err) {
4576
    give_sigsegv:
4577
        if (sig == TARGET_SIGSEGV) {
4578
            ka->_sa_handler = TARGET_SIG_DFL;
4579
        }
4580
        force_sig(TARGET_SIGSEGV);
4581
    }
4582

    
4583
    env->ir[IR_RA] = r26;
4584
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
4585
    env->ir[IR_A0] = sig;
4586
    env->ir[IR_A1] = 0;
4587
    env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
4588
    env->ir[IR_SP] = frame_addr;
4589
}
4590

    
4591
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4592
                           target_siginfo_t *info,
4593
                           target_sigset_t *set, CPUState *env)
4594
{
4595
    abi_ulong frame_addr, r26;
4596
    struct target_rt_sigframe *frame;
4597
    int i, err = 0;
4598

    
4599
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
4600
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4601
        goto give_sigsegv;
4602
    }
4603

    
4604
    err |= copy_siginfo_to_user(&frame->info, info);
4605

    
4606
    err |= __put_user(0, &frame->uc.tuc_flags);
4607
    err |= __put_user(0, &frame->uc.tuc_link);
4608
    err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
4609
    err |= __put_user(target_sigaltstack_used.ss_sp,
4610
                      &frame->uc.tuc_stack.ss_sp);
4611
    err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
4612
                      &frame->uc.tuc_stack.ss_flags);
4613
    err |= __put_user(target_sigaltstack_used.ss_size,
4614
                      &frame->uc.tuc_stack.ss_size);
4615
    err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
4616
    for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
4617
        err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
4618
    }
4619

    
4620
    if (ka->sa_restorer) {
4621
        r26 = ka->sa_restorer;
4622
    } else {
4623
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4624
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
4625
                          &frame->retcode[1]);
4626
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4627
        /* imb(); */
4628
        r26 = frame_addr;
4629
    }
4630

    
4631
    if (err) {
4632
    give_sigsegv:
4633
       if (sig == TARGET_SIGSEGV) {
4634
            ka->_sa_handler = TARGET_SIG_DFL;
4635
        }
4636
        force_sig(TARGET_SIGSEGV);
4637
    }
4638

    
4639
    env->ir[IR_RA] = r26;
4640
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
4641
    env->ir[IR_A0] = sig;
4642
    env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
4643
    env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
4644
    env->ir[IR_SP] = frame_addr;
4645
}
4646

    
4647
long do_sigreturn(CPUState *env)
4648
{
4649
    struct target_sigcontext *sc;
4650
    abi_ulong sc_addr = env->ir[IR_A0];
4651
    target_sigset_t target_set;
4652
    sigset_t set;
4653

    
4654
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
4655
        goto badframe;
4656
    }
4657

    
4658
    target_sigemptyset(&target_set);
4659
    if (__get_user(target_set.sig[0], &sc->sc_mask)) {
4660
        goto badframe;
4661
    }
4662

    
4663
    target_to_host_sigset_internal(&set, &target_set);
4664
    sigprocmask(SIG_SETMASK, &set, NULL);
4665

    
4666
    if (restore_sigcontext(env, sc)) {
4667
        goto badframe;
4668
    }
4669
    unlock_user_struct(sc, sc_addr, 0);
4670
    return env->ir[IR_V0];
4671

    
4672
 badframe:
4673
    unlock_user_struct(sc, sc_addr, 0);
4674
    force_sig(TARGET_SIGSEGV);
4675
}
4676

    
4677
long do_rt_sigreturn(CPUState *env)
4678
{
4679
    abi_ulong frame_addr = env->ir[IR_A0];
4680
    struct target_rt_sigframe *frame;
4681
    sigset_t set;
4682

    
4683
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4684
        goto badframe;
4685
    }
4686
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4687
    sigprocmask(SIG_SETMASK, &set, NULL);
4688

    
4689
    if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
4690
        goto badframe;
4691
    }
4692
    if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
4693
                                             uc.tuc_stack),
4694
                       0, env->ir[IR_SP]) == -EFAULT) {
4695
        goto badframe;
4696
    }
4697

    
4698
    unlock_user_struct(frame, frame_addr, 0);
4699
    return env->ir[IR_V0];
4700

    
4701

    
4702
 badframe:
4703
    unlock_user_struct(frame, frame_addr, 0);
4704
    force_sig(TARGET_SIGSEGV);
4705
}
4706

    
4707
#else
4708

    
4709
static void setup_frame(int sig, struct target_sigaction *ka,
4710
                        target_sigset_t *set, CPUState *env)
4711
{
4712
    fprintf(stderr, "setup_frame: not implemented\n");
4713
}
4714

    
4715
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4716
                           target_siginfo_t *info,
4717
                           target_sigset_t *set, CPUState *env)
4718
{
4719
    fprintf(stderr, "setup_rt_frame: not implemented\n");
4720
}
4721

    
4722
long do_sigreturn(CPUState *env)
4723
{
4724
    fprintf(stderr, "do_sigreturn: not implemented\n");
4725
    return -TARGET_ENOSYS;
4726
}
4727

    
4728
long do_rt_sigreturn(CPUState *env)
4729
{
4730
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
4731
    return -TARGET_ENOSYS;
4732
}
4733

    
4734
#endif
4735

    
4736
void process_pending_signals(CPUState *cpu_env)
4737
{
4738
    int sig;
4739
    abi_ulong handler;
4740
    sigset_t set, old_set;
4741
    target_sigset_t target_old_set;
4742
    struct emulated_sigtable *k;
4743
    struct target_sigaction *sa;
4744
    struct sigqueue *q;
4745
    TaskState *ts = cpu_env->opaque;
4746

    
4747
    if (!ts->signal_pending)
4748
        return;
4749

    
4750
    /* FIXME: This is not threadsafe.  */
4751
    k = ts->sigtab;
4752
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
4753
        if (k->pending)
4754
            goto handle_signal;
4755
        k++;
4756
    }
4757
    /* if no signal is pending, just return */
4758
    ts->signal_pending = 0;
4759
    return;
4760

    
4761
 handle_signal:
4762
#ifdef DEBUG_SIGNAL
4763
    fprintf(stderr, "qemu: process signal %d\n", sig);
4764
#endif
4765
    /* dequeue signal */
4766
    q = k->first;
4767
    k->first = q->next;
4768
    if (!k->first)
4769
        k->pending = 0;
4770

    
4771
    sig = gdb_handlesig (cpu_env, sig);
4772
    if (!sig) {
4773
        sa = NULL;
4774
        handler = TARGET_SIG_IGN;
4775
    } else {
4776
        sa = &sigact_table[sig - 1];
4777
        handler = sa->_sa_handler;
4778
    }
4779

    
4780
    if (handler == TARGET_SIG_DFL) {
4781
        /* default handler : ignore some signal. The other are job control or fatal */
4782
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
4783
            kill(getpid(),SIGSTOP);
4784
        } else if (sig != TARGET_SIGCHLD &&
4785
                   sig != TARGET_SIGURG &&
4786
                   sig != TARGET_SIGWINCH &&
4787
                   sig != TARGET_SIGCONT) {
4788
            force_sig(sig);
4789
        }
4790
    } else if (handler == TARGET_SIG_IGN) {
4791
        /* ignore sig */
4792
    } else if (handler == TARGET_SIG_ERR) {
4793
        force_sig(sig);
4794
    } else {
4795
        /* compute the blocked signals during the handler execution */
4796
        target_to_host_sigset(&set, &sa->sa_mask);
4797
        /* SA_NODEFER indicates that the current signal should not be
4798
           blocked during the handler */
4799
        if (!(sa->sa_flags & TARGET_SA_NODEFER))
4800
            sigaddset(&set, target_to_host_signal(sig));
4801

    
4802
        /* block signals in the handler using Linux */
4803
        sigprocmask(SIG_BLOCK, &set, &old_set);
4804
        /* save the previous blocked signal state to restore it at the
4805
           end of the signal execution (see do_sigreturn) */
4806
        host_to_target_sigset_internal(&target_old_set, &old_set);
4807

    
4808
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
4809
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
4810
        {
4811
            CPUX86State *env = cpu_env;
4812
            if (env->eflags & VM_MASK)
4813
                save_v86_state(env);
4814
        }
4815
#endif
4816
        /* prepare the stack frame of the virtual CPU */
4817
        if (sa->sa_flags & TARGET_SA_SIGINFO)
4818
            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
4819
        else
4820
            setup_frame(sig, sa, &target_old_set, cpu_env);
4821
        if (sa->sa_flags & TARGET_SA_RESETHAND)
4822
            sa->_sa_handler = TARGET_SIG_DFL;
4823
    }
4824
    if (q != &k->info)
4825
        free_sigqueue(cpu_env, q);
4826
}