Statistics
| Branch: | Revision:

root / linux-user / signal.c @ 7c9958b0

History | View | Annotate | Download (156.5 kB)

1
/*
2
 *  Emulation of Linux signals
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, 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 <errno.h>
25
#include <assert.h>
26
#include <sys/ucontext.h>
27
#include <sys/resource.h>
28

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

    
33
//#define DEBUG_SIGNAL
34

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

    
41
static struct target_sigaction sigact_table[TARGET_NSIG];
42

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
200
/* siginfo conversion */
201

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

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

    
248

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

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

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

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

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

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

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

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

    
348
/* signal queue handling */
349

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
639
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
640
                                       const target_siginfo_t *info)
641
{
642
    tswap_siginfo(tinfo, info);
643
    return 0;
644
}
645

    
646
static inline int current_exec_domain_sig(int sig)
647
{
648
    return /* current->exec_domain && current->exec_domain->signal_invmap
649
              && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
650
}
651

    
652
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
653

    
654
/* from the Linux kernel */
655

    
656
struct target_fpreg {
657
        uint16_t significand[4];
658
        uint16_t exponent;
659
};
660

    
661
struct target_fpxreg {
662
        uint16_t significand[4];
663
        uint16_t exponent;
664
        uint16_t padding[3];
665
};
666

    
667
struct target_xmmreg {
668
        abi_ulong element[4];
669
};
670

    
671
struct target_fpstate {
672
        /* Regular FPU environment */
673
        abi_ulong       cw;
674
        abi_ulong       sw;
675
        abi_ulong       tag;
676
        abi_ulong       ipoff;
677
        abi_ulong       cssel;
678
        abi_ulong       dataoff;
679
        abi_ulong       datasel;
680
        struct target_fpreg        _st[8];
681
        uint16_t        status;
682
        uint16_t        magic;                /* 0xffff = regular FPU data only */
683

    
684
        /* FXSR FPU environment */
685
        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
686
        abi_ulong       mxcsr;
687
        abi_ulong       reserved;
688
        struct target_fpxreg        _fxsr_st[8];        /* FXSR FPU reg data is ignored */
689
        struct target_xmmreg        _xmm[8];
690
        abi_ulong       padding[56];
691
};
692

    
693
#define X86_FXSR_MAGIC                0x0000
694

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

    
720
struct target_ucontext {
721
        abi_ulong         tuc_flags;
722
        abi_ulong         tuc_link;
723
        target_stack_t          tuc_stack;
724
        struct target_sigcontext tuc_mcontext;
725
        target_sigset_t          tuc_sigmask;        /* mask last for extensibility */
726
};
727

    
728
struct sigframe
729
{
730
    abi_ulong pretcode;
731
    int sig;
732
    struct target_sigcontext sc;
733
    struct target_fpstate fpstate;
734
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
735
    char retcode[8];
736
};
737

    
738
struct rt_sigframe
739
{
740
    abi_ulong pretcode;
741
    int sig;
742
    abi_ulong pinfo;
743
    abi_ulong puc;
744
    struct target_siginfo info;
745
    struct target_ucontext uc;
746
    struct target_fpstate fpstate;
747
    char retcode[8];
748
};
749

    
750
/*
751
 * Set up a signal frame.
752
 */
753

    
754
/* XXX: save x87 state */
755
static int
756
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
757
                 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
758
{
759
        int err = 0;
760
        uint16_t magic;
761

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

    
783
        cpu_x86_fsave(env, fpstate_addr, 1);
784
        fpstate->status = fpstate->sw;
785
        magic = 0xffff;
786
        err |= __put_user(magic, &fpstate->magic);
787
        err |= __put_user(fpstate_addr, &sc->fpstate);
788

    
789
        /* non-iBCS2 extensions.. */
790
        err |= __put_user(mask, &sc->oldmask);
791
        err |= __put_user(env->cr[2], &sc->cr2);
792
        return err;
793
}
794

    
795
/*
796
 * Determine which stack to use..
797
 */
798

    
799
static inline abi_ulong
800
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
801
{
802
        unsigned long esp;
803

    
804
        /* Default to using normal stack */
805
        esp = env->regs[R_ESP];
806
        /* This is the X/Open sanctioned signal stack switching.  */
807
        if (ka->sa_flags & TARGET_SA_ONSTACK) {
808
            if (sas_ss_flags(esp) == 0)
809
                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
810
        }
811

    
812
        /* This is the legacy signal stack switching. */
813
        else
814
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
815
            !(ka->sa_flags & TARGET_SA_RESTORER) &&
816
            ka->sa_restorer) {
817
            esp = (unsigned long) ka->sa_restorer;
818
        }
819
        return (esp - frame_size) & -8ul;
820
}
821

    
822
/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
823
static void setup_frame(int sig, struct target_sigaction *ka,
824
                        target_sigset_t *set, CPUX86State *env)
825
{
826
        abi_ulong frame_addr;
827
        struct sigframe *frame;
828
        int i, err = 0;
829

    
830
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
831

    
832
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
833
                goto give_sigsegv;
834

    
835
        err |= __put_user(current_exec_domain_sig(sig),
836
                          &frame->sig);
837
        if (err)
838
                goto give_sigsegv;
839

    
840
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
841
                         frame_addr + offsetof(struct sigframe, fpstate));
842
        if (err)
843
                goto give_sigsegv;
844

    
845
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
846
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
847
                goto give_sigsegv;
848
        }
849

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

    
867
        if (err)
868
                goto give_sigsegv;
869

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

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

    
880
        unlock_user_struct(frame, frame_addr, 1);
881

    
882
        return;
883

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

    
891
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
892
static void setup_rt_frame(int sig, struct target_sigaction *ka,
893
                           target_siginfo_t *info,
894
                           target_sigset_t *set, CPUX86State *env)
895
{
896
        abi_ulong frame_addr, addr;
897
        struct rt_sigframe *frame;
898
        int i, err = 0;
899

    
900
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
901

    
902
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
903
                goto give_sigsegv;
904

    
905
        err |= __put_user(current_exec_domain_sig(sig),
906
                          &frame->sig);
907
        addr = frame_addr + offsetof(struct rt_sigframe, info);
908
        err |= __put_user(addr, &frame->pinfo);
909
        addr = frame_addr + offsetof(struct rt_sigframe, uc);
910
        err |= __put_user(addr, &frame->puc);
911
        err |= copy_siginfo_to_user(&frame->info, info);
912
        if (err)
913
                goto give_sigsegv;
914

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

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

    
947
        if (err)
948
                goto give_sigsegv;
949

    
950
        /* Set up registers for signal handler */
951
        env->regs[R_ESP] = frame_addr;
952
        env->eip = ka->_sa_handler;
953

    
954
        cpu_x86_load_seg(env, R_DS, __USER_DS);
955
        cpu_x86_load_seg(env, R_ES, __USER_DS);
956
        cpu_x86_load_seg(env, R_SS, __USER_DS);
957
        cpu_x86_load_seg(env, R_CS, __USER_CS);
958
        env->eflags &= ~TF_MASK;
959

    
960
        unlock_user_struct(frame, frame_addr, 1);
961

    
962
        return;
963

    
964
give_sigsegv:
965
        unlock_user_struct(frame, frame_addr, 1);
966
        if (sig == TARGET_SIGSEGV)
967
                ka->_sa_handler = TARGET_SIG_DFL;
968
        force_sig(TARGET_SIGSEGV /* , current */);
969
}
970

    
971
static int
972
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
973
{
974
        unsigned int err = 0;
975
        abi_ulong fpstate_addr;
976
        unsigned int tmpflags;
977

    
978
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
979
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
980
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
981
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
982

    
983
        env->regs[R_EDI] = tswapl(sc->edi);
984
        env->regs[R_ESI] = tswapl(sc->esi);
985
        env->regs[R_EBP] = tswapl(sc->ebp);
986
        env->regs[R_ESP] = tswapl(sc->esp);
987
        env->regs[R_EBX] = tswapl(sc->ebx);
988
        env->regs[R_EDX] = tswapl(sc->edx);
989
        env->regs[R_ECX] = tswapl(sc->ecx);
990
        env->eip = tswapl(sc->eip);
991

    
992
        cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
993
        cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
994

    
995
        tmpflags = tswapl(sc->eflags);
996
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
997
        //                regs->orig_eax = -1;                /* disable syscall checks */
998

    
999
        fpstate_addr = tswapl(sc->fpstate);
1000
        if (fpstate_addr != 0) {
1001
                if (!access_ok(VERIFY_READ, fpstate_addr, 
1002
                               sizeof(struct target_fpstate)))
1003
                        goto badframe;
1004
                cpu_x86_frstor(env, fpstate_addr, 1);
1005
        }
1006

    
1007
        *peax = tswapl(sc->eax);
1008
        return err;
1009
badframe:
1010
        return 1;
1011
}
1012

    
1013
long do_sigreturn(CPUX86State *env)
1014
{
1015
    struct sigframe *frame;
1016
    abi_ulong frame_addr = env->regs[R_ESP] - 8;
1017
    target_sigset_t target_set;
1018
    sigset_t set;
1019
    int eax, i;
1020

    
1021
#if defined(DEBUG_SIGNAL)
1022
    fprintf(stderr, "do_sigreturn\n");
1023
#endif
1024
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1025
        goto badframe;
1026
    /* set blocked signals */
1027
    if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1028
        goto badframe;
1029
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1030
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1031
            goto badframe;
1032
    }
1033

    
1034
    target_to_host_sigset_internal(&set, &target_set);
1035
    sigprocmask(SIG_SETMASK, &set, NULL);
1036

    
1037
    /* restore registers */
1038
    if (restore_sigcontext(env, &frame->sc, &eax))
1039
        goto badframe;
1040
    unlock_user_struct(frame, frame_addr, 0);
1041
    return eax;
1042

    
1043
badframe:
1044
    unlock_user_struct(frame, frame_addr, 0);
1045
    force_sig(TARGET_SIGSEGV);
1046
    return 0;
1047
}
1048

    
1049
long do_rt_sigreturn(CPUX86State *env)
1050
{
1051
        abi_ulong frame_addr;
1052
        struct rt_sigframe *frame;
1053
        sigset_t set;
1054
        int eax;
1055

    
1056
        frame_addr = env->regs[R_ESP] - 4;
1057
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1058
                goto badframe;
1059
        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1060
        sigprocmask(SIG_SETMASK, &set, NULL);
1061

    
1062
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1063
                goto badframe;
1064

    
1065
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
1066
                           get_sp_from_cpustate(env)) == -EFAULT)
1067
                goto badframe;
1068

    
1069
        unlock_user_struct(frame, frame_addr, 0);
1070
        return eax;
1071

    
1072
badframe:
1073
        unlock_user_struct(frame, frame_addr, 0);
1074
        force_sig(TARGET_SIGSEGV);
1075
        return 0;
1076
}
1077

    
1078
#elif defined(TARGET_ARM)
1079

    
1080
struct target_sigcontext {
1081
        abi_ulong trap_no;
1082
        abi_ulong error_code;
1083
        abi_ulong oldmask;
1084
        abi_ulong arm_r0;
1085
        abi_ulong arm_r1;
1086
        abi_ulong arm_r2;
1087
        abi_ulong arm_r3;
1088
        abi_ulong arm_r4;
1089
        abi_ulong arm_r5;
1090
        abi_ulong arm_r6;
1091
        abi_ulong arm_r7;
1092
        abi_ulong arm_r8;
1093
        abi_ulong arm_r9;
1094
        abi_ulong arm_r10;
1095
        abi_ulong arm_fp;
1096
        abi_ulong arm_ip;
1097
        abi_ulong arm_sp;
1098
        abi_ulong arm_lr;
1099
        abi_ulong arm_pc;
1100
        abi_ulong arm_cpsr;
1101
        abi_ulong fault_address;
1102
};
1103

    
1104
struct target_ucontext_v1 {
1105
    abi_ulong tuc_flags;
1106
    abi_ulong tuc_link;
1107
    target_stack_t tuc_stack;
1108
    struct target_sigcontext tuc_mcontext;
1109
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1110
};
1111

    
1112
struct target_ucontext_v2 {
1113
    abi_ulong tuc_flags;
1114
    abi_ulong tuc_link;
1115
    target_stack_t tuc_stack;
1116
    struct target_sigcontext tuc_mcontext;
1117
    target_sigset_t  tuc_sigmask;        /* mask last for extensibility */
1118
    char __unused[128 - sizeof(target_sigset_t)];
1119
    abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1120
};
1121

    
1122
struct target_user_vfp {
1123
    uint64_t fpregs[32];
1124
    abi_ulong fpscr;
1125
};
1126

    
1127
struct target_user_vfp_exc {
1128
    abi_ulong fpexc;
1129
    abi_ulong fpinst;
1130
    abi_ulong fpinst2;
1131
};
1132

    
1133
struct target_vfp_sigframe {
1134
    abi_ulong magic;
1135
    abi_ulong size;
1136
    struct target_user_vfp ufp;
1137
    struct target_user_vfp_exc ufp_exc;
1138
} __attribute__((__aligned__(8)));
1139

    
1140
struct target_iwmmxt_sigframe {
1141
    abi_ulong magic;
1142
    abi_ulong size;
1143
    uint64_t regs[16];
1144
    /* Note that not all the coprocessor control registers are stored here */
1145
    uint32_t wcssf;
1146
    uint32_t wcasf;
1147
    uint32_t wcgr0;
1148
    uint32_t wcgr1;
1149
    uint32_t wcgr2;
1150
    uint32_t wcgr3;
1151
} __attribute__((__aligned__(8)));
1152

    
1153
#define TARGET_VFP_MAGIC 0x56465001
1154
#define TARGET_IWMMXT_MAGIC 0x12ef842a
1155

    
1156
struct sigframe_v1
1157
{
1158
    struct target_sigcontext sc;
1159
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
1160
    abi_ulong retcode;
1161
};
1162

    
1163
struct sigframe_v2
1164
{
1165
    struct target_ucontext_v2 uc;
1166
    abi_ulong retcode;
1167
};
1168

    
1169
struct rt_sigframe_v1
1170
{
1171
    abi_ulong pinfo;
1172
    abi_ulong puc;
1173
    struct target_siginfo info;
1174
    struct target_ucontext_v1 uc;
1175
    abi_ulong retcode;
1176
};
1177

    
1178
struct rt_sigframe_v2
1179
{
1180
    struct target_siginfo info;
1181
    struct target_ucontext_v2 uc;
1182
    abi_ulong retcode;
1183
};
1184

    
1185
#define TARGET_CONFIG_CPU_32 1
1186

    
1187
/*
1188
 * For ARM syscalls, we encode the syscall number into the instruction.
1189
 */
1190
#define SWI_SYS_SIGRETURN        (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1191
#define SWI_SYS_RT_SIGRETURN        (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1192

    
1193
/*
1194
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
1195
 * need two 16-bit instructions.
1196
 */
1197
#define SWI_THUMB_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1198
#define SWI_THUMB_RT_SIGRETURN        (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1199

    
1200
static const abi_ulong retcodes[4] = {
1201
        SWI_SYS_SIGRETURN,        SWI_THUMB_SIGRETURN,
1202
        SWI_SYS_RT_SIGRETURN,        SWI_THUMB_RT_SIGRETURN
1203
};
1204

    
1205

    
1206
#define __get_user_error(x,p,e) __get_user(x, p)
1207

    
1208
static inline int valid_user_regs(CPUARMState *regs)
1209
{
1210
    return 1;
1211
}
1212

    
1213
static void
1214
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1215
                 CPUARMState *env, abi_ulong mask)
1216
{
1217
        __put_user(env->regs[0], &sc->arm_r0);
1218
        __put_user(env->regs[1], &sc->arm_r1);
1219
        __put_user(env->regs[2], &sc->arm_r2);
1220
        __put_user(env->regs[3], &sc->arm_r3);
1221
        __put_user(env->regs[4], &sc->arm_r4);
1222
        __put_user(env->regs[5], &sc->arm_r5);
1223
        __put_user(env->regs[6], &sc->arm_r6);
1224
        __put_user(env->regs[7], &sc->arm_r7);
1225
        __put_user(env->regs[8], &sc->arm_r8);
1226
        __put_user(env->regs[9], &sc->arm_r9);
1227
        __put_user(env->regs[10], &sc->arm_r10);
1228
        __put_user(env->regs[11], &sc->arm_fp);
1229
        __put_user(env->regs[12], &sc->arm_ip);
1230
        __put_user(env->regs[13], &sc->arm_sp);
1231
        __put_user(env->regs[14], &sc->arm_lr);
1232
        __put_user(env->regs[15], &sc->arm_pc);
1233
#ifdef TARGET_CONFIG_CPU_32
1234
        __put_user(cpsr_read(env), &sc->arm_cpsr);
1235
#endif
1236

    
1237
        __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1238
        __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1239
        __put_user(/* current->thread.address */ 0, &sc->fault_address);
1240
        __put_user(mask, &sc->oldmask);
1241
}
1242

    
1243
static inline abi_ulong
1244
get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1245
{
1246
        unsigned long sp = regs->regs[13];
1247

    
1248
        /*
1249
         * This is the X/Open sanctioned signal stack switching.
1250
         */
1251
        if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1252
            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1253
        /*
1254
         * ATPCS B01 mandates 8-byte alignment
1255
         */
1256
        return (sp - framesize) & ~7;
1257
}
1258

    
1259
static int
1260
setup_return(CPUARMState *env, struct target_sigaction *ka,
1261
             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1262
{
1263
        abi_ulong handler = ka->_sa_handler;
1264
        abi_ulong retcode;
1265
        int thumb = handler & 1;
1266
        uint32_t cpsr = cpsr_read(env);
1267

    
1268
        cpsr &= ~CPSR_IT;
1269
        if (thumb) {
1270
                cpsr |= CPSR_T;
1271
        } else {
1272
                cpsr &= ~CPSR_T;
1273
        }
1274

    
1275
        if (ka->sa_flags & TARGET_SA_RESTORER) {
1276
                retcode = ka->sa_restorer;
1277
        } else {
1278
                unsigned int idx = thumb;
1279

    
1280
                if (ka->sa_flags & TARGET_SA_SIGINFO)
1281
                        idx += 2;
1282

    
1283
                if (__put_user(retcodes[idx], rc))
1284
                        return 1;
1285

    
1286
                retcode = rc_addr + thumb;
1287
        }
1288

    
1289
        env->regs[0] = usig;
1290
        env->regs[13] = frame_addr;
1291
        env->regs[14] = retcode;
1292
        env->regs[15] = handler & (thumb ? ~1 : ~3);
1293
        cpsr_write(env, cpsr, 0xffffffff);
1294

    
1295
        return 0;
1296
}
1297

    
1298
static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1299
{
1300
    int i;
1301
    struct target_vfp_sigframe *vfpframe;
1302
    vfpframe = (struct target_vfp_sigframe *)regspace;
1303
    __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1304
    __put_user(sizeof(*vfpframe), &vfpframe->size);
1305
    for (i = 0; i < 32; i++) {
1306
        __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1307
    }
1308
    __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1309
    __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1310
    __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1311
    __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1312
    return (abi_ulong*)(vfpframe+1);
1313
}
1314

    
1315
static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1316
                                           CPUARMState *env)
1317
{
1318
    int i;
1319
    struct target_iwmmxt_sigframe *iwmmxtframe;
1320
    iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1321
    __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1322
    __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1323
    for (i = 0; i < 16; i++) {
1324
        __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1325
    }
1326
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1327
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1328
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1329
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1330
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1331
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1332
    return (abi_ulong*)(iwmmxtframe+1);
1333
}
1334

    
1335
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1336
                              target_sigset_t *set, CPUARMState *env)
1337
{
1338
    struct target_sigaltstack stack;
1339
    int i;
1340
    abi_ulong *regspace;
1341

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

    
1345
    memset(&stack, 0, sizeof(stack));
1346
    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1347
    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1348
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1349
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1350

    
1351
    setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1352
    /* Save coprocessor signal frame.  */
1353
    regspace = uc->tuc_regspace;
1354
    if (arm_feature(env, ARM_FEATURE_VFP)) {
1355
        regspace = setup_sigframe_v2_vfp(regspace, env);
1356
    }
1357
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1358
        regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1359
    }
1360

    
1361
    /* Write terminating magic word */
1362
    __put_user(0, regspace);
1363

    
1364
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1365
        __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1366
    }
1367
}
1368

    
1369
/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1370
static void setup_frame_v1(int usig, struct target_sigaction *ka,
1371
                           target_sigset_t *set, CPUARMState *regs)
1372
{
1373
        struct sigframe_v1 *frame;
1374
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1375
        int i;
1376

    
1377
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1378
                return;
1379

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

    
1382
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1383
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1384
                goto end;
1385
        }
1386

    
1387
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1388
                     frame_addr + offsetof(struct sigframe_v1, retcode));
1389

    
1390
end:
1391
        unlock_user_struct(frame, frame_addr, 1);
1392
}
1393

    
1394
static void setup_frame_v2(int usig, struct target_sigaction *ka,
1395
                           target_sigset_t *set, CPUARMState *regs)
1396
{
1397
        struct sigframe_v2 *frame;
1398
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1399

    
1400
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1401
                return;
1402

    
1403
        setup_sigframe_v2(&frame->uc, set, regs);
1404

    
1405
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1406
                     frame_addr + offsetof(struct sigframe_v2, retcode));
1407

    
1408
        unlock_user_struct(frame, frame_addr, 1);
1409
}
1410

    
1411
static void setup_frame(int usig, struct target_sigaction *ka,
1412
                        target_sigset_t *set, CPUARMState *regs)
1413
{
1414
    if (get_osversion() >= 0x020612) {
1415
        setup_frame_v2(usig, ka, set, regs);
1416
    } else {
1417
        setup_frame_v1(usig, ka, set, regs);
1418
    }
1419
}
1420

    
1421
/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1422
static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1423
                              target_siginfo_t *info,
1424
                              target_sigset_t *set, CPUARMState *env)
1425
{
1426
        struct rt_sigframe_v1 *frame;
1427
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1428
        struct target_sigaltstack stack;
1429
        int i;
1430
        abi_ulong info_addr, uc_addr;
1431

    
1432
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1433
            return /* 1 */;
1434

    
1435
        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1436
        __put_user(info_addr, &frame->pinfo);
1437
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1438
        __put_user(uc_addr, &frame->puc);
1439
        copy_siginfo_to_user(&frame->info, info);
1440

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

    
1444
        memset(&stack, 0, sizeof(stack));
1445
        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1446
        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1447
        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1448
        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1449

    
1450
        setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1451
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1452
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1453
                goto end;
1454
        }
1455

    
1456
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1457
                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1458

    
1459
        env->regs[1] = info_addr;
1460
        env->regs[2] = uc_addr;
1461

    
1462
end:
1463
        unlock_user_struct(frame, frame_addr, 1);
1464
}
1465

    
1466
static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1467
                              target_siginfo_t *info,
1468
                              target_sigset_t *set, CPUARMState *env)
1469
{
1470
        struct rt_sigframe_v2 *frame;
1471
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1472
        abi_ulong info_addr, uc_addr;
1473

    
1474
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1475
            return /* 1 */;
1476

    
1477
        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1478
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1479
        copy_siginfo_to_user(&frame->info, info);
1480

    
1481
        setup_sigframe_v2(&frame->uc, set, env);
1482

    
1483
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
1484
                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1485

    
1486
        env->regs[1] = info_addr;
1487
        env->regs[2] = uc_addr;
1488

    
1489
        unlock_user_struct(frame, frame_addr, 1);
1490
}
1491

    
1492
static void setup_rt_frame(int usig, struct target_sigaction *ka,
1493
                           target_siginfo_t *info,
1494
                           target_sigset_t *set, CPUARMState *env)
1495
{
1496
    if (get_osversion() >= 0x020612) {
1497
        setup_rt_frame_v2(usig, ka, info, set, env);
1498
    } else {
1499
        setup_rt_frame_v1(usig, ka, info, set, env);
1500
    }
1501
}
1502

    
1503
static int
1504
restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1505
{
1506
        int err = 0;
1507
        uint32_t cpsr;
1508

    
1509
        __get_user_error(env->regs[0], &sc->arm_r0, err);
1510
        __get_user_error(env->regs[1], &sc->arm_r1, err);
1511
        __get_user_error(env->regs[2], &sc->arm_r2, err);
1512
        __get_user_error(env->regs[3], &sc->arm_r3, err);
1513
        __get_user_error(env->regs[4], &sc->arm_r4, err);
1514
        __get_user_error(env->regs[5], &sc->arm_r5, err);
1515
        __get_user_error(env->regs[6], &sc->arm_r6, err);
1516
        __get_user_error(env->regs[7], &sc->arm_r7, err);
1517
        __get_user_error(env->regs[8], &sc->arm_r8, err);
1518
        __get_user_error(env->regs[9], &sc->arm_r9, err);
1519
        __get_user_error(env->regs[10], &sc->arm_r10, err);
1520
        __get_user_error(env->regs[11], &sc->arm_fp, err);
1521
        __get_user_error(env->regs[12], &sc->arm_ip, err);
1522
        __get_user_error(env->regs[13], &sc->arm_sp, err);
1523
        __get_user_error(env->regs[14], &sc->arm_lr, err);
1524
        __get_user_error(env->regs[15], &sc->arm_pc, err);
1525
#ifdef TARGET_CONFIG_CPU_32
1526
        __get_user_error(cpsr, &sc->arm_cpsr, err);
1527
        cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1528
#endif
1529

    
1530
        err |= !valid_user_regs(env);
1531

    
1532
        return err;
1533
}
1534

    
1535
static long do_sigreturn_v1(CPUARMState *env)
1536
{
1537
        abi_ulong frame_addr;
1538
        struct sigframe_v1 *frame;
1539
        target_sigset_t set;
1540
        sigset_t host_set;
1541
        int i;
1542

    
1543
        /*
1544
         * Since we stacked the signal on a 64-bit boundary,
1545
         * then 'sp' should be word aligned here.  If it's
1546
         * not, then the user is trying to mess with us.
1547
         */
1548
        if (env->regs[13] & 7)
1549
                goto badframe;
1550

    
1551
        frame_addr = env->regs[13];
1552
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1553
                goto badframe;
1554

    
1555
        if (__get_user(set.sig[0], &frame->sc.oldmask))
1556
            goto badframe;
1557
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1558
            if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1559
                goto badframe;
1560
        }
1561

    
1562
        target_to_host_sigset_internal(&host_set, &set);
1563
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1564

    
1565
        if (restore_sigcontext(env, &frame->sc))
1566
                goto badframe;
1567

    
1568
#if 0
1569
        /* Send SIGTRAP if we're single-stepping */
1570
        if (ptrace_cancel_bpt(current))
1571
                send_sig(SIGTRAP, current, 1);
1572
#endif
1573
        unlock_user_struct(frame, frame_addr, 0);
1574
        return env->regs[0];
1575

    
1576
badframe:
1577
        unlock_user_struct(frame, frame_addr, 0);
1578
        force_sig(TARGET_SIGSEGV /* , current */);
1579
        return 0;
1580
}
1581

    
1582
static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1583
{
1584
    int i;
1585
    abi_ulong magic, sz;
1586
    uint32_t fpscr, fpexc;
1587
    struct target_vfp_sigframe *vfpframe;
1588
    vfpframe = (struct target_vfp_sigframe *)regspace;
1589

    
1590
    __get_user(magic, &vfpframe->magic);
1591
    __get_user(sz, &vfpframe->size);
1592
    if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1593
        return 0;
1594
    }
1595
    for (i = 0; i < 32; i++) {
1596
        __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1597
    }
1598
    __get_user(fpscr, &vfpframe->ufp.fpscr);
1599
    vfp_set_fpscr(env, fpscr);
1600
    __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1601
    /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1602
     * and the exception flag is cleared
1603
     */
1604
    fpexc |= (1 << 30);
1605
    fpexc &= ~((1 << 31) | (1 << 28));
1606
    env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1607
    __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1608
    __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1609
    return (abi_ulong*)(vfpframe + 1);
1610
}
1611

    
1612
static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1613
                                             abi_ulong *regspace)
1614
{
1615
    int i;
1616
    abi_ulong magic, sz;
1617
    struct target_iwmmxt_sigframe *iwmmxtframe;
1618
    iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1619

    
1620
    __get_user(magic, &iwmmxtframe->magic);
1621
    __get_user(sz, &iwmmxtframe->size);
1622
    if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1623
        return 0;
1624
    }
1625
    for (i = 0; i < 16; i++) {
1626
        __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1627
    }
1628
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1629
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1630
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1631
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1632
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1633
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1634
    return (abi_ulong*)(iwmmxtframe + 1);
1635
}
1636

    
1637
static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1638
                                 struct target_ucontext_v2 *uc)
1639
{
1640
    sigset_t host_set;
1641
    abi_ulong *regspace;
1642

    
1643
    target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1644
    sigprocmask(SIG_SETMASK, &host_set, NULL);
1645

    
1646
    if (restore_sigcontext(env, &uc->tuc_mcontext))
1647
        return 1;
1648

    
1649
    /* Restore coprocessor signal frame */
1650
    regspace = uc->tuc_regspace;
1651
    if (arm_feature(env, ARM_FEATURE_VFP)) {
1652
        regspace = restore_sigframe_v2_vfp(env, regspace);
1653
        if (!regspace) {
1654
            return 1;
1655
        }
1656
    }
1657
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1658
        regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1659
        if (!regspace) {
1660
            return 1;
1661
        }
1662
    }
1663

    
1664
    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1665
        return 1;
1666

    
1667
#if 0
1668
    /* Send SIGTRAP if we're single-stepping */
1669
    if (ptrace_cancel_bpt(current))
1670
            send_sig(SIGTRAP, current, 1);
1671
#endif
1672

    
1673
    return 0;
1674
}
1675

    
1676
static long do_sigreturn_v2(CPUARMState *env)
1677
{
1678
        abi_ulong frame_addr;
1679
        struct sigframe_v2 *frame;
1680

    
1681
        /*
1682
         * Since we stacked the signal on a 64-bit boundary,
1683
         * then 'sp' should be word aligned here.  If it's
1684
         * not, then the user is trying to mess with us.
1685
         */
1686
        if (env->regs[13] & 7)
1687
                goto badframe;
1688

    
1689
        frame_addr = env->regs[13];
1690
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1691
                goto badframe;
1692

    
1693
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1694
                goto badframe;
1695

    
1696
        unlock_user_struct(frame, frame_addr, 0);
1697
        return env->regs[0];
1698

    
1699
badframe:
1700
        unlock_user_struct(frame, frame_addr, 0);
1701
        force_sig(TARGET_SIGSEGV /* , current */);
1702
        return 0;
1703
}
1704

    
1705
long do_sigreturn(CPUARMState *env)
1706
{
1707
    if (get_osversion() >= 0x020612) {
1708
        return do_sigreturn_v2(env);
1709
    } else {
1710
        return do_sigreturn_v1(env);
1711
    }
1712
}
1713

    
1714
static long do_rt_sigreturn_v1(CPUARMState *env)
1715
{
1716
        abi_ulong frame_addr;
1717
        struct rt_sigframe_v1 *frame;
1718
        sigset_t host_set;
1719

    
1720
        /*
1721
         * Since we stacked the signal on a 64-bit boundary,
1722
         * then 'sp' should be word aligned here.  If it's
1723
         * not, then the user is trying to mess with us.
1724
         */
1725
        if (env->regs[13] & 7)
1726
                goto badframe;
1727

    
1728
        frame_addr = env->regs[13];
1729
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1730
                goto badframe;
1731

    
1732
        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1733
        sigprocmask(SIG_SETMASK, &host_set, NULL);
1734

    
1735
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1736
                goto badframe;
1737

    
1738
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1739
                goto badframe;
1740

    
1741
#if 0
1742
        /* Send SIGTRAP if we're single-stepping */
1743
        if (ptrace_cancel_bpt(current))
1744
                send_sig(SIGTRAP, current, 1);
1745
#endif
1746
        unlock_user_struct(frame, frame_addr, 0);
1747
        return env->regs[0];
1748

    
1749
badframe:
1750
        unlock_user_struct(frame, frame_addr, 0);
1751
        force_sig(TARGET_SIGSEGV /* , current */);
1752
        return 0;
1753
}
1754

    
1755
static long do_rt_sigreturn_v2(CPUARMState *env)
1756
{
1757
        abi_ulong frame_addr;
1758
        struct rt_sigframe_v2 *frame;
1759

    
1760
        /*
1761
         * Since we stacked the signal on a 64-bit boundary,
1762
         * then 'sp' should be word aligned here.  If it's
1763
         * not, then the user is trying to mess with us.
1764
         */
1765
        if (env->regs[13] & 7)
1766
                goto badframe;
1767

    
1768
        frame_addr = env->regs[13];
1769
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1770
                goto badframe;
1771

    
1772
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1773
                goto badframe;
1774

    
1775
        unlock_user_struct(frame, frame_addr, 0);
1776
        return env->regs[0];
1777

    
1778
badframe:
1779
        unlock_user_struct(frame, frame_addr, 0);
1780
        force_sig(TARGET_SIGSEGV /* , current */);
1781
        return 0;
1782
}
1783

    
1784
long do_rt_sigreturn(CPUARMState *env)
1785
{
1786
    if (get_osversion() >= 0x020612) {
1787
        return do_rt_sigreturn_v2(env);
1788
    } else {
1789
        return do_rt_sigreturn_v1(env);
1790
    }
1791
}
1792

    
1793
#elif defined(TARGET_SPARC)
1794

    
1795
#define __SUNOS_MAXWIN   31
1796

    
1797
/* This is what SunOS does, so shall I. */
1798
struct target_sigcontext {
1799
        abi_ulong sigc_onstack;      /* state to restore */
1800

    
1801
        abi_ulong sigc_mask;         /* sigmask to restore */
1802
        abi_ulong sigc_sp;           /* stack pointer */
1803
        abi_ulong sigc_pc;           /* program counter */
1804
        abi_ulong sigc_npc;          /* next program counter */
1805
        abi_ulong sigc_psr;          /* for condition codes etc */
1806
        abi_ulong sigc_g1;           /* User uses these two registers */
1807
        abi_ulong sigc_o0;           /* within the trampoline code. */
1808

    
1809
        /* Now comes information regarding the users window set
1810
         * at the time of the signal.
1811
         */
1812
        abi_ulong sigc_oswins;       /* outstanding windows */
1813

    
1814
        /* stack ptrs for each regwin buf */
1815
        char *sigc_spbuf[__SUNOS_MAXWIN];
1816

    
1817
        /* Windows to restore after signal */
1818
        struct {
1819
                abi_ulong locals[8];
1820
                abi_ulong ins[8];
1821
        } sigc_wbuf[__SUNOS_MAXWIN];
1822
};
1823
/* A Sparc stack frame */
1824
struct sparc_stackf {
1825
        abi_ulong locals[8];
1826
        abi_ulong ins[8];
1827
        /* It's simpler to treat fp and callers_pc as elements of ins[]
1828
         * since we never need to access them ourselves.
1829
         */
1830
        char *structptr;
1831
        abi_ulong xargs[6];
1832
        abi_ulong xxargs[1];
1833
};
1834

    
1835
typedef struct {
1836
        struct {
1837
                abi_ulong psr;
1838
                abi_ulong pc;
1839
                abi_ulong npc;
1840
                abi_ulong y;
1841
                abi_ulong u_regs[16]; /* globals and ins */
1842
        }               si_regs;
1843
        int             si_mask;
1844
} __siginfo_t;
1845

    
1846
typedef struct {
1847
        unsigned   long si_float_regs [32];
1848
        unsigned   long si_fsr;
1849
        unsigned   long si_fpqdepth;
1850
        struct {
1851
                unsigned long *insn_addr;
1852
                unsigned long insn;
1853
        } si_fpqueue [16];
1854
} qemu_siginfo_fpu_t;
1855

    
1856

    
1857
struct target_signal_frame {
1858
        struct sparc_stackf        ss;
1859
        __siginfo_t                info;
1860
        abi_ulong               fpu_save;
1861
        abi_ulong                insns[2] __attribute__ ((aligned (8)));
1862
        abi_ulong                extramask[TARGET_NSIG_WORDS - 1];
1863
        abi_ulong                extra_size; /* Should be 0 */
1864
        qemu_siginfo_fpu_t        fpu_state;
1865
};
1866
struct target_rt_signal_frame {
1867
        struct sparc_stackf        ss;
1868
        siginfo_t                info;
1869
        abi_ulong                regs[20];
1870
        sigset_t                mask;
1871
        abi_ulong               fpu_save;
1872
        unsigned int                insns[2];
1873
        stack_t                        stack;
1874
        unsigned int                extra_size; /* Should be 0 */
1875
        qemu_siginfo_fpu_t        fpu_state;
1876
};
1877

    
1878
#define UREG_O0        16
1879
#define UREG_O6        22
1880
#define UREG_I0        0
1881
#define UREG_I1        1
1882
#define UREG_I2        2
1883
#define UREG_I3        3
1884
#define UREG_I4        4
1885
#define UREG_I5        5
1886
#define UREG_I6        6
1887
#define UREG_I7        7
1888
#define UREG_L0               8
1889
#define UREG_FP        UREG_I6
1890
#define UREG_SP        UREG_O6
1891

    
1892
static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
1893
                                     CPUSPARCState *env,
1894
                                     unsigned long framesize)
1895
{
1896
        abi_ulong sp;
1897

    
1898
        sp = env->regwptr[UREG_FP];
1899

    
1900
        /* This is the X/Open sanctioned signal stack switching.  */
1901
        if (sa->sa_flags & TARGET_SA_ONSTACK) {
1902
            if (!on_sig_stack(sp)
1903
                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1904
                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1905
        }
1906
        return sp - framesize;
1907
}
1908

    
1909
static int
1910
setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
1911
{
1912
        int err = 0, i;
1913

    
1914
        err |= __put_user(env->psr, &si->si_regs.psr);
1915
        err |= __put_user(env->pc, &si->si_regs.pc);
1916
        err |= __put_user(env->npc, &si->si_regs.npc);
1917
        err |= __put_user(env->y, &si->si_regs.y);
1918
        for (i=0; i < 8; i++) {
1919
                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1920
        }
1921
        for (i=0; i < 8; i++) {
1922
                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1923
        }
1924
        err |= __put_user(mask, &si->si_mask);
1925
        return err;
1926
}
1927

    
1928
#if 0
1929
static int
1930
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1931
                 CPUSPARCState *env, unsigned long mask)
1932
{
1933
        int err = 0;
1934

1935
        err |= __put_user(mask, &sc->sigc_mask);
1936
        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1937
        err |= __put_user(env->pc, &sc->sigc_pc);
1938
        err |= __put_user(env->npc, &sc->sigc_npc);
1939
        err |= __put_user(env->psr, &sc->sigc_psr);
1940
        err |= __put_user(env->gregs[1], &sc->sigc_g1);
1941
        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1942

1943
        return err;
1944
}
1945
#endif
1946
#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1947

    
1948
static void setup_frame(int sig, struct target_sigaction *ka,
1949
                        target_sigset_t *set, CPUSPARCState *env)
1950
{
1951
        abi_ulong sf_addr;
1952
        struct target_signal_frame *sf;
1953
        int sigframe_size, err, i;
1954

    
1955
        /* 1. Make sure everything is clean */
1956
        //synchronize_user_stack();
1957

    
1958
        sigframe_size = NF_ALIGNEDSZ;
1959
        sf_addr = get_sigframe(ka, env, sigframe_size);
1960

    
1961
        sf = lock_user(VERIFY_WRITE, sf_addr, 
1962
                       sizeof(struct target_signal_frame), 0);
1963
        if (!sf)
1964
                goto sigsegv;
1965
                
1966
        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1967
#if 0
1968
        if (invalid_frame_pointer(sf, sigframe_size))
1969
                goto sigill_and_return;
1970
#endif
1971
        /* 2. Save the current process state */
1972
        err = setup___siginfo(&sf->info, env, set->sig[0]);
1973
        err |= __put_user(0, &sf->extra_size);
1974

    
1975
        //err |= save_fpu_state(regs, &sf->fpu_state);
1976
        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1977

    
1978
        err |= __put_user(set->sig[0], &sf->info.si_mask);
1979
        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1980
                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1981
        }
1982

    
1983
        for (i = 0; i < 8; i++) {
1984
                  err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1985
        }
1986
        for (i = 0; i < 8; i++) {
1987
                  err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1988
        }
1989
        if (err)
1990
                goto sigsegv;
1991

    
1992
        /* 3. signal handler back-trampoline and parameters */
1993
        env->regwptr[UREG_FP] = sf_addr;
1994
        env->regwptr[UREG_I0] = sig;
1995
        env->regwptr[UREG_I1] = sf_addr + 
1996
                offsetof(struct target_signal_frame, info);
1997
        env->regwptr[UREG_I2] = sf_addr + 
1998
                offsetof(struct target_signal_frame, info);
1999

    
2000
        /* 4. signal handler */
2001
        env->pc = ka->_sa_handler;
2002
        env->npc = (env->pc + 4);
2003
        /* 5. return to kernel instructions */
2004
        if (ka->sa_restorer)
2005
                env->regwptr[UREG_I7] = ka->sa_restorer;
2006
        else {
2007
                uint32_t val32;
2008

    
2009
                env->regwptr[UREG_I7] = sf_addr + 
2010
                        offsetof(struct target_signal_frame, insns) - 2 * 4;
2011

    
2012
                /* mov __NR_sigreturn, %g1 */
2013
                val32 = 0x821020d8;
2014
                err |= __put_user(val32, &sf->insns[0]);
2015

    
2016
                /* t 0x10 */
2017
                val32 = 0x91d02010;
2018
                err |= __put_user(val32, &sf->insns[1]);
2019
                if (err)
2020
                        goto sigsegv;
2021

    
2022
                /* Flush instruction space. */
2023
                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2024
                //                tb_flush(env);
2025
        }
2026
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2027
        return;
2028
#if 0
2029
sigill_and_return:
2030
        force_sig(TARGET_SIGILL);
2031
#endif
2032
sigsegv:
2033
        //fprintf(stderr, "force_sig\n");
2034
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2035
        force_sig(TARGET_SIGSEGV);
2036
}
2037
static inline int
2038
restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2039
{
2040
        int err;
2041
#if 0
2042
#ifdef CONFIG_SMP
2043
        if (current->flags & PF_USEDFPU)
2044
                regs->psr &= ~PSR_EF;
2045
#else
2046
        if (current == last_task_used_math) {
2047
                last_task_used_math = 0;
2048
                regs->psr &= ~PSR_EF;
2049
        }
2050
#endif
2051
        current->used_math = 1;
2052
        current->flags &= ~PF_USEDFPU;
2053
#endif
2054
#if 0
2055
        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2056
                return -EFAULT;
2057
#endif
2058

    
2059
#if 0
2060
        /* XXX: incorrect */
2061
        err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
2062
                                     (sizeof(unsigned long) * 32));
2063
#endif
2064
        err |= __get_user(env->fsr, &fpu->si_fsr);
2065
#if 0
2066
        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2067
        if (current->thread.fpqdepth != 0)
2068
                err |= __copy_from_user(&current->thread.fpqueue[0],
2069
                                        &fpu->si_fpqueue[0],
2070
                                        ((sizeof(unsigned long) +
2071
                                        (sizeof(unsigned long *)))*16));
2072
#endif
2073
        return err;
2074
}
2075

    
2076

    
2077
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2078
                           target_siginfo_t *info,
2079
                           target_sigset_t *set, CPUSPARCState *env)
2080
{
2081
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2082
}
2083

    
2084
long do_sigreturn(CPUSPARCState *env)
2085
{
2086
        abi_ulong sf_addr;
2087
        struct target_signal_frame *sf;
2088
        uint32_t up_psr, pc, npc;
2089
        target_sigset_t set;
2090
        sigset_t host_set;
2091
        int err, i;
2092

    
2093
        sf_addr = env->regwptr[UREG_FP];
2094
        if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2095
                goto segv_and_exit;
2096
#if 0
2097
        fprintf(stderr, "sigreturn\n");
2098
        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2099
#endif
2100
        //cpu_dump_state(env, stderr, fprintf, 0);
2101

    
2102
        /* 1. Make sure we are not getting garbage from the user */
2103

    
2104
        if (sf_addr & 3)
2105
                goto segv_and_exit;
2106

    
2107
        err = __get_user(pc,  &sf->info.si_regs.pc);
2108
        err |= __get_user(npc, &sf->info.si_regs.npc);
2109

    
2110
        if ((pc | npc) & 3)
2111
                goto segv_and_exit;
2112

    
2113
        /* 2. Restore the state */
2114
        err |= __get_user(up_psr, &sf->info.si_regs.psr);
2115

    
2116
        /* User can only change condition codes and FPU enabling in %psr. */
2117
        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2118
                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2119

    
2120
        env->pc = pc;
2121
        env->npc = npc;
2122
        err |= __get_user(env->y, &sf->info.si_regs.y);
2123
        for (i=0; i < 8; i++) {
2124
                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2125
        }
2126
        for (i=0; i < 8; i++) {
2127
                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2128
        }
2129

    
2130
        /* FIXME: implement FPU save/restore:
2131
         * __get_user(fpu_save, &sf->fpu_save);
2132
         * if (fpu_save)
2133
         *        err |= restore_fpu_state(env, fpu_save);
2134
         */
2135

    
2136
        /* This is pretty much atomic, no amount locking would prevent
2137
         * the races which exist anyways.
2138
         */
2139
        err |= __get_user(set.sig[0], &sf->info.si_mask);
2140
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2141
            err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2142
        }
2143

    
2144
        target_to_host_sigset_internal(&host_set, &set);
2145
        sigprocmask(SIG_SETMASK, &host_set, NULL);
2146

    
2147
        if (err)
2148
                goto segv_and_exit;
2149
        unlock_user_struct(sf, sf_addr, 0);
2150
        return env->regwptr[0];
2151

    
2152
segv_and_exit:
2153
        unlock_user_struct(sf, sf_addr, 0);
2154
        force_sig(TARGET_SIGSEGV);
2155
}
2156

    
2157
long do_rt_sigreturn(CPUSPARCState *env)
2158
{
2159
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2160
    return -TARGET_ENOSYS;
2161
}
2162

    
2163
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2164
#define MC_TSTATE 0
2165
#define MC_PC 1
2166
#define MC_NPC 2
2167
#define MC_Y 3
2168
#define MC_G1 4
2169
#define MC_G2 5
2170
#define MC_G3 6
2171
#define MC_G4 7
2172
#define MC_G5 8
2173
#define MC_G6 9
2174
#define MC_G7 10
2175
#define MC_O0 11
2176
#define MC_O1 12
2177
#define MC_O2 13
2178
#define MC_O3 14
2179
#define MC_O4 15
2180
#define MC_O5 16
2181
#define MC_O6 17
2182
#define MC_O7 18
2183
#define MC_NGREG 19
2184

    
2185
typedef abi_ulong target_mc_greg_t;
2186
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2187

    
2188
struct target_mc_fq {
2189
    abi_ulong *mcfq_addr;
2190
    uint32_t mcfq_insn;
2191
};
2192

    
2193
struct target_mc_fpu {
2194
    union {
2195
        uint32_t sregs[32];
2196
        uint64_t dregs[32];
2197
        //uint128_t qregs[16];
2198
    } mcfpu_fregs;
2199
    abi_ulong mcfpu_fsr;
2200
    abi_ulong mcfpu_fprs;
2201
    abi_ulong mcfpu_gsr;
2202
    struct target_mc_fq *mcfpu_fq;
2203
    unsigned char mcfpu_qcnt;
2204
    unsigned char mcfpu_qentsz;
2205
    unsigned char mcfpu_enab;
2206
};
2207
typedef struct target_mc_fpu target_mc_fpu_t;
2208

    
2209
typedef struct {
2210
    target_mc_gregset_t mc_gregs;
2211
    target_mc_greg_t mc_fp;
2212
    target_mc_greg_t mc_i7;
2213
    target_mc_fpu_t mc_fpregs;
2214
} target_mcontext_t;
2215

    
2216
struct target_ucontext {
2217
    struct target_ucontext *tuc_link;
2218
    abi_ulong tuc_flags;
2219
    target_sigset_t tuc_sigmask;
2220
    target_mcontext_t tuc_mcontext;
2221
};
2222

    
2223
/* A V9 register window */
2224
struct target_reg_window {
2225
    abi_ulong locals[8];
2226
    abi_ulong ins[8];
2227
};
2228

    
2229
#define TARGET_STACK_BIAS 2047
2230

    
2231
/* {set, get}context() needed for 64-bit SparcLinux userland. */
2232
void sparc64_set_context(CPUSPARCState *env)
2233
{
2234
    abi_ulong ucp_addr;
2235
    struct target_ucontext *ucp;
2236
    target_mc_gregset_t *grp;
2237
    abi_ulong pc, npc, tstate;
2238
    abi_ulong fp, i7, w_addr;
2239
    int err;
2240
    unsigned int i;
2241

    
2242
    ucp_addr = env->regwptr[UREG_I0];
2243
    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2244
        goto do_sigsegv;
2245
    grp  = &ucp->tuc_mcontext.mc_gregs;
2246
    err  = __get_user(pc, &((*grp)[MC_PC]));
2247
    err |= __get_user(npc, &((*grp)[MC_NPC]));
2248
    if (err || ((pc | npc) & 3))
2249
        goto do_sigsegv;
2250
    if (env->regwptr[UREG_I1]) {
2251
        target_sigset_t target_set;
2252
        sigset_t set;
2253

    
2254
        if (TARGET_NSIG_WORDS == 1) {
2255
            if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2256
                goto do_sigsegv;
2257
        } else {
2258
            abi_ulong *src, *dst;
2259
            src = ucp->tuc_sigmask.sig;
2260
            dst = target_set.sig;
2261
            for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2262
                 i++, dst++, src++)
2263
                err |= __get_user(*dst, src);
2264
            if (err)
2265
                goto do_sigsegv;
2266
        }
2267
        target_to_host_sigset_internal(&set, &target_set);
2268
        sigprocmask(SIG_SETMASK, &set, NULL);
2269
    }
2270
    env->pc = pc;
2271
    env->npc = npc;
2272
    err |= __get_user(env->y, &((*grp)[MC_Y]));
2273
    err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2274
    env->asi = (tstate >> 24) & 0xff;
2275
    cpu_put_ccr(env, tstate >> 32);
2276
    cpu_put_cwp64(env, tstate & 0x1f);
2277
    err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2278
    err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2279
    err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2280
    err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2281
    err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2282
    err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2283
    err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2284
    err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2285
    err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2286
    err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2287
    err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2288
    err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2289
    err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2290
    err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2291
    err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2292

    
2293
    err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2294
    err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2295

    
2296
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2297
    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2298
                 abi_ulong) != 0)
2299
        goto do_sigsegv;
2300
    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2301
                 abi_ulong) != 0)
2302
        goto do_sigsegv;
2303
    /* FIXME this does not match how the kernel handles the FPU in
2304
     * its sparc64_set_context implementation. In particular the FPU
2305
     * is only restored if fenab is non-zero in:
2306
     *   __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2307
     */
2308
    err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2309
    {
2310
        uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2311
        for (i = 0; i < 64; i++, src++) {
2312
            if (i & 1) {
2313
                err |= __get_user(env->fpr[i/2].l.lower, src);
2314
            } else {
2315
                err |= __get_user(env->fpr[i/2].l.upper, src);
2316
            }
2317
        }
2318
    }
2319
    err |= __get_user(env->fsr,
2320
                      &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2321
    err |= __get_user(env->gsr,
2322
                      &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2323
    if (err)
2324
        goto do_sigsegv;
2325
    unlock_user_struct(ucp, ucp_addr, 0);
2326
    return;
2327
 do_sigsegv:
2328
    unlock_user_struct(ucp, ucp_addr, 0);
2329
    force_sig(TARGET_SIGSEGV);
2330
}
2331

    
2332
void sparc64_get_context(CPUSPARCState *env)
2333
{
2334
    abi_ulong ucp_addr;
2335
    struct target_ucontext *ucp;
2336
    target_mc_gregset_t *grp;
2337
    target_mcontext_t *mcp;
2338
    abi_ulong fp, i7, w_addr;
2339
    int err;
2340
    unsigned int i;
2341
    target_sigset_t target_set;
2342
    sigset_t set;
2343

    
2344
    ucp_addr = env->regwptr[UREG_I0];
2345
    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2346
        goto do_sigsegv;
2347
    
2348
    mcp = &ucp->tuc_mcontext;
2349
    grp = &mcp->mc_gregs;
2350

    
2351
    /* Skip over the trap instruction, first. */
2352
    env->pc = env->npc;
2353
    env->npc += 4;
2354

    
2355
    err = 0;
2356

    
2357
    sigprocmask(0, NULL, &set);
2358
    host_to_target_sigset_internal(&target_set, &set);
2359
    if (TARGET_NSIG_WORDS == 1) {
2360
        err |= __put_user(target_set.sig[0],
2361
                          (abi_ulong *)&ucp->tuc_sigmask);
2362
    } else {
2363
        abi_ulong *src, *dst;
2364
        src = target_set.sig;
2365
        dst = ucp->tuc_sigmask.sig;
2366
        for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2367
             i++, dst++, src++)
2368
            err |= __put_user(*src, dst);
2369
        if (err)
2370
            goto do_sigsegv;
2371
    }
2372

    
2373
    /* XXX: tstate must be saved properly */
2374
    //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2375
    err |= __put_user(env->pc, &((*grp)[MC_PC]));
2376
    err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2377
    err |= __put_user(env->y, &((*grp)[MC_Y]));
2378
    err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2379
    err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2380
    err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2381
    err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2382
    err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2383
    err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2384
    err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2385
    err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2386
    err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2387
    err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2388
    err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2389
    err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2390
    err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2391
    err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2392
    err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2393

    
2394
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2395
    fp = i7 = 0;
2396
    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2397
                 abi_ulong) != 0)
2398
        goto do_sigsegv;
2399
    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2400
                 abi_ulong) != 0)
2401
        goto do_sigsegv;
2402
    err |= __put_user(fp, &(mcp->mc_fp));
2403
    err |= __put_user(i7, &(mcp->mc_i7));
2404

    
2405
    {
2406
        uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2407
        for (i = 0; i < 64; i++, dst++) {
2408
            if (i & 1) {
2409
                err |= __put_user(env->fpr[i/2].l.lower, dst);
2410
            } else {
2411
                err |= __put_user(env->fpr[i/2].l.upper, dst);
2412
            }
2413
        }
2414
    }
2415
    err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2416
    err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2417
    err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2418

    
2419
    if (err)
2420
        goto do_sigsegv;
2421
    unlock_user_struct(ucp, ucp_addr, 1);
2422
    return;
2423
 do_sigsegv:
2424
    unlock_user_struct(ucp, ucp_addr, 1);
2425
    force_sig(TARGET_SIGSEGV);
2426
}
2427
#endif
2428
#elif defined(TARGET_ABI_MIPSN64)
2429

    
2430
# warning signal handling not implemented
2431

    
2432
static void setup_frame(int sig, struct target_sigaction *ka,
2433
                        target_sigset_t *set, CPUMIPSState *env)
2434
{
2435
    fprintf(stderr, "setup_frame: not implemented\n");
2436
}
2437

    
2438
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2439
                           target_siginfo_t *info,
2440
                           target_sigset_t *set, CPUMIPSState *env)
2441
{
2442
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2443
}
2444

    
2445
long do_sigreturn(CPUMIPSState *env)
2446
{
2447
    fprintf(stderr, "do_sigreturn: not implemented\n");
2448
    return -TARGET_ENOSYS;
2449
}
2450

    
2451
long do_rt_sigreturn(CPUMIPSState *env)
2452
{
2453
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2454
    return -TARGET_ENOSYS;
2455
}
2456

    
2457
#elif defined(TARGET_ABI_MIPSN32)
2458

    
2459
# warning signal handling not implemented
2460

    
2461
static void setup_frame(int sig, struct target_sigaction *ka,
2462
                        target_sigset_t *set, CPUMIPSState *env)
2463
{
2464
    fprintf(stderr, "setup_frame: not implemented\n");
2465
}
2466

    
2467
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2468
                           target_siginfo_t *info,
2469
                           target_sigset_t *set, CPUMIPSState *env)
2470
{
2471
    fprintf(stderr, "setup_rt_frame: not implemented\n");
2472
}
2473

    
2474
long do_sigreturn(CPUMIPSState *env)
2475
{
2476
    fprintf(stderr, "do_sigreturn: not implemented\n");
2477
    return -TARGET_ENOSYS;
2478
}
2479

    
2480
long do_rt_sigreturn(CPUMIPSState *env)
2481
{
2482
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2483
    return -TARGET_ENOSYS;
2484
}
2485

    
2486
#elif defined(TARGET_ABI_MIPSO32)
2487

    
2488
struct target_sigcontext {
2489
    uint32_t   sc_regmask;     /* Unused */
2490
    uint32_t   sc_status;
2491
    uint64_t   sc_pc;
2492
    uint64_t   sc_regs[32];
2493
    uint64_t   sc_fpregs[32];
2494
    uint32_t   sc_ownedfp;     /* Unused */
2495
    uint32_t   sc_fpc_csr;
2496
    uint32_t   sc_fpc_eir;     /* Unused */
2497
    uint32_t   sc_used_math;
2498
    uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
2499
    uint32_t   pad0;
2500
    uint64_t   sc_mdhi;
2501
    uint64_t   sc_mdlo;
2502
    target_ulong   sc_hi1;         /* Was sc_cause */
2503
    target_ulong   sc_lo1;         /* Was sc_badvaddr */
2504
    target_ulong   sc_hi2;         /* Was sc_sigset[4] */
2505
    target_ulong   sc_lo2;
2506
    target_ulong   sc_hi3;
2507
    target_ulong   sc_lo3;
2508
};
2509

    
2510
struct sigframe {
2511
    uint32_t sf_ass[4];                        /* argument save space for o32 */
2512
    uint32_t sf_code[2];                        /* signal trampoline */
2513
    struct target_sigcontext sf_sc;
2514
    target_sigset_t sf_mask;
2515
};
2516

    
2517
struct target_ucontext {
2518
    target_ulong tuc_flags;
2519
    target_ulong tuc_link;
2520
    target_stack_t tuc_stack;
2521
    target_ulong pad0;
2522
    struct target_sigcontext tuc_mcontext;
2523
    target_sigset_t tuc_sigmask;
2524
};
2525

    
2526
struct target_rt_sigframe {
2527
    uint32_t rs_ass[4];               /* argument save space for o32 */
2528
    uint32_t rs_code[2];              /* signal trampoline */
2529
    struct target_siginfo rs_info;
2530
    struct target_ucontext rs_uc;
2531
};
2532

    
2533
/* Install trampoline to jump back from signal handler */
2534
static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2535
{
2536
    int err;
2537

    
2538
    /*
2539
    * Set up the return code ...
2540
    *
2541
    *         li      v0, __NR__foo_sigreturn
2542
    *         syscall
2543
    */
2544

    
2545
    err = __put_user(0x24020000 + syscall, tramp + 0);
2546
    err |= __put_user(0x0000000c          , tramp + 1);
2547
    /* flush_cache_sigtramp((unsigned long) tramp); */
2548
    return err;
2549
}
2550

    
2551
static inline int
2552
setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2553
{
2554
    int err = 0;
2555

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

    
2558
#define save_gp_reg(i) do {                                                   \
2559
        err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);        \
2560
    } while(0)
2561
    __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2562
    save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2563
    save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2564
    save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2565
    save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2566
    save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2567
    save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2568
    save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2569
    save_gp_reg(31);
2570
#undef save_gp_reg
2571

    
2572
    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2573
    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2574

    
2575
    /* Not used yet, but might be useful if we ever have DSP suppport */
2576
#if 0
2577
    if (cpu_has_dsp) {
2578
        err |= __put_user(mfhi1(), &sc->sc_hi1);
2579
        err |= __put_user(mflo1(), &sc->sc_lo1);
2580
        err |= __put_user(mfhi2(), &sc->sc_hi2);
2581
        err |= __put_user(mflo2(), &sc->sc_lo2);
2582
        err |= __put_user(mfhi3(), &sc->sc_hi3);
2583
        err |= __put_user(mflo3(), &sc->sc_lo3);
2584
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2585
    }
2586
    /* same with 64 bit */
2587
#ifdef CONFIG_64BIT
2588
    err |= __put_user(regs->hi, &sc->sc_hi[0]);
2589
    err |= __put_user(regs->lo, &sc->sc_lo[0]);
2590
    if (cpu_has_dsp) {
2591
        err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2592
        err |= __put_user(mflo1(), &sc->sc_lo[1]);
2593
        err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2594
        err |= __put_user(mflo2(), &sc->sc_lo[2]);
2595
        err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2596
        err |= __put_user(mflo3(), &sc->sc_lo[3]);
2597
        err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2598
    }
2599
#endif
2600
#endif
2601

    
2602
#if 0
2603
    err |= __put_user(!!used_math(), &sc->sc_used_math);
2604

2605
    if (!used_math())
2606
        goto out;
2607

2608
    /*
2609
    * Save FPU state to signal context.  Signal handler will "inherit"
2610
    * current FPU state.
2611
    */
2612
    preempt_disable();
2613

2614
    if (!is_fpu_owner()) {
2615
        own_fpu();
2616
        restore_fp(current);
2617
    }
2618
    err |= save_fp_context(sc);
2619

2620
    preempt_enable();
2621
    out:
2622
#endif
2623
    return err;
2624
}
2625

    
2626
static inline int
2627
restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2628
{
2629
    int err = 0;
2630

    
2631
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2632

    
2633
    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2634
    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2635

    
2636
#define restore_gp_reg(i) do {                                                           \
2637
        err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);                \
2638
    } while(0)
2639
    restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2640
    restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2641
    restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2642
    restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2643
    restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2644
    restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2645
    restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2646
    restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2647
    restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2648
    restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2649
    restore_gp_reg(31);
2650
#undef restore_gp_reg
2651

    
2652
#if 0
2653
    if (cpu_has_dsp) {
2654
        err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2655
        err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2656
        err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2657
        err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2658
        err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2659
        err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2660
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2661
    }
2662
#ifdef CONFIG_64BIT
2663
    err |= __get_user(regs->hi, &sc->sc_hi[0]);
2664
    err |= __get_user(regs->lo, &sc->sc_lo[0]);
2665
    if (cpu_has_dsp) {
2666
        err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2667
        err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2668
        err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2669
        err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2670
        err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2671
        err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2672
        err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2673
    }
2674
#endif
2675

    
2676
    err |= __get_user(used_math, &sc->sc_used_math);
2677
    conditional_used_math(used_math);
2678

    
2679
    preempt_disable();
2680

    
2681
    if (used_math()) {
2682
        /* restore fpu context if we have used it before */
2683
        own_fpu();
2684
        err |= restore_fp_context(sc);
2685
    } else {
2686
        /* signal handler may have used FPU.  Give it up. */
2687
        lose_fpu();
2688
    }
2689

    
2690
    preempt_enable();
2691
#endif
2692
    return err;
2693
}
2694
/*
2695
 * Determine which stack to use..
2696
 */
2697
static inline abi_ulong
2698
get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2699
{
2700
    unsigned long sp;
2701

    
2702
    /* Default to using normal stack */
2703
    sp = regs->active_tc.gpr[29];
2704

    
2705
    /*
2706
     * FPU emulator may have its own trampoline active just
2707
     * above the user stack, 16-bytes before the next lowest
2708
     * 16 byte boundary.  Try to avoid trashing it.
2709
     */
2710
    sp -= 32;
2711

    
2712
    /* This is the X/Open sanctioned signal stack switching.  */
2713
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2714
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2715
    }
2716

    
2717
    return (sp - frame_size) & ~7;
2718
}
2719

    
2720
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2721
static void setup_frame(int sig, struct target_sigaction * ka,
2722
                        target_sigset_t *set, CPUMIPSState *regs)
2723
{
2724
    struct sigframe *frame;
2725
    abi_ulong frame_addr;
2726
    int i;
2727

    
2728
    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2729
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2730
        goto give_sigsegv;
2731

    
2732
    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2733

    
2734
    if(setup_sigcontext(regs, &frame->sf_sc))
2735
        goto give_sigsegv;
2736

    
2737
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2738
        if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2739
            goto give_sigsegv;
2740
    }
2741

    
2742
    /*
2743
    * Arguments to signal handler:
2744
    *
2745
    *   a0 = signal number
2746
    *   a1 = 0 (should be cause)
2747
    *   a2 = pointer to struct sigcontext
2748
    *
2749
    * $25 and PC point to the signal handler, $29 points to the
2750
    * struct sigframe.
2751
    */
2752
    regs->active_tc.gpr[ 4] = sig;
2753
    regs->active_tc.gpr[ 5] = 0;
2754
    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2755
    regs->active_tc.gpr[29] = frame_addr;
2756
    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2757
    /* The original kernel code sets CP0_EPC to the handler
2758
    * since it returns to userland using eret
2759
    * we cannot do this here, and we must set PC directly */
2760
    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2761
    unlock_user_struct(frame, frame_addr, 1);
2762
    return;
2763

    
2764
give_sigsegv:
2765
    unlock_user_struct(frame, frame_addr, 1);
2766
    force_sig(TARGET_SIGSEGV/*, current*/);
2767
    return;
2768
}
2769

    
2770
long do_sigreturn(CPUMIPSState *regs)
2771
{
2772
    struct sigframe *frame;
2773
    abi_ulong frame_addr;
2774
    sigset_t blocked;
2775
    target_sigset_t target_set;
2776
    int i;
2777

    
2778
#if defined(DEBUG_SIGNAL)
2779
    fprintf(stderr, "do_sigreturn\n");
2780
#endif
2781
    frame_addr = regs->active_tc.gpr[29];
2782
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2783
           goto badframe;
2784

    
2785
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2786
           if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2787
            goto badframe;
2788
    }
2789

    
2790
    target_to_host_sigset_internal(&blocked, &target_set);
2791
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2792

    
2793
    if (restore_sigcontext(regs, &frame->sf_sc))
2794
           goto badframe;
2795

    
2796
#if 0
2797
    /*
2798
     * Don't let your children do this ...
2799
     */
2800
    __asm__ __volatile__(
2801
           "move\t$29, %0\n\t"
2802
           "j\tsyscall_exit"
2803
           :/* no outputs */
2804
           :"r" (&regs));
2805
    /* Unreached */
2806
#endif
2807

    
2808
    regs->active_tc.PC = regs->CP0_EPC;
2809
    /* I am not sure this is right, but it seems to work
2810
    * maybe a problem with nested signals ? */
2811
    regs->CP0_EPC = 0;
2812
    return -TARGET_QEMU_ESIGRETURN;
2813

    
2814
badframe:
2815
    force_sig(TARGET_SIGSEGV/*, current*/);
2816
    return 0;
2817
}
2818

    
2819
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2820
                           target_siginfo_t *info,
2821
                           target_sigset_t *set, CPUMIPSState *env)
2822
{
2823
    struct target_rt_sigframe *frame;
2824
    abi_ulong frame_addr;
2825
    int i;
2826

    
2827
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
2828
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2829
        goto give_sigsegv;
2830

    
2831
    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
2832

    
2833
    copy_siginfo_to_user(&frame->rs_info, info);
2834

    
2835
    __put_user(0, &frame->rs_uc.tuc_flags);
2836
    __put_user(0, &frame->rs_uc.tuc_link);
2837
    __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
2838
    __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
2839
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
2840
               &frame->rs_uc.tuc_stack.ss_flags);
2841

    
2842
    setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
2843

    
2844
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2845
        __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
2846
    }
2847

    
2848
    /*
2849
    * Arguments to signal handler:
2850
    *
2851
    *   a0 = signal number
2852
    *   a1 = pointer to struct siginfo
2853
    *   a2 = pointer to struct ucontext
2854
    *
2855
    * $25 and PC point to the signal handler, $29 points to the
2856
    * struct sigframe.
2857
    */
2858
    env->active_tc.gpr[ 4] = sig;
2859
    env->active_tc.gpr[ 5] = frame_addr
2860
                             + offsetof(struct target_rt_sigframe, rs_info);
2861
    env->active_tc.gpr[ 6] = frame_addr
2862
                             + offsetof(struct target_rt_sigframe, rs_uc);
2863
    env->active_tc.gpr[29] = frame_addr;
2864
    env->active_tc.gpr[31] = frame_addr
2865
                             + offsetof(struct target_rt_sigframe, rs_code);
2866
    /* The original kernel code sets CP0_EPC to the handler
2867
    * since it returns to userland using eret
2868
    * we cannot do this here, and we must set PC directly */
2869
    env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
2870
    unlock_user_struct(frame, frame_addr, 1);
2871
    return;
2872

    
2873
give_sigsegv:
2874
    unlock_user_struct(frame, frame_addr, 1);
2875
    force_sig(TARGET_SIGSEGV/*, current*/);
2876
    return;
2877
}
2878

    
2879
long do_rt_sigreturn(CPUMIPSState *env)
2880
{
2881
    struct target_rt_sigframe *frame;
2882
    abi_ulong frame_addr;
2883
    sigset_t blocked;
2884

    
2885
#if defined(DEBUG_SIGNAL)
2886
    fprintf(stderr, "do_rt_sigreturn\n");
2887
#endif
2888
    frame_addr = env->active_tc.gpr[29];
2889
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2890
           goto badframe;
2891

    
2892
    target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
2893
    sigprocmask(SIG_SETMASK, &blocked, NULL);
2894

    
2895
    if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
2896
        goto badframe;
2897

    
2898
    if (do_sigaltstack(frame_addr +
2899
                       offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
2900
                       0, get_sp_from_cpustate(env)) == -EFAULT)
2901
        goto badframe;
2902

    
2903
    env->active_tc.PC = env->CP0_EPC;
2904
    /* I am not sure this is right, but it seems to work
2905
    * maybe a problem with nested signals ? */
2906
    env->CP0_EPC = 0;
2907
    return -TARGET_QEMU_ESIGRETURN;
2908

    
2909
badframe:
2910
    force_sig(TARGET_SIGSEGV/*, current*/);
2911
    return 0;
2912
}
2913

    
2914
#elif defined(TARGET_SH4)
2915

    
2916
/*
2917
 * code and data structures from linux kernel:
2918
 * include/asm-sh/sigcontext.h
2919
 * arch/sh/kernel/signal.c
2920
 */
2921

    
2922
struct target_sigcontext {
2923
    target_ulong  oldmask;
2924

    
2925
    /* CPU registers */
2926
    target_ulong  sc_gregs[16];
2927
    target_ulong  sc_pc;
2928
    target_ulong  sc_pr;
2929
    target_ulong  sc_sr;
2930
    target_ulong  sc_gbr;
2931
    target_ulong  sc_mach;
2932
    target_ulong  sc_macl;
2933

    
2934
    /* FPU registers */
2935
    target_ulong  sc_fpregs[16];
2936
    target_ulong  sc_xfpregs[16];
2937
    unsigned int sc_fpscr;
2938
    unsigned int sc_fpul;
2939
    unsigned int sc_ownedfp;
2940
};
2941

    
2942
struct target_sigframe
2943
{
2944
    struct target_sigcontext sc;
2945
    target_ulong extramask[TARGET_NSIG_WORDS-1];
2946
    uint16_t retcode[3];
2947
};
2948

    
2949

    
2950
struct target_ucontext {
2951
    target_ulong tuc_flags;
2952
    struct target_ucontext *tuc_link;
2953
    target_stack_t tuc_stack;
2954
    struct target_sigcontext tuc_mcontext;
2955
    target_sigset_t tuc_sigmask;        /* mask last for extensibility */
2956
};
2957

    
2958
struct target_rt_sigframe
2959
{
2960
    struct target_siginfo info;
2961
    struct target_ucontext uc;
2962
    uint16_t retcode[3];
2963
};
2964

    
2965

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

    
2969
static abi_ulong get_sigframe(struct target_sigaction *ka,
2970
                         unsigned long sp, size_t frame_size)
2971
{
2972
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2973
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2974
    }
2975

    
2976
    return (sp - frame_size) & -8ul;
2977
}
2978

    
2979
static int setup_sigcontext(struct target_sigcontext *sc,
2980
                            CPUSH4State *regs, unsigned long mask)
2981
{
2982
    int err = 0;
2983
    int i;
2984

    
2985
#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
2986
    COPY(gregs[0]); COPY(gregs[1]);
2987
    COPY(gregs[2]); COPY(gregs[3]);
2988
    COPY(gregs[4]); COPY(gregs[5]);
2989
    COPY(gregs[6]); COPY(gregs[7]);
2990
    COPY(gregs[8]); COPY(gregs[9]);
2991
    COPY(gregs[10]); COPY(gregs[11]);
2992
    COPY(gregs[12]); COPY(gregs[13]);
2993
    COPY(gregs[14]); COPY(gregs[15]);
2994
    COPY(gbr); COPY(mach);
2995
    COPY(macl); COPY(pr);
2996
    COPY(sr); COPY(pc);
2997
#undef COPY
2998

    
2999
    for (i=0; i<16; i++) {
3000
        err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3001
    }
3002
    err |= __put_user(regs->fpscr, &sc->sc_fpscr);
3003
    err |= __put_user(regs->fpul, &sc->sc_fpul);
3004

    
3005
    /* non-iBCS2 extensions.. */
3006
    err |= __put_user(mask, &sc->oldmask);
3007

    
3008
    return err;
3009
}
3010

    
3011
static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3012
                              target_ulong *r0_p)
3013
{
3014
    unsigned int err = 0;
3015
    int i;
3016

    
3017
#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
3018
    COPY(gregs[1]);
3019
    COPY(gregs[2]); COPY(gregs[3]);
3020
    COPY(gregs[4]); COPY(gregs[5]);
3021
    COPY(gregs[6]); COPY(gregs[7]);
3022
    COPY(gregs[8]); COPY(gregs[9]);
3023
    COPY(gregs[10]); COPY(gregs[11]);
3024
    COPY(gregs[12]); COPY(gregs[13]);
3025
    COPY(gregs[14]); COPY(gregs[15]);
3026
    COPY(gbr); COPY(mach);
3027
    COPY(macl); COPY(pr);
3028
    COPY(sr); COPY(pc);
3029
#undef COPY
3030

    
3031
    for (i=0; i<16; i++) {
3032
        err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3033
    }
3034
    err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3035
    err |= __get_user(regs->fpul, &sc->sc_fpul);
3036

    
3037
    regs->tra = -1;         /* disable syscall checks */
3038
    err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3039
    return err;
3040
}
3041

    
3042
static void setup_frame(int sig, struct target_sigaction *ka,
3043
                        target_sigset_t *set, CPUSH4State *regs)
3044
{
3045
    struct target_sigframe *frame;
3046
    abi_ulong frame_addr;
3047
    int i;
3048
    int err = 0;
3049
    int signal;
3050

    
3051
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3052
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3053
        goto give_sigsegv;
3054

    
3055
    signal = current_exec_domain_sig(sig);
3056

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

    
3059
    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3060
        err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3061
    }
3062

    
3063
    /* Set up to return from userspace.  If provided, use a stub
3064
       already in userspace.  */
3065
    if (ka->sa_flags & TARGET_SA_RESTORER) {
3066
        regs->pr = (unsigned long) ka->sa_restorer;
3067
    } else {
3068
        /* Generate return code (system call to sigreturn) */
3069
        err |= __put_user(MOVW(2), &frame->retcode[0]);
3070
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3071
        err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3072
        regs->pr = (unsigned long) frame->retcode;
3073
    }
3074

    
3075
    if (err)
3076
        goto give_sigsegv;
3077

    
3078
    /* Set up registers for signal handler */
3079
    regs->gregs[15] = frame_addr;
3080
    regs->gregs[4] = signal; /* Arg for signal handler */
3081
    regs->gregs[5] = 0;
3082
    regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3083
    regs->pc = (unsigned long) ka->_sa_handler;
3084

    
3085
    unlock_user_struct(frame, frame_addr, 1);
3086
    return;
3087

    
3088
give_sigsegv:
3089
    unlock_user_struct(frame, frame_addr, 1);
3090
    force_sig(TARGET_SIGSEGV);
3091
}
3092

    
3093
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3094
                           target_siginfo_t *info,
3095
                           target_sigset_t *set, CPUSH4State *regs)
3096
{
3097
    struct target_rt_sigframe *frame;
3098
    abi_ulong frame_addr;
3099
    int i;
3100
    int err = 0;
3101
    int signal;
3102

    
3103
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3104
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3105
        goto give_sigsegv;
3106

    
3107
    signal = current_exec_domain_sig(sig);
3108

    
3109
    err |= copy_siginfo_to_user(&frame->info, info);
3110

    
3111
    /* Create the ucontext.  */
3112
    err |= __put_user(0, &frame->uc.tuc_flags);
3113
    err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3114
    err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3115
                      &frame->uc.tuc_stack.ss_sp);
3116
    err |= __put_user(sas_ss_flags(regs->gregs[15]),
3117
                      &frame->uc.tuc_stack.ss_flags);
3118
    err |= __put_user(target_sigaltstack_used.ss_size,
3119
                      &frame->uc.tuc_stack.ss_size);
3120
    err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3121
                            regs, set->sig[0]);
3122
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3123
        err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3124
    }
3125

    
3126
    /* Set up to return from userspace.  If provided, use a stub
3127
       already in userspace.  */
3128
    if (ka->sa_flags & TARGET_SA_RESTORER) {
3129
        regs->pr = (unsigned long) ka->sa_restorer;
3130
    } else {
3131
        /* Generate return code (system call to sigreturn) */
3132
        err |= __put_user(MOVW(2), &frame->retcode[0]);
3133
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3134
        err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3135
        regs->pr = (unsigned long) frame->retcode;
3136
    }
3137

    
3138
    if (err)
3139
        goto give_sigsegv;
3140

    
3141
    /* Set up registers for signal handler */
3142
    regs->gregs[15] = frame_addr;
3143
    regs->gregs[4] = signal; /* Arg for signal handler */
3144
    regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3145
    regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3146
    regs->pc = (unsigned long) ka->_sa_handler;
3147

    
3148
    unlock_user_struct(frame, frame_addr, 1);
3149
    return;
3150

    
3151
give_sigsegv:
3152
    unlock_user_struct(frame, frame_addr, 1);
3153
    force_sig(TARGET_SIGSEGV);
3154
}
3155

    
3156
long do_sigreturn(CPUSH4State *regs)
3157
{
3158
    struct target_sigframe *frame;
3159
    abi_ulong frame_addr;
3160
    sigset_t blocked;
3161
    target_sigset_t target_set;
3162
    target_ulong r0;
3163
    int i;
3164
    int err = 0;
3165

    
3166
#if defined(DEBUG_SIGNAL)
3167
    fprintf(stderr, "do_sigreturn\n");
3168
#endif
3169
    frame_addr = regs->gregs[15];
3170
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3171
           goto badframe;
3172

    
3173
    err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3174
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3175
        err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3176
    }
3177

    
3178
    if (err)
3179
        goto badframe;
3180

    
3181
    target_to_host_sigset_internal(&blocked, &target_set);
3182
    sigprocmask(SIG_SETMASK, &blocked, NULL);
3183

    
3184
    if (restore_sigcontext(regs, &frame->sc, &r0))
3185
        goto badframe;
3186

    
3187
    unlock_user_struct(frame, frame_addr, 0);
3188
    return r0;
3189

    
3190
badframe:
3191
    unlock_user_struct(frame, frame_addr, 0);
3192
    force_sig(TARGET_SIGSEGV);
3193
    return 0;
3194
}
3195

    
3196
long do_rt_sigreturn(CPUSH4State *regs)
3197
{
3198
    struct target_rt_sigframe *frame;
3199
    abi_ulong frame_addr;
3200
    sigset_t blocked;
3201
    target_ulong r0;
3202

    
3203
#if defined(DEBUG_SIGNAL)
3204
    fprintf(stderr, "do_rt_sigreturn\n");
3205
#endif
3206
    frame_addr = regs->gregs[15];
3207
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3208
           goto badframe;
3209

    
3210
    target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3211
    sigprocmask(SIG_SETMASK, &blocked, NULL);
3212

    
3213
    if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3214
        goto badframe;
3215

    
3216
    if (do_sigaltstack(frame_addr +
3217
                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
3218
                       0, get_sp_from_cpustate(regs)) == -EFAULT)
3219
        goto badframe;
3220

    
3221
    unlock_user_struct(frame, frame_addr, 0);
3222
    return r0;
3223

    
3224
badframe:
3225
    unlock_user_struct(frame, frame_addr, 0);
3226
    force_sig(TARGET_SIGSEGV);
3227
    return 0;
3228
}
3229
#elif defined(TARGET_MICROBLAZE)
3230

    
3231
struct target_sigcontext {
3232
    struct target_pt_regs regs;  /* needs to be first */
3233
    uint32_t oldmask;
3234
};
3235

    
3236
struct target_stack_t {
3237
    abi_ulong ss_sp;
3238
    int ss_flags;
3239
    unsigned int ss_size;
3240
};
3241

    
3242
struct target_ucontext {
3243
    abi_ulong tuc_flags;
3244
    abi_ulong tuc_link;
3245
    struct target_stack_t tuc_stack;
3246
    struct target_sigcontext tuc_mcontext;
3247
    uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3248
};
3249

    
3250
/* Signal frames. */
3251
struct target_signal_frame {
3252
    struct target_ucontext uc;
3253
    uint32_t extramask[TARGET_NSIG_WORDS - 1];
3254
    uint32_t tramp[2];
3255
};
3256

    
3257
struct rt_signal_frame {
3258
    struct siginfo info;
3259
    struct ucontext uc;
3260
    uint32_t tramp[2];
3261
};
3262

    
3263
static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3264
{
3265
    __put_user(env->regs[0], &sc->regs.r0);
3266
    __put_user(env->regs[1], &sc->regs.r1);
3267
    __put_user(env->regs[2], &sc->regs.r2);
3268
    __put_user(env->regs[3], &sc->regs.r3);
3269
    __put_user(env->regs[4], &sc->regs.r4);
3270
    __put_user(env->regs[5], &sc->regs.r5);
3271
    __put_user(env->regs[6], &sc->regs.r6);
3272
    __put_user(env->regs[7], &sc->regs.r7);
3273
    __put_user(env->regs[8], &sc->regs.r8);
3274
    __put_user(env->regs[9], &sc->regs.r9);
3275
    __put_user(env->regs[10], &sc->regs.r10);
3276
    __put_user(env->regs[11], &sc->regs.r11);
3277
    __put_user(env->regs[12], &sc->regs.r12);
3278
    __put_user(env->regs[13], &sc->regs.r13);
3279
    __put_user(env->regs[14], &sc->regs.r14);
3280
    __put_user(env->regs[15], &sc->regs.r15);
3281
    __put_user(env->regs[16], &sc->regs.r16);
3282
    __put_user(env->regs[17], &sc->regs.r17);
3283
    __put_user(env->regs[18], &sc->regs.r18);
3284
    __put_user(env->regs[19], &sc->regs.r19);
3285
    __put_user(env->regs[20], &sc->regs.r20);
3286
    __put_user(env->regs[21], &sc->regs.r21);
3287
    __put_user(env->regs[22], &sc->regs.r22);
3288
    __put_user(env->regs[23], &sc->regs.r23);
3289
    __put_user(env->regs[24], &sc->regs.r24);
3290
    __put_user(env->regs[25], &sc->regs.r25);
3291
    __put_user(env->regs[26], &sc->regs.r26);
3292
    __put_user(env->regs[27], &sc->regs.r27);
3293
    __put_user(env->regs[28], &sc->regs.r28);
3294
    __put_user(env->regs[29], &sc->regs.r29);
3295
    __put_user(env->regs[30], &sc->regs.r30);
3296
    __put_user(env->regs[31], &sc->regs.r31);
3297
    __put_user(env->sregs[SR_PC], &sc->regs.pc);
3298
}
3299

    
3300
static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3301
{
3302
    __get_user(env->regs[0], &sc->regs.r0);
3303
    __get_user(env->regs[1], &sc->regs.r1);
3304
    __get_user(env->regs[2], &sc->regs.r2);
3305
    __get_user(env->regs[3], &sc->regs.r3);
3306
    __get_user(env->regs[4], &sc->regs.r4);
3307
    __get_user(env->regs[5], &sc->regs.r5);
3308
    __get_user(env->regs[6], &sc->regs.r6);
3309
    __get_user(env->regs[7], &sc->regs.r7);
3310
    __get_user(env->regs[8], &sc->regs.r8);
3311
    __get_user(env->regs[9], &sc->regs.r9);
3312
    __get_user(env->regs[10], &sc->regs.r10);
3313
    __get_user(env->regs[11], &sc->regs.r11);
3314
    __get_user(env->regs[12], &sc->regs.r12);
3315
    __get_user(env->regs[13], &sc->regs.r13);
3316
    __get_user(env->regs[14], &sc->regs.r14);
3317
    __get_user(env->regs[15], &sc->regs.r15);
3318
    __get_user(env->regs[16], &sc->regs.r16);
3319
    __get_user(env->regs[17], &sc->regs.r17);
3320
    __get_user(env->regs[18], &sc->regs.r18);
3321
    __get_user(env->regs[19], &sc->regs.r19);
3322
    __get_user(env->regs[20], &sc->regs.r20);
3323
    __get_user(env->regs[21], &sc->regs.r21);
3324
    __get_user(env->regs[22], &sc->regs.r22);
3325
    __get_user(env->regs[23], &sc->regs.r23);
3326
    __get_user(env->regs[24], &sc->regs.r24);
3327
    __get_user(env->regs[25], &sc->regs.r25);
3328
    __get_user(env->regs[26], &sc->regs.r26);
3329
    __get_user(env->regs[27], &sc->regs.r27);
3330
    __get_user(env->regs[28], &sc->regs.r28);
3331
    __get_user(env->regs[29], &sc->regs.r29);
3332
    __get_user(env->regs[30], &sc->regs.r30);
3333
    __get_user(env->regs[31], &sc->regs.r31);
3334
    __get_user(env->sregs[SR_PC], &sc->regs.pc);
3335
}
3336

    
3337
static abi_ulong get_sigframe(struct target_sigaction *ka,
3338
                              CPUMBState *env, int frame_size)
3339
{
3340
    abi_ulong sp = env->regs[1];
3341

    
3342
    if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3343
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3344

    
3345
    return ((sp - frame_size) & -8UL);
3346
}
3347

    
3348
static void setup_frame(int sig, struct target_sigaction *ka,
3349
                        target_sigset_t *set, CPUMBState *env)
3350
{
3351
    struct target_signal_frame *frame;
3352
    abi_ulong frame_addr;
3353
    int err = 0;
3354
    int i;
3355

    
3356
    frame_addr = get_sigframe(ka, env, sizeof *frame);
3357
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3358
        goto badframe;
3359

    
3360
    /* Save the mask.  */
3361
    err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3362
    if (err)
3363
        goto badframe;
3364

    
3365
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3366
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3367
            goto badframe;
3368
    }
3369

    
3370
    setup_sigcontext(&frame->uc.tuc_mcontext, env);
3371

    
3372
    /* Set up to return from userspace. If provided, use a stub
3373
       already in userspace. */
3374
    /* minus 8 is offset to cater for "rtsd r15,8" offset */
3375
    if (ka->sa_flags & TARGET_SA_RESTORER) {
3376
        env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3377
    } else {
3378
        uint32_t t;
3379
        /* Note, these encodings are _big endian_! */
3380
        /* addi r12, r0, __NR_sigreturn */
3381
        t = 0x31800000UL | TARGET_NR_sigreturn;
3382
        err |= __put_user(t, frame->tramp + 0);
3383
        /* brki r14, 0x8 */
3384
        t = 0xb9cc0008UL;
3385
        err |= __put_user(t, frame->tramp + 1);
3386

    
3387
        /* Return from sighandler will jump to the tramp.
3388
           Negative 8 offset because return is rtsd r15, 8 */
3389
        env->regs[15] = ((unsigned long)frame->tramp) - 8;
3390
    }
3391

    
3392
    if (err)
3393
        goto badframe;
3394

    
3395
    /* Set up registers for signal handler */
3396
    env->regs[1] = frame_addr;
3397
    /* Signal handler args: */
3398
    env->regs[5] = sig; /* Arg 0: signum */
3399
    env->regs[6] = 0;
3400
    /* arg 1: sigcontext */
3401
    env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3402

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

    
3406
    unlock_user_struct(frame, frame_addr, 1);
3407
    return;
3408
  badframe:
3409
    unlock_user_struct(frame, frame_addr, 1);
3410
    force_sig(TARGET_SIGSEGV);
3411
}
3412

    
3413
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3414
                           target_siginfo_t *info,
3415
                           target_sigset_t *set, CPUMBState *env)
3416
{
3417
    fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3418
}
3419

    
3420
long do_sigreturn(CPUMBState *env)
3421
{
3422
    struct target_signal_frame *frame;
3423
    abi_ulong frame_addr;
3424
    target_sigset_t target_set;
3425
    sigset_t set;
3426
    int i;
3427

    
3428
    frame_addr = env->regs[R_SP];
3429
    /* Make sure the guest isn't playing games.  */
3430
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3431
        goto badframe;
3432

    
3433
    /* Restore blocked signals */
3434
    if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3435
        goto badframe;
3436
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3437
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3438
            goto badframe;
3439
    }
3440
    target_to_host_sigset_internal(&set, &target_set);
3441
    sigprocmask(SIG_SETMASK, &set, NULL);
3442

    
3443
    restore_sigcontext(&frame->uc.tuc_mcontext, env);
3444
    /* We got here through a sigreturn syscall, our path back is via an
3445
       rtb insn so setup r14 for that.  */
3446
    env->regs[14] = env->sregs[SR_PC];
3447
 
3448
    unlock_user_struct(frame, frame_addr, 0);
3449
    return env->regs[10];
3450
  badframe:
3451
    unlock_user_struct(frame, frame_addr, 0);
3452
    force_sig(TARGET_SIGSEGV);
3453
}
3454

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

    
3461
#elif defined(TARGET_CRIS)
3462

    
3463
struct target_sigcontext {
3464
        struct target_pt_regs regs;  /* needs to be first */
3465
        uint32_t oldmask;
3466
        uint32_t usp;    /* usp before stacking this gunk on it */
3467
};
3468

    
3469
/* Signal frames. */
3470
struct target_signal_frame {
3471
        struct target_sigcontext sc;
3472
        uint32_t extramask[TARGET_NSIG_WORDS - 1];
3473
        uint8_t retcode[8];       /* Trampoline code. */
3474
};
3475

    
3476
struct rt_signal_frame {
3477
        struct siginfo *pinfo;
3478
        void *puc;
3479
        struct siginfo info;
3480
        struct ucontext uc;
3481
        uint8_t retcode[8];       /* Trampoline code. */
3482
};
3483

    
3484
static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3485
{
3486
        __put_user(env->regs[0], &sc->regs.r0);
3487
        __put_user(env->regs[1], &sc->regs.r1);
3488
        __put_user(env->regs[2], &sc->regs.r2);
3489
        __put_user(env->regs[3], &sc->regs.r3);
3490
        __put_user(env->regs[4], &sc->regs.r4);
3491
        __put_user(env->regs[5], &sc->regs.r5);
3492
        __put_user(env->regs[6], &sc->regs.r6);
3493
        __put_user(env->regs[7], &sc->regs.r7);
3494
        __put_user(env->regs[8], &sc->regs.r8);
3495
        __put_user(env->regs[9], &sc->regs.r9);
3496
        __put_user(env->regs[10], &sc->regs.r10);
3497
        __put_user(env->regs[11], &sc->regs.r11);
3498
        __put_user(env->regs[12], &sc->regs.r12);
3499
        __put_user(env->regs[13], &sc->regs.r13);
3500
        __put_user(env->regs[14], &sc->usp);
3501
        __put_user(env->regs[15], &sc->regs.acr);
3502
        __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3503
        __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3504
        __put_user(env->pc, &sc->regs.erp);
3505
}
3506

    
3507
static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3508
{
3509
        __get_user(env->regs[0], &sc->regs.r0);
3510
        __get_user(env->regs[1], &sc->regs.r1);
3511
        __get_user(env->regs[2], &sc->regs.r2);
3512
        __get_user(env->regs[3], &sc->regs.r3);
3513
        __get_user(env->regs[4], &sc->regs.r4);
3514
        __get_user(env->regs[5], &sc->regs.r5);
3515
        __get_user(env->regs[6], &sc->regs.r6);
3516
        __get_user(env->regs[7], &sc->regs.r7);
3517
        __get_user(env->regs[8], &sc->regs.r8);
3518
        __get_user(env->regs[9], &sc->regs.r9);
3519
        __get_user(env->regs[10], &sc->regs.r10);
3520
        __get_user(env->regs[11], &sc->regs.r11);
3521
        __get_user(env->regs[12], &sc->regs.r12);
3522
        __get_user(env->regs[13], &sc->regs.r13);
3523
        __get_user(env->regs[14], &sc->usp);
3524
        __get_user(env->regs[15], &sc->regs.acr);
3525
        __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3526
        __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3527
        __get_user(env->pc, &sc->regs.erp);
3528
}
3529

    
3530
static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3531
{
3532
        abi_ulong sp;
3533
        /* Align the stack downwards to 4.  */
3534
        sp = (env->regs[R_SP] & ~3);
3535
        return sp - framesize;
3536
}
3537

    
3538
static void setup_frame(int sig, struct target_sigaction *ka,
3539
                        target_sigset_t *set, CPUCRISState *env)
3540
{
3541
        struct target_signal_frame *frame;
3542
        abi_ulong frame_addr;
3543
        int err = 0;
3544
        int i;
3545

    
3546
        frame_addr = get_sigframe(env, sizeof *frame);
3547
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3548
                goto badframe;
3549

    
3550
        /*
3551
         * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3552
         * use this trampoline anymore but it sets it up for GDB.
3553
         * In QEMU, using the trampoline simplifies things a bit so we use it.
3554
         *
3555
         * This is movu.w __NR_sigreturn, r9; break 13;
3556
         */
3557
        err |= __put_user(0x9c5f, frame->retcode+0);
3558
        err |= __put_user(TARGET_NR_sigreturn, 
3559
                          frame->retcode+2);
3560
        err |= __put_user(0xe93d, frame->retcode+4);
3561

    
3562
        /* Save the mask.  */
3563
        err |= __put_user(set->sig[0], &frame->sc.oldmask);
3564
        if (err)
3565
                goto badframe;
3566

    
3567
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3568
                if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3569
                        goto badframe;
3570
        }
3571

    
3572
        setup_sigcontext(&frame->sc, env);
3573

    
3574
        /* Move the stack and setup the arguments for the handler.  */
3575
        env->regs[R_SP] = frame_addr;
3576
        env->regs[10] = sig;
3577
        env->pc = (unsigned long) ka->_sa_handler;
3578
        /* Link SRP so the guest returns through the trampoline.  */
3579
        env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3580

    
3581
        unlock_user_struct(frame, frame_addr, 1);
3582
        return;
3583
  badframe:
3584
        unlock_user_struct(frame, frame_addr, 1);
3585
        force_sig(TARGET_SIGSEGV);
3586
}
3587

    
3588
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3589
                           target_siginfo_t *info,
3590
                           target_sigset_t *set, CPUCRISState *env)
3591
{
3592
    fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3593
}
3594

    
3595
long do_sigreturn(CPUCRISState *env)
3596
{
3597
        struct target_signal_frame *frame;
3598
        abi_ulong frame_addr;
3599
        target_sigset_t target_set;
3600
        sigset_t set;
3601
        int i;
3602

    
3603
        frame_addr = env->regs[R_SP];
3604
        /* Make sure the guest isn't playing games.  */
3605
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3606
                goto badframe;
3607

    
3608
        /* Restore blocked signals */
3609
        if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3610
                goto badframe;
3611
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3612
                if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3613
                        goto badframe;
3614
        }
3615
        target_to_host_sigset_internal(&set, &target_set);
3616
        sigprocmask(SIG_SETMASK, &set, NULL);
3617

    
3618
        restore_sigcontext(&frame->sc, env);
3619
        unlock_user_struct(frame, frame_addr, 0);
3620
        return env->regs[10];
3621
  badframe:
3622
        unlock_user_struct(frame, frame_addr, 0);
3623
        force_sig(TARGET_SIGSEGV);
3624
}
3625

    
3626
long do_rt_sigreturn(CPUCRISState *env)
3627
{
3628
    fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3629
    return -TARGET_ENOSYS;
3630
}
3631

    
3632
#elif defined(TARGET_S390X)
3633

    
3634
#define __NUM_GPRS 16
3635
#define __NUM_FPRS 16
3636
#define __NUM_ACRS 16
3637

    
3638
#define S390_SYSCALL_SIZE   2
3639
#define __SIGNAL_FRAMESIZE      160 /* FIXME: 31-bit mode -> 96 */
3640

    
3641
#define _SIGCONTEXT_NSIG        64
3642
#define _SIGCONTEXT_NSIG_BPW    64 /* FIXME: 31-bit mode -> 32 */
3643
#define _SIGCONTEXT_NSIG_WORDS  (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
3644
#define _SIGMASK_COPY_SIZE    (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
3645
#define PSW_ADDR_AMODE            0x0000000000000000UL /* 0x80000000UL for 31-bit */
3646
#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
3647

    
3648
typedef struct {
3649
    target_psw_t psw;
3650
    target_ulong gprs[__NUM_GPRS];
3651
    unsigned int acrs[__NUM_ACRS];
3652
} target_s390_regs_common;
3653

    
3654
typedef struct {
3655
    unsigned int fpc;
3656
    double   fprs[__NUM_FPRS];
3657
} target_s390_fp_regs;
3658

    
3659
typedef struct {
3660
    target_s390_regs_common regs;
3661
    target_s390_fp_regs     fpregs;
3662
} target_sigregs;
3663

    
3664
struct target_sigcontext {
3665
    target_ulong   oldmask[_SIGCONTEXT_NSIG_WORDS];
3666
    target_sigregs *sregs;
3667
};
3668

    
3669
typedef struct {
3670
    uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
3671
    struct target_sigcontext sc;
3672
    target_sigregs sregs;
3673
    int signo;
3674
    uint8_t retcode[S390_SYSCALL_SIZE];
3675
} sigframe;
3676

    
3677
struct target_ucontext {
3678
    target_ulong tuc_flags;
3679
    struct target_ucontext *tuc_link;
3680
    target_stack_t tuc_stack;
3681
    target_sigregs tuc_mcontext;
3682
    target_sigset_t tuc_sigmask;   /* mask last for extensibility */
3683
};
3684

    
3685
typedef struct {
3686
    uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
3687
    uint8_t retcode[S390_SYSCALL_SIZE];
3688
    struct target_siginfo info;
3689
    struct target_ucontext uc;
3690
} rt_sigframe;
3691

    
3692
static inline abi_ulong
3693
get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
3694
{
3695
    abi_ulong sp;
3696

    
3697
    /* Default to using normal stack */
3698
    sp = env->regs[15];
3699

    
3700
    /* This is the X/Open sanctioned signal stack switching.  */
3701
    if (ka->sa_flags & TARGET_SA_ONSTACK) {
3702
        if (!sas_ss_flags(sp)) {
3703
            sp = target_sigaltstack_used.ss_sp +
3704
                 target_sigaltstack_used.ss_size;
3705
        }
3706
    }
3707

    
3708
    /* This is the legacy signal stack switching. */
3709
    else if (/* FIXME !user_mode(regs) */ 0 &&
3710
             !(ka->sa_flags & TARGET_SA_RESTORER) &&
3711
             ka->sa_restorer) {
3712
        sp = (abi_ulong) ka->sa_restorer;
3713
    }
3714

    
3715
    return (sp - frame_size) & -8ul;
3716
}
3717

    
3718
static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
3719
{
3720
    int i;
3721
    //save_access_regs(current->thread.acrs); FIXME
3722

    
3723
    /* Copy a 'clean' PSW mask to the user to avoid leaking
3724
       information about whether PER is currently on.  */
3725
    __put_user(env->psw.mask, &sregs->regs.psw.mask);
3726
    __put_user(env->psw.addr, &sregs->regs.psw.addr);
3727
    for (i = 0; i < 16; i++) {
3728
        __put_user(env->regs[i], &sregs->regs.gprs[i]);
3729
    }
3730
    for (i = 0; i < 16; i++) {
3731
        __put_user(env->aregs[i], &sregs->regs.acrs[i]);
3732
    }
3733
    /*
3734
     * We have to store the fp registers to current->thread.fp_regs
3735
     * to merge them with the emulated registers.
3736
     */
3737
    //save_fp_regs(&current->thread.fp_regs); FIXME
3738
    for (i = 0; i < 16; i++) {
3739
        __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
3740
    }
3741
}
3742

    
3743
static void setup_frame(int sig, struct target_sigaction *ka,
3744
                        target_sigset_t *set, CPUS390XState *env)
3745
{
3746
    sigframe *frame;
3747
    abi_ulong frame_addr;
3748

    
3749
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
3750
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3751
             (unsigned long long)frame_addr);
3752
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3753
            goto give_sigsegv;
3754
    }
3755

    
3756
    qemu_log("%s: 1\n", __FUNCTION__);
3757
    if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
3758
              goto give_sigsegv;
3759
    }
3760

    
3761
    save_sigregs(env, &frame->sregs);
3762

    
3763
    __put_user((abi_ulong)(unsigned long)&frame->sregs,
3764
               (abi_ulong *)&frame->sc.sregs);
3765

    
3766
    /* Set up to return from userspace.  If provided, use a stub
3767
       already in userspace.  */
3768
    if (ka->sa_flags & TARGET_SA_RESTORER) {
3769
            env->regs[14] = (unsigned long)
3770
                    ka->sa_restorer | PSW_ADDR_AMODE;
3771
    } else {
3772
            env->regs[14] = (unsigned long)
3773
                    frame->retcode | PSW_ADDR_AMODE;
3774
            if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
3775
                           (uint16_t *)(frame->retcode)))
3776
                    goto give_sigsegv;
3777
    }
3778

    
3779
    /* Set up backchain. */
3780
    if (__put_user(env->regs[15], (abi_ulong *) frame)) {
3781
            goto give_sigsegv;
3782
    }
3783

    
3784
    /* Set up registers for signal handler */
3785
    env->regs[15] = frame_addr;
3786
    env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
3787

    
3788
    env->regs[2] = sig; //map_signal(sig);
3789
    env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
3790

    
3791
    /* We forgot to include these in the sigcontext.
3792
       To avoid breaking binary compatibility, they are passed as args. */
3793
    env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
3794
    env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
3795

    
3796
    /* Place signal number on stack to allow backtrace from handler.  */
3797
    if (__put_user(env->regs[2], (int *) &frame->signo)) {
3798
            goto give_sigsegv;
3799
    }
3800
    unlock_user_struct(frame, frame_addr, 1);
3801
    return;
3802

    
3803
give_sigsegv:
3804
    qemu_log("%s: give_sigsegv\n", __FUNCTION__);
3805
    unlock_user_struct(frame, frame_addr, 1);
3806
    force_sig(TARGET_SIGSEGV);
3807
}
3808

    
3809
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3810
                           target_siginfo_t *info,
3811
                           target_sigset_t *set, CPUS390XState *env)
3812
{
3813
    int i;
3814
    rt_sigframe *frame;
3815
    abi_ulong frame_addr;
3816

    
3817
    frame_addr = get_sigframe(ka, env, sizeof *frame);
3818
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3819
             (unsigned long long)frame_addr);
3820
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3821
        goto give_sigsegv;
3822
    }
3823

    
3824
    qemu_log("%s: 1\n", __FUNCTION__);
3825
    if (copy_siginfo_to_user(&frame->info, info)) {
3826
        goto give_sigsegv;
3827
    }
3828

    
3829
    /* Create the ucontext.  */
3830
    __put_user(0, &frame->uc.tuc_flags);
3831
    __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
3832
    __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
3833
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3834
                      &frame->uc.tuc_stack.ss_flags);
3835
    __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
3836
    save_sigregs(env, &frame->uc.tuc_mcontext);
3837
    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
3838
        __put_user((abi_ulong)set->sig[i],
3839
        (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
3840
    }
3841

    
3842
    /* Set up to return from userspace.  If provided, use a stub
3843
       already in userspace.  */
3844
    if (ka->sa_flags & TARGET_SA_RESTORER) {
3845
        env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
3846
    } else {
3847
        env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
3848
        if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
3849
                       (uint16_t *)(frame->retcode))) {
3850
            goto give_sigsegv;
3851
        }
3852
    }
3853

    
3854
    /* Set up backchain. */
3855
    if (__put_user(env->regs[15], (abi_ulong *) frame)) {
3856
        goto give_sigsegv;
3857
    }
3858

    
3859
    /* Set up registers for signal handler */
3860
    env->regs[15] = frame_addr;
3861
    env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
3862

    
3863
    env->regs[2] = sig; //map_signal(sig);
3864
    env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
3865
    env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
3866
    return;
3867

    
3868
give_sigsegv:
3869
    qemu_log("%s: give_sigsegv\n", __FUNCTION__);
3870
    unlock_user_struct(frame, frame_addr, 1);
3871
    force_sig(TARGET_SIGSEGV);
3872
}
3873

    
3874
static int
3875
restore_sigregs(CPUS390XState *env, target_sigregs *sc)
3876
{
3877
    int err = 0;
3878
    int i;
3879

    
3880
    for (i = 0; i < 16; i++) {
3881
        err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
3882
    }
3883

    
3884
    err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
3885
    qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
3886
             __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
3887
             (unsigned long long)env->psw.addr);
3888
    err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
3889
    /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
3890

    
3891
    for (i = 0; i < 16; i++) {
3892
        err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
3893
    }
3894
    for (i = 0; i < 16; i++) {
3895
        err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
3896
    }
3897

    
3898
    return err;
3899
}
3900

    
3901
long do_sigreturn(CPUS390XState *env)
3902
{
3903
    sigframe *frame;
3904
    abi_ulong frame_addr = env->regs[15];
3905
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3906
             (unsigned long long)frame_addr);
3907
    target_sigset_t target_set;
3908
    sigset_t set;
3909

    
3910
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
3911
        goto badframe;
3912
    }
3913
    if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
3914
        goto badframe;
3915
    }
3916

    
3917
    target_to_host_sigset_internal(&set, &target_set);
3918
    sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
3919

    
3920
    if (restore_sigregs(env, &frame->sregs)) {
3921
        goto badframe;
3922
    }
3923

    
3924
    unlock_user_struct(frame, frame_addr, 0);
3925
    return env->regs[2];
3926

    
3927
badframe:
3928
    unlock_user_struct(frame, frame_addr, 0);
3929
    force_sig(TARGET_SIGSEGV);
3930
    return 0;
3931
}
3932

    
3933
long do_rt_sigreturn(CPUS390XState *env)
3934
{
3935
    rt_sigframe *frame;
3936
    abi_ulong frame_addr = env->regs[15];
3937
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
3938
             (unsigned long long)frame_addr);
3939
    sigset_t set;
3940

    
3941
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
3942
        goto badframe;
3943
    }
3944
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
3945

    
3946
    sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
3947

    
3948
    if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
3949
        goto badframe;
3950
    }
3951

    
3952
    if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
3953
                       get_sp_from_cpustate(env)) == -EFAULT) {
3954
        goto badframe;
3955
    }
3956
    unlock_user_struct(frame, frame_addr, 0);
3957
    return env->regs[2];
3958

    
3959
badframe:
3960
    unlock_user_struct(frame, frame_addr, 0);
3961
    force_sig(TARGET_SIGSEGV);
3962
    return 0;
3963
}
3964

    
3965
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3966

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

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

    
3975
/* Size of dummy stack frame allocated when calling signal handler.
3976
   See arch/powerpc/include/asm/ptrace.h.  */
3977
#if defined(TARGET_PPC64)
3978
#define SIGNAL_FRAMESIZE 128
3979
#else
3980
#define SIGNAL_FRAMESIZE 64
3981
#endif
3982

    
3983
/* See arch/powerpc/include/asm/sigcontext.h.  */
3984
struct target_sigcontext {
3985
    target_ulong _unused[4];
3986
    int32_t signal;
3987
#if defined(TARGET_PPC64)
3988
    int32_t pad0;
3989
#endif
3990
    target_ulong handler;
3991
    target_ulong oldmask;
3992
    target_ulong regs;      /* struct pt_regs __user * */
3993
    /* TODO: PPC64 includes extra bits here.  */
3994
};
3995

    
3996
/* Indices for target_mcontext.mc_gregs, below.
3997
   See arch/powerpc/include/asm/ptrace.h for details.  */
3998
enum {
3999
    TARGET_PT_R0 = 0,
4000
    TARGET_PT_R1 = 1,
4001
    TARGET_PT_R2 = 2,
4002
    TARGET_PT_R3 = 3,
4003
    TARGET_PT_R4 = 4,
4004
    TARGET_PT_R5 = 5,
4005
    TARGET_PT_R6 = 6,
4006
    TARGET_PT_R7 = 7,
4007
    TARGET_PT_R8 = 8,
4008
    TARGET_PT_R9 = 9,
4009
    TARGET_PT_R10 = 10,
4010
    TARGET_PT_R11 = 11,
4011
    TARGET_PT_R12 = 12,
4012
    TARGET_PT_R13 = 13,
4013
    TARGET_PT_R14 = 14,
4014
    TARGET_PT_R15 = 15,
4015
    TARGET_PT_R16 = 16,
4016
    TARGET_PT_R17 = 17,
4017
    TARGET_PT_R18 = 18,
4018
    TARGET_PT_R19 = 19,
4019
    TARGET_PT_R20 = 20,
4020
    TARGET_PT_R21 = 21,
4021
    TARGET_PT_R22 = 22,
4022
    TARGET_PT_R23 = 23,
4023
    TARGET_PT_R24 = 24,
4024
    TARGET_PT_R25 = 25,
4025
    TARGET_PT_R26 = 26,
4026
    TARGET_PT_R27 = 27,
4027
    TARGET_PT_R28 = 28,
4028
    TARGET_PT_R29 = 29,
4029
    TARGET_PT_R30 = 30,
4030
    TARGET_PT_R31 = 31,
4031
    TARGET_PT_NIP = 32,
4032
    TARGET_PT_MSR = 33,
4033
    TARGET_PT_ORIG_R3 = 34,
4034
    TARGET_PT_CTR = 35,
4035
    TARGET_PT_LNK = 36,
4036
    TARGET_PT_XER = 37,
4037
    TARGET_PT_CCR = 38,
4038
    /* Yes, there are two registers with #39.  One is 64-bit only.  */
4039
    TARGET_PT_MQ = 39,
4040
    TARGET_PT_SOFTE = 39,
4041
    TARGET_PT_TRAP = 40,
4042
    TARGET_PT_DAR = 41,
4043
    TARGET_PT_DSISR = 42,
4044
    TARGET_PT_RESULT = 43,
4045
    TARGET_PT_REGS_COUNT = 44
4046
};
4047

    
4048
/* See arch/powerpc/include/asm/ucontext.h.  Only used for 32-bit PPC;
4049
   on 64-bit PPC, sigcontext and mcontext are one and the same.  */
4050
struct target_mcontext {
4051
    target_ulong mc_gregs[48];
4052
    /* Includes fpscr.  */
4053
    uint64_t mc_fregs[33];
4054
    target_ulong mc_pad[2];
4055
    /* We need to handle Altivec and SPE at the same time, which no
4056
       kernel needs to do.  Fortunately, the kernel defines this bit to
4057
       be Altivec-register-large all the time, rather than trying to
4058
       twiddle it based on the specific platform.  */
4059
    union {
4060
        /* SPE vector registers.  One extra for SPEFSCR.  */
4061
        uint32_t spe[33];
4062
        /* Altivec vector registers.  The packing of VSCR and VRSAVE
4063
           varies depending on whether we're PPC64 or not: PPC64 splits
4064
           them apart; PPC32 stuffs them together.  */
4065
#if defined(TARGET_PPC64)
4066
#define QEMU_NVRREG 34
4067
#else
4068
#define QEMU_NVRREG 33
4069
#endif
4070
        ppc_avr_t altivec[QEMU_NVRREG];
4071
#undef QEMU_NVRREG
4072
    } mc_vregs __attribute__((__aligned__(16)));
4073
};
4074

    
4075
struct target_ucontext {
4076
    target_ulong tuc_flags;
4077
    target_ulong tuc_link;    /* struct ucontext __user * */
4078
    struct target_sigaltstack tuc_stack;
4079
#if !defined(TARGET_PPC64)
4080
    int32_t tuc_pad[7];
4081
    target_ulong tuc_regs;    /* struct mcontext __user *
4082
                                points to uc_mcontext field */
4083
#endif
4084
    target_sigset_t tuc_sigmask;
4085
#if defined(TARGET_PPC64)
4086
    target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4087
    struct target_sigcontext tuc_mcontext;
4088
#else
4089
    int32_t tuc_maskext[30];
4090
    int32_t tuc_pad2[3];
4091
    struct target_mcontext tuc_mcontext;
4092
#endif
4093
};
4094

    
4095
/* See arch/powerpc/kernel/signal_32.c.  */
4096
struct target_sigframe {
4097
    struct target_sigcontext sctx;
4098
    struct target_mcontext mctx;
4099
    int32_t abigap[56];
4100
};
4101

    
4102
struct target_rt_sigframe {
4103
    struct target_siginfo info;
4104
    struct target_ucontext uc;
4105
    int32_t abigap[56];
4106
};
4107

    
4108
/* We use the mc_pad field for the signal return trampoline.  */
4109
#define tramp mc_pad
4110

    
4111
/* See arch/powerpc/kernel/signal.c.  */
4112
static target_ulong get_sigframe(struct target_sigaction *ka,
4113
                                 CPUPPCState *env,
4114
                                 int frame_size)
4115
{
4116
    target_ulong oldsp, newsp;
4117

    
4118
    oldsp = env->gpr[1];
4119

    
4120
    if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4121
        (sas_ss_flags(oldsp) == 0)) {
4122
        oldsp = (target_sigaltstack_used.ss_sp
4123
                 + target_sigaltstack_used.ss_size);
4124
    }
4125

    
4126
    newsp = (oldsp - frame_size) & ~0xFUL;
4127

    
4128
    return newsp;
4129
}
4130

    
4131
static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4132
                          int sigret)
4133
{
4134
    target_ulong msr = env->msr;
4135
    int i;
4136
    target_ulong ccr = 0;
4137

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

    
4142
    /* Save general registers.  */
4143
    for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4144
        if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
4145
            return 1;
4146
        }
4147
    }
4148
    if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4149
        || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4150
        || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4151
        || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4152
        return 1;
4153

    
4154
    for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4155
        ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4156
    }
4157
    if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4158
        return 1;
4159

    
4160
    /* Save Altivec registers if necessary.  */
4161
    if (env->insns_flags & PPC_ALTIVEC) {
4162
        for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4163
            ppc_avr_t *avr = &env->avr[i];
4164
            ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4165

    
4166
            if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4167
                __put_user(avr->u64[1], &vreg->u64[1])) {
4168
                return 1;
4169
            }
4170
        }
4171
        /* Set MSR_VR in the saved MSR value to indicate that
4172
           frame->mc_vregs contains valid data.  */
4173
        msr |= MSR_VR;
4174
        if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4175
                       &frame->mc_vregs.altivec[32].u32[3]))
4176
            return 1;
4177
    }
4178

    
4179
    /* Save floating point registers.  */
4180
    if (env->insns_flags & PPC_FLOAT) {
4181
        for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4182
            if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
4183
                return 1;
4184
            }
4185
        }
4186
        if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
4187
            return 1;
4188
    }
4189

    
4190
    /* Save SPE registers.  The kernel only saves the high half.  */
4191
    if (env->insns_flags & PPC_SPE) {
4192
#if defined(TARGET_PPC64)
4193
        for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4194
            if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
4195
                return 1;
4196
            }
4197
        }
4198
#else
4199
        for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4200
            if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4201
                return 1;
4202
            }
4203
        }
4204
#endif
4205
        /* Set MSR_SPE in the saved MSR value to indicate that
4206
           frame->mc_vregs contains valid data.  */
4207
        msr |= MSR_SPE;
4208
        if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4209
            return 1;
4210
    }
4211

    
4212
    /* Store MSR.  */
4213
    if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4214
        return 1;
4215

    
4216
    /* Set up the sigreturn trampoline: li r0,sigret; sc.  */
4217
    if (sigret) {
4218
        if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4219
            __put_user(0x44000002UL, &frame->tramp[1])) {
4220
            return 1;
4221
        }
4222
    }
4223

    
4224
    return 0;
4225
}
4226

    
4227
static int restore_user_regs(CPUPPCState *env,
4228
                             struct target_mcontext *frame, int sig)
4229
{
4230
    target_ulong save_r2 = 0;
4231
    target_ulong msr;
4232
    target_ulong ccr;
4233

    
4234
    int i;
4235

    
4236
    if (!sig) {
4237
        save_r2 = env->gpr[2];
4238
    }
4239

    
4240
    /* Restore general registers.  */
4241
    for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4242
        if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
4243
            return 1;
4244
        }
4245
    }
4246
    if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4247
        || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4248
        || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4249
        || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4250
        return 1;
4251
    if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4252
        return 1;
4253

    
4254
    for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4255
        env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4256
    }
4257

    
4258
    if (!sig) {
4259
        env->gpr[2] = save_r2;
4260
    }
4261
    /* Restore MSR.  */
4262
    if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4263
        return 1;
4264

    
4265
    /* If doing signal return, restore the previous little-endian mode.  */
4266
    if (sig)
4267
        env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4268

    
4269
    /* Restore Altivec registers if necessary.  */
4270
    if (env->insns_flags & PPC_ALTIVEC) {
4271
        for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4272
            ppc_avr_t *avr = &env->avr[i];
4273
            ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4274

    
4275
            if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4276
                __get_user(avr->u64[1], &vreg->u64[1])) {
4277
                return 1;
4278
            }
4279
        }
4280
        /* Set MSR_VEC in the saved MSR value to indicate that
4281
           frame->mc_vregs contains valid data.  */
4282
        if (__get_user(env->spr[SPR_VRSAVE],
4283
                       (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
4284
            return 1;
4285
    }
4286

    
4287
    /* Restore floating point registers.  */
4288
    if (env->insns_flags & PPC_FLOAT) {
4289
        uint64_t fpscr;
4290
        for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4291
            if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4292
                return 1;
4293
            }
4294
        }
4295
        if (__get_user(fpscr, &frame->mc_fregs[32]))
4296
            return 1;
4297
        env->fpscr = (uint32_t) fpscr;
4298
    }
4299

    
4300
    /* Save SPE registers.  The kernel only saves the high half.  */
4301
    if (env->insns_flags & PPC_SPE) {
4302
#if defined(TARGET_PPC64)
4303
        for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4304
            uint32_t hi;
4305

    
4306
            if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4307
                return 1;
4308
            }
4309
            env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4310
        }
4311
#else
4312
        for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4313
            if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4314
                return 1;
4315
            }
4316
        }
4317
#endif
4318
        if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4319
            return 1;
4320
    }
4321

    
4322
    return 0;
4323
}
4324

    
4325
static void setup_frame(int sig, struct target_sigaction *ka,
4326
                        target_sigset_t *set, CPUPPCState *env)
4327
{
4328
    struct target_sigframe *frame;
4329
    struct target_sigcontext *sc;
4330
    target_ulong frame_addr, newsp;
4331
    int err = 0;
4332
    int signal;
4333

    
4334
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
4335
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4336
        goto sigsegv;
4337
    sc = &frame->sctx;
4338

    
4339
    signal = current_exec_domain_sig(sig);
4340

    
4341
    err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
4342
    err |= __put_user(set->sig[0], &sc->oldmask);
4343
#if defined(TARGET_PPC64)
4344
    err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4345
#else
4346
    err |= __put_user(set->sig[1], &sc->_unused[3]);
4347
#endif
4348
    err |= __put_user(h2g(&frame->mctx), &sc->regs);
4349
    err |= __put_user(sig, &sc->signal);
4350

    
4351
    /* Save user regs.  */
4352
    err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4353

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

    
4358
    /* Turn off all fp exceptions.  */
4359
    env->fpscr = 0;
4360

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

    
4365
    if (err)
4366
        goto sigsegv;
4367

    
4368
    /* Set up registers for signal handler.  */
4369
    env->gpr[1] = newsp;
4370
    env->gpr[3] = signal;
4371
    env->gpr[4] = (target_ulong) h2g(sc);
4372
    env->nip = (target_ulong) ka->_sa_handler;
4373
    /* Signal handlers are entered in big-endian mode.  */
4374
    env->msr &= ~MSR_LE;
4375

    
4376
    unlock_user_struct(frame, frame_addr, 1);
4377
    return;
4378

    
4379
sigsegv:
4380
    unlock_user_struct(frame, frame_addr, 1);
4381
    if (logfile)
4382
        fprintf (logfile, "segfaulting from setup_frame\n");
4383
    force_sig(TARGET_SIGSEGV);
4384
}
4385

    
4386
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4387
                           target_siginfo_t *info,
4388
                           target_sigset_t *set, CPUPPCState *env)
4389
{
4390
    struct target_rt_sigframe *rt_sf;
4391
    struct target_mcontext *frame;
4392
    target_ulong rt_sf_addr, newsp = 0;
4393
    int i, err = 0;
4394
    int signal;
4395

    
4396
    rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4397
    if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4398
        goto sigsegv;
4399

    
4400
    signal = current_exec_domain_sig(sig);
4401

    
4402
    err |= copy_siginfo_to_user(&rt_sf->info, info);
4403

    
4404
    err |= __put_user(0, &rt_sf->uc.tuc_flags);
4405
    err |= __put_user(0, &rt_sf->uc.tuc_link);
4406
    err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4407
                      &rt_sf->uc.tuc_stack.ss_sp);
4408
    err |= __put_user(sas_ss_flags(env->gpr[1]),
4409
                      &rt_sf->uc.tuc_stack.ss_flags);
4410
    err |= __put_user(target_sigaltstack_used.ss_size,
4411
                      &rt_sf->uc.tuc_stack.ss_size);
4412
    err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4413
                      &rt_sf->uc.tuc_regs);
4414
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4415
        err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4416
    }
4417

    
4418
    frame = &rt_sf->uc.tuc_mcontext;
4419
    err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4420

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

    
4425
    /* Turn off all fp exceptions.  */
4426
    env->fpscr = 0;
4427

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

    
4432
    if (err)
4433
        goto sigsegv;
4434

    
4435
    /* Set up registers for signal handler.  */
4436
    env->gpr[1] = newsp;
4437
    env->gpr[3] = (target_ulong) signal;
4438
    env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4439
    env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4440
    env->gpr[6] = (target_ulong) h2g(rt_sf);
4441
    env->nip = (target_ulong) ka->_sa_handler;
4442
    /* Signal handlers are entered in big-endian mode.  */
4443
    env->msr &= ~MSR_LE;
4444

    
4445
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
4446
    return;
4447

    
4448
sigsegv:
4449
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
4450
    if (logfile)
4451
        fprintf (logfile, "segfaulting from setup_rt_frame\n");
4452
    force_sig(TARGET_SIGSEGV);
4453

    
4454
}
4455

    
4456
long do_sigreturn(CPUPPCState *env)
4457
{
4458
    struct target_sigcontext *sc = NULL;
4459
    struct target_mcontext *sr = NULL;
4460
    target_ulong sr_addr, sc_addr;
4461
    sigset_t blocked;
4462
    target_sigset_t set;
4463

    
4464
    sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4465
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4466
        goto sigsegv;
4467

    
4468
#if defined(TARGET_PPC64)
4469
    set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4470
#else
4471
    if(__get_user(set.sig[0], &sc->oldmask) ||
4472
       __get_user(set.sig[1], &sc->_unused[3]))
4473
       goto sigsegv;
4474
#endif
4475
    target_to_host_sigset_internal(&blocked, &set);
4476
    sigprocmask(SIG_SETMASK, &blocked, NULL);
4477

    
4478
    if (__get_user(sr_addr, &sc->regs))
4479
        goto sigsegv;
4480
    if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4481
        goto sigsegv;
4482
    if (restore_user_regs(env, sr, 1))
4483
        goto sigsegv;
4484

    
4485
    unlock_user_struct(sr, sr_addr, 1);
4486
    unlock_user_struct(sc, sc_addr, 1);
4487
    return -TARGET_QEMU_ESIGRETURN;
4488

    
4489
sigsegv:
4490
    unlock_user_struct(sr, sr_addr, 1);
4491
    unlock_user_struct(sc, sc_addr, 1);
4492
    if (logfile)
4493
        fprintf (logfile, "segfaulting from do_sigreturn\n");
4494
    force_sig(TARGET_SIGSEGV);
4495
    return 0;
4496
}
4497

    
4498
/* See arch/powerpc/kernel/signal_32.c.  */
4499
static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4500
{
4501
    struct target_mcontext *mcp;
4502
    target_ulong mcp_addr;
4503
    sigset_t blocked;
4504
    target_sigset_t set;
4505

    
4506
    if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4507
                       sizeof (set)))
4508
        return 1;
4509

    
4510
#if defined(TARGET_PPC64)
4511
    fprintf (stderr, "do_setcontext: not implemented\n");
4512
    return 0;
4513
#else
4514
    if (__get_user(mcp_addr, &ucp->tuc_regs))
4515
        return 1;
4516

    
4517
    if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4518
        return 1;
4519

    
4520
    target_to_host_sigset_internal(&blocked, &set);
4521
    sigprocmask(SIG_SETMASK, &blocked, NULL);
4522
    if (restore_user_regs(env, mcp, sig))
4523
        goto sigsegv;
4524

    
4525
    unlock_user_struct(mcp, mcp_addr, 1);
4526
    return 0;
4527

    
4528
sigsegv:
4529
    unlock_user_struct(mcp, mcp_addr, 1);
4530
    return 1;
4531
#endif
4532
}
4533

    
4534
long do_rt_sigreturn(CPUPPCState *env)
4535
{
4536
    struct target_rt_sigframe *rt_sf = NULL;
4537
    target_ulong rt_sf_addr;
4538

    
4539
    rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4540
    if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4541
        goto sigsegv;
4542

    
4543
    if (do_setcontext(&rt_sf->uc, env, 1))
4544
        goto sigsegv;
4545

    
4546
    do_sigaltstack(rt_sf_addr
4547
                   + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4548
                   0, env->gpr[1]);
4549

    
4550
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
4551
    return -TARGET_QEMU_ESIGRETURN;
4552

    
4553
sigsegv:
4554
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
4555
    if (logfile)
4556
        fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
4557
    force_sig(TARGET_SIGSEGV);
4558
    return 0;
4559
}
4560

    
4561
#elif defined(TARGET_M68K)
4562

    
4563
struct target_sigcontext {
4564
    abi_ulong  sc_mask;
4565
    abi_ulong  sc_usp;
4566
    abi_ulong  sc_d0;
4567
    abi_ulong  sc_d1;
4568
    abi_ulong  sc_a0;
4569
    abi_ulong  sc_a1;
4570
    unsigned short sc_sr;
4571
    abi_ulong  sc_pc;
4572
};
4573

    
4574
struct target_sigframe
4575
{
4576
    abi_ulong pretcode;
4577
    int sig;
4578
    int code;
4579
    abi_ulong psc;
4580
    char retcode[8];
4581
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
4582
    struct target_sigcontext sc;
4583
};
4584
 
4585
typedef int target_greg_t;
4586
#define TARGET_NGREG 18
4587
typedef target_greg_t target_gregset_t[TARGET_NGREG];
4588

    
4589
typedef struct target_fpregset {
4590
    int f_fpcntl[3];
4591
    int f_fpregs[8*3];
4592
} target_fpregset_t;
4593

    
4594
struct target_mcontext {
4595
    int version;
4596
    target_gregset_t gregs;
4597
    target_fpregset_t fpregs;
4598
};
4599

    
4600
#define TARGET_MCONTEXT_VERSION 2
4601

    
4602
struct target_ucontext {
4603
    abi_ulong tuc_flags;
4604
    abi_ulong tuc_link;
4605
    target_stack_t tuc_stack;
4606
    struct target_mcontext tuc_mcontext;
4607
    abi_long tuc_filler[80];
4608
    target_sigset_t tuc_sigmask;
4609
};
4610

    
4611
struct target_rt_sigframe
4612
{
4613
    abi_ulong pretcode;
4614
    int sig;
4615
    abi_ulong pinfo;
4616
    abi_ulong puc;
4617
    char retcode[8];
4618
    struct target_siginfo info;
4619
    struct target_ucontext uc;
4620
};
4621

    
4622
static int
4623
setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
4624
                 abi_ulong mask)
4625
{
4626
    int err = 0;
4627

    
4628
    err |= __put_user(mask, &sc->sc_mask);
4629
    err |= __put_user(env->aregs[7], &sc->sc_usp);
4630
    err |= __put_user(env->dregs[0], &sc->sc_d0);
4631
    err |= __put_user(env->dregs[1], &sc->sc_d1);
4632
    err |= __put_user(env->aregs[0], &sc->sc_a0);
4633
    err |= __put_user(env->aregs[1], &sc->sc_a1);
4634
    err |= __put_user(env->sr, &sc->sc_sr);
4635
    err |= __put_user(env->pc, &sc->sc_pc);
4636

    
4637
    return err;
4638
}
4639

    
4640
static int
4641
restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
4642
{
4643
    int err = 0;
4644
    int temp;
4645

    
4646
    err |= __get_user(env->aregs[7], &sc->sc_usp);
4647
    err |= __get_user(env->dregs[1], &sc->sc_d1);
4648
    err |= __get_user(env->aregs[0], &sc->sc_a0);
4649
    err |= __get_user(env->aregs[1], &sc->sc_a1);
4650
    err |= __get_user(env->pc, &sc->sc_pc);
4651
    err |= __get_user(temp, &sc->sc_sr);
4652
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
4653

    
4654
    *pd0 = tswapl(sc->sc_d0);
4655

    
4656
    return err;
4657
}
4658

    
4659
/*
4660
 * Determine which stack to use..
4661
 */
4662
static inline abi_ulong
4663
get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
4664
             size_t frame_size)
4665
{
4666
    unsigned long sp;
4667

    
4668
    sp = regs->aregs[7];
4669

    
4670
    /* This is the X/Open sanctioned signal stack switching.  */
4671
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4672
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4673
    }
4674

    
4675
    return ((sp - frame_size) & -8UL);
4676
}
4677

    
4678
static void setup_frame(int sig, struct target_sigaction *ka,
4679
                        target_sigset_t *set, CPUM68KState *env)
4680
{
4681
    struct target_sigframe *frame;
4682
    abi_ulong frame_addr;
4683
    abi_ulong retcode_addr;
4684
    abi_ulong sc_addr;
4685
    int err = 0;
4686
    int i;
4687

    
4688
    frame_addr = get_sigframe(ka, env, sizeof *frame);
4689
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4690
        goto give_sigsegv;
4691

    
4692
    err |= __put_user(sig, &frame->sig);
4693

    
4694
    sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4695
    err |= __put_user(sc_addr, &frame->psc);
4696

    
4697
    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4698
    if (err)
4699
        goto give_sigsegv;
4700

    
4701
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4702
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4703
            goto give_sigsegv;
4704
    }
4705

    
4706
    /* Set up to return from userspace.  */
4707

    
4708
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4709
    err |= __put_user(retcode_addr, &frame->pretcode);
4710

    
4711
    /* moveq #,d0; trap #0 */
4712

    
4713
    err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4714
                      (long *)(frame->retcode));
4715

    
4716
    if (err)
4717
        goto give_sigsegv;
4718

    
4719
    /* Set up to return from userspace */
4720

    
4721
    env->aregs[7] = frame_addr;
4722
    env->pc = ka->_sa_handler;
4723

    
4724
    unlock_user_struct(frame, frame_addr, 1);
4725
    return;
4726

    
4727
give_sigsegv:
4728
    unlock_user_struct(frame, frame_addr, 1);
4729
    force_sig(TARGET_SIGSEGV);
4730
}
4731

    
4732
static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
4733
                                           CPUM68KState *env)
4734
{
4735
    target_greg_t *gregs = uc->tuc_mcontext.gregs;
4736
    int err;
4737

    
4738
    err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
4739
    err |= __put_user(env->dregs[0], &gregs[0]);
4740
    err |= __put_user(env->dregs[1], &gregs[1]);
4741
    err |= __put_user(env->dregs[2], &gregs[2]);
4742
    err |= __put_user(env->dregs[3], &gregs[3]);
4743
    err |= __put_user(env->dregs[4], &gregs[4]);
4744
    err |= __put_user(env->dregs[5], &gregs[5]);
4745
    err |= __put_user(env->dregs[6], &gregs[6]);
4746
    err |= __put_user(env->dregs[7], &gregs[7]);
4747
    err |= __put_user(env->aregs[0], &gregs[8]);
4748
    err |= __put_user(env->aregs[1], &gregs[9]);
4749
    err |= __put_user(env->aregs[2], &gregs[10]);
4750
    err |= __put_user(env->aregs[3], &gregs[11]);
4751
    err |= __put_user(env->aregs[4], &gregs[12]);
4752
    err |= __put_user(env->aregs[5], &gregs[13]);
4753
    err |= __put_user(env->aregs[6], &gregs[14]);
4754
    err |= __put_user(env->aregs[7], &gregs[15]);
4755
    err |= __put_user(env->pc, &gregs[16]);
4756
    err |= __put_user(env->sr, &gregs[17]);
4757

    
4758
    return err;
4759
}
4760
 
4761
static inline int target_rt_restore_ucontext(CPUM68KState *env,
4762
                                             struct target_ucontext *uc,
4763
                                             int *pd0)
4764
{
4765
    int temp;
4766
    int err;
4767
    target_greg_t *gregs = uc->tuc_mcontext.gregs;
4768
    
4769
    err = __get_user(temp, &uc->tuc_mcontext.version);
4770
    if (temp != TARGET_MCONTEXT_VERSION)
4771
        goto badframe;
4772

    
4773
    /* restore passed registers */
4774
    err |= __get_user(env->dregs[0], &gregs[0]);
4775
    err |= __get_user(env->dregs[1], &gregs[1]);
4776
    err |= __get_user(env->dregs[2], &gregs[2]);
4777
    err |= __get_user(env->dregs[3], &gregs[3]);
4778
    err |= __get_user(env->dregs[4], &gregs[4]);
4779
    err |= __get_user(env->dregs[5], &gregs[5]);
4780
    err |= __get_user(env->dregs[6], &gregs[6]);
4781
    err |= __get_user(env->dregs[7], &gregs[7]);
4782
    err |= __get_user(env->aregs[0], &gregs[8]);
4783
    err |= __get_user(env->aregs[1], &gregs[9]);
4784
    err |= __get_user(env->aregs[2], &gregs[10]);
4785
    err |= __get_user(env->aregs[3], &gregs[11]);
4786
    err |= __get_user(env->aregs[4], &gregs[12]);
4787
    err |= __get_user(env->aregs[5], &gregs[13]);
4788
    err |= __get_user(env->aregs[6], &gregs[14]);
4789
    err |= __get_user(env->aregs[7], &gregs[15]);
4790
    err |= __get_user(env->pc, &gregs[16]);
4791
    err |= __get_user(temp, &gregs[17]);
4792
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
4793

    
4794
    *pd0 = env->dregs[0];
4795
    return err;
4796

    
4797
badframe:
4798
    return 1;
4799
}
4800

    
4801
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4802
                           target_siginfo_t *info,
4803
                           target_sigset_t *set, CPUM68KState *env)
4804
{
4805
    struct target_rt_sigframe *frame;
4806
    abi_ulong frame_addr;
4807
    abi_ulong retcode_addr;
4808
    abi_ulong info_addr;
4809
    abi_ulong uc_addr;
4810
    int err = 0;
4811
    int i;
4812

    
4813
    frame_addr = get_sigframe(ka, env, sizeof *frame);
4814
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4815
        goto give_sigsegv;
4816

    
4817
    err |= __put_user(sig, &frame->sig);
4818

    
4819
    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4820
    err |= __put_user(info_addr, &frame->pinfo);
4821

    
4822
    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4823
    err |= __put_user(uc_addr, &frame->puc);
4824

    
4825
    err |= copy_siginfo_to_user(&frame->info, info);
4826

    
4827
    /* Create the ucontext */
4828

    
4829
    err |= __put_user(0, &frame->uc.tuc_flags);
4830
    err |= __put_user(0, &frame->uc.tuc_link);
4831
    err |= __put_user(target_sigaltstack_used.ss_sp,
4832
                      &frame->uc.tuc_stack.ss_sp);
4833
    err |= __put_user(sas_ss_flags(env->aregs[7]),
4834
                      &frame->uc.tuc_stack.ss_flags);
4835
    err |= __put_user(target_sigaltstack_used.ss_size,
4836
                      &frame->uc.tuc_stack.ss_size);
4837
    err |= target_rt_setup_ucontext(&frame->uc, env);
4838

    
4839
    if (err)
4840
            goto give_sigsegv;
4841

    
4842
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4843
        if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
4844
            goto give_sigsegv;
4845
    }
4846

    
4847
    /* Set up to return from userspace.  */
4848

    
4849
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4850
    err |= __put_user(retcode_addr, &frame->pretcode);
4851

    
4852
    /* moveq #,d0; notb d0; trap #0 */
4853

    
4854
    err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
4855
                      (long *)(frame->retcode + 0));
4856
    err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
4857

    
4858
    if (err)
4859
        goto give_sigsegv;
4860

    
4861
    /* Set up to return from userspace */
4862

    
4863
    env->aregs[7] = frame_addr;
4864
    env->pc = ka->_sa_handler;
4865

    
4866
    unlock_user_struct(frame, frame_addr, 1);
4867
    return;
4868

    
4869
give_sigsegv:
4870
    unlock_user_struct(frame, frame_addr, 1);
4871
    force_sig(TARGET_SIGSEGV);
4872
}
4873

    
4874
long do_sigreturn(CPUM68KState *env)
4875
{
4876
    struct target_sigframe *frame;
4877
    abi_ulong frame_addr = env->aregs[7] - 4;
4878
    target_sigset_t target_set;
4879
    sigset_t set;
4880
    int d0, i;
4881

    
4882
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4883
        goto badframe;
4884

    
4885
    /* set blocked signals */
4886

    
4887
    if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4888
        goto badframe;
4889

    
4890
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4891
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4892
            goto badframe;
4893
    }
4894

    
4895
    target_to_host_sigset_internal(&set, &target_set);
4896
    sigprocmask(SIG_SETMASK, &set, NULL);
4897

    
4898
    /* restore registers */
4899

    
4900
    if (restore_sigcontext(env, &frame->sc, &d0))
4901
        goto badframe;
4902

    
4903
    unlock_user_struct(frame, frame_addr, 0);
4904
    return d0;
4905

    
4906
badframe:
4907
    unlock_user_struct(frame, frame_addr, 0);
4908
    force_sig(TARGET_SIGSEGV);
4909
    return 0;
4910
}
4911

    
4912
long do_rt_sigreturn(CPUM68KState *env)
4913
{
4914
    struct target_rt_sigframe *frame;
4915
    abi_ulong frame_addr = env->aregs[7] - 4;
4916
    target_sigset_t target_set;
4917
    sigset_t set;
4918
    int d0;
4919

    
4920
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4921
        goto badframe;
4922

    
4923
    target_to_host_sigset_internal(&set, &target_set);
4924
    sigprocmask(SIG_SETMASK, &set, NULL);
4925

    
4926
    /* restore registers */
4927

    
4928
    if (target_rt_restore_ucontext(env, &frame->uc, &d0))
4929
        goto badframe;
4930

    
4931
    if (do_sigaltstack(frame_addr +
4932
                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
4933
                       0, get_sp_from_cpustate(env)) == -EFAULT)
4934
        goto badframe;
4935

    
4936
    unlock_user_struct(frame, frame_addr, 0);
4937
    return d0;
4938

    
4939
badframe:
4940
    unlock_user_struct(frame, frame_addr, 0);
4941
    force_sig(TARGET_SIGSEGV);
4942
    return 0;
4943
}
4944

    
4945
#elif defined(TARGET_ALPHA)
4946

    
4947
struct target_sigcontext {
4948
    abi_long sc_onstack;
4949
    abi_long sc_mask;
4950
    abi_long sc_pc;
4951
    abi_long sc_ps;
4952
    abi_long sc_regs[32];
4953
    abi_long sc_ownedfp;
4954
    abi_long sc_fpregs[32];
4955
    abi_ulong sc_fpcr;
4956
    abi_ulong sc_fp_control;
4957
    abi_ulong sc_reserved1;
4958
    abi_ulong sc_reserved2;
4959
    abi_ulong sc_ssize;
4960
    abi_ulong sc_sbase;
4961
    abi_ulong sc_traparg_a0;
4962
    abi_ulong sc_traparg_a1;
4963
    abi_ulong sc_traparg_a2;
4964
    abi_ulong sc_fp_trap_pc;
4965
    abi_ulong sc_fp_trigger_sum;
4966
    abi_ulong sc_fp_trigger_inst;
4967
};
4968

    
4969
struct target_ucontext {
4970
    abi_ulong tuc_flags;
4971
    abi_ulong tuc_link;
4972
    abi_ulong tuc_osf_sigmask;
4973
    target_stack_t tuc_stack;
4974
    struct target_sigcontext tuc_mcontext;
4975
    target_sigset_t tuc_sigmask;
4976
};
4977

    
4978
struct target_sigframe {
4979
    struct target_sigcontext sc;
4980
    unsigned int retcode[3];
4981
};
4982

    
4983
struct target_rt_sigframe {
4984
    target_siginfo_t info;
4985
    struct target_ucontext uc;
4986
    unsigned int retcode[3];
4987
};
4988

    
4989
#define INSN_MOV_R30_R16        0x47fe0410
4990
#define INSN_LDI_R0             0x201f0000
4991
#define INSN_CALLSYS            0x00000083
4992

    
4993
static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
4994
                            abi_ulong frame_addr, target_sigset_t *set)
4995
{
4996
    int i, err = 0;
4997

    
4998
    err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4999
    err |= __put_user(set->sig[0], &sc->sc_mask);
5000
    err |= __put_user(env->pc, &sc->sc_pc);
5001
    err |= __put_user(8, &sc->sc_ps);
5002

    
5003
    for (i = 0; i < 31; ++i) {
5004
        err |= __put_user(env->ir[i], &sc->sc_regs[i]);
5005
    }
5006
    err |= __put_user(0, &sc->sc_regs[31]);
5007

    
5008
    for (i = 0; i < 31; ++i) {
5009
        err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
5010
    }
5011
    err |= __put_user(0, &sc->sc_fpregs[31]);
5012
    err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5013

    
5014
    err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5015
    err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5016
    err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5017

    
5018
    return err;
5019
}
5020

    
5021
static int restore_sigcontext(CPUAlphaState *env,
5022
                              struct target_sigcontext *sc)
5023
{
5024
    uint64_t fpcr;
5025
    int i, err = 0;
5026

    
5027
    err |= __get_user(env->pc, &sc->sc_pc);
5028

    
5029
    for (i = 0; i < 31; ++i) {
5030
        err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5031
    }
5032
    for (i = 0; i < 31; ++i) {
5033
        err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5034
    }
5035

    
5036
    err |= __get_user(fpcr, &sc->sc_fpcr);
5037
    cpu_alpha_store_fpcr(env, fpcr);
5038

    
5039
    return err;
5040
}
5041

    
5042
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5043
                                     CPUAlphaState *env,
5044
                                     unsigned long framesize)
5045
{
5046
    abi_ulong sp = env->ir[IR_SP];
5047

    
5048
    /* This is the X/Open sanctioned signal stack switching.  */
5049
    if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5050
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5051
    }
5052
    return (sp - framesize) & -32;
5053
}
5054

    
5055
static void setup_frame(int sig, struct target_sigaction *ka,
5056
                        target_sigset_t *set, CPUAlphaState *env)
5057
{
5058
    abi_ulong frame_addr, r26;
5059
    struct target_sigframe *frame;
5060
    int err = 0;
5061

    
5062
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
5063
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5064
        goto give_sigsegv;
5065
    }
5066

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

    
5069
    if (ka->sa_restorer) {
5070
        r26 = ka->sa_restorer;
5071
    } else {
5072
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5073
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5074
                          &frame->retcode[1]);
5075
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5076
        /* imb() */
5077
        r26 = frame_addr;
5078
    }
5079

    
5080
    unlock_user_struct(frame, frame_addr, 1);
5081

    
5082
    if (err) {
5083
    give_sigsegv:
5084
        if (sig == TARGET_SIGSEGV) {
5085
            ka->_sa_handler = TARGET_SIG_DFL;
5086
        }
5087
        force_sig(TARGET_SIGSEGV);
5088
    }
5089

    
5090
    env->ir[IR_RA] = r26;
5091
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
5092
    env->ir[IR_A0] = sig;
5093
    env->ir[IR_A1] = 0;
5094
    env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5095
    env->ir[IR_SP] = frame_addr;
5096
}
5097

    
5098
static void setup_rt_frame(int sig, struct target_sigaction *ka,
5099
                           target_siginfo_t *info,
5100
                           target_sigset_t *set, CPUAlphaState *env)
5101
{
5102
    abi_ulong frame_addr, r26;
5103
    struct target_rt_sigframe *frame;
5104
    int i, err = 0;
5105

    
5106
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
5107
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5108
        goto give_sigsegv;
5109
    }
5110

    
5111
    err |= copy_siginfo_to_user(&frame->info, info);
5112

    
5113
    err |= __put_user(0, &frame->uc.tuc_flags);
5114
    err |= __put_user(0, &frame->uc.tuc_link);
5115
    err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5116
    err |= __put_user(target_sigaltstack_used.ss_sp,
5117
                      &frame->uc.tuc_stack.ss_sp);
5118
    err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
5119
                      &frame->uc.tuc_stack.ss_flags);
5120
    err |= __put_user(target_sigaltstack_used.ss_size,
5121
                      &frame->uc.tuc_stack.ss_size);
5122
    err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5123
    for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5124
        err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5125
    }
5126

    
5127
    if (ka->sa_restorer) {
5128
        r26 = ka->sa_restorer;
5129
    } else {
5130
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5131
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5132
                          &frame->retcode[1]);
5133
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5134
        /* imb(); */
5135
        r26 = frame_addr;
5136
    }
5137

    
5138
    if (err) {
5139
    give_sigsegv:
5140
       if (sig == TARGET_SIGSEGV) {
5141
            ka->_sa_handler = TARGET_SIG_DFL;
5142
        }
5143
        force_sig(TARGET_SIGSEGV);
5144
    }
5145

    
5146
    env->ir[IR_RA] = r26;
5147
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
5148
    env->ir[IR_A0] = sig;
5149
    env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5150
    env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5151
    env->ir[IR_SP] = frame_addr;
5152
}
5153

    
5154
long do_sigreturn(CPUAlphaState *env)
5155
{
5156
    struct target_sigcontext *sc;
5157
    abi_ulong sc_addr = env->ir[IR_A0];
5158
    target_sigset_t target_set;
5159
    sigset_t set;
5160

    
5161
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5162
        goto badframe;
5163
    }
5164

    
5165
    target_sigemptyset(&target_set);
5166
    if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5167
        goto badframe;
5168
    }
5169

    
5170
    target_to_host_sigset_internal(&set, &target_set);
5171
    sigprocmask(SIG_SETMASK, &set, NULL);
5172

    
5173
    if (restore_sigcontext(env, sc)) {
5174
        goto badframe;
5175
    }
5176
    unlock_user_struct(sc, sc_addr, 0);
5177
    return env->ir[IR_V0];
5178

    
5179
 badframe:
5180
    unlock_user_struct(sc, sc_addr, 0);
5181
    force_sig(TARGET_SIGSEGV);
5182
}
5183

    
5184
long do_rt_sigreturn(CPUAlphaState *env)
5185
{
5186
    abi_ulong frame_addr = env->ir[IR_A0];
5187
    struct target_rt_sigframe *frame;
5188
    sigset_t set;
5189

    
5190
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5191
        goto badframe;
5192
    }
5193
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5194
    sigprocmask(SIG_SETMASK, &set, NULL);
5195

    
5196
    if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5197
        goto badframe;
5198
    }
5199
    if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5200
                                             uc.tuc_stack),
5201
                       0, env->ir[IR_SP]) == -EFAULT) {
5202
        goto badframe;
5203
    }
5204

    
5205
    unlock_user_struct(frame, frame_addr, 0);
5206
    return env->ir[IR_V0];
5207

    
5208

    
5209
 badframe:
5210
    unlock_user_struct(frame, frame_addr, 0);
5211
    force_sig(TARGET_SIGSEGV);
5212
}
5213

    
5214
#else
5215

    
5216
static void setup_frame(int sig, struct target_sigaction *ka,
5217
                        target_sigset_t *set, CPUArchState *env)
5218
{
5219
    fprintf(stderr, "setup_frame: not implemented\n");
5220
}
5221

    
5222
static void setup_rt_frame(int sig, struct target_sigaction *ka,
5223
                           target_siginfo_t *info,
5224
                           target_sigset_t *set, CPUArchState *env)
5225
{
5226
    fprintf(stderr, "setup_rt_frame: not implemented\n");
5227
}
5228

    
5229
long do_sigreturn(CPUArchState *env)
5230
{
5231
    fprintf(stderr, "do_sigreturn: not implemented\n");
5232
    return -TARGET_ENOSYS;
5233
}
5234

    
5235
long do_rt_sigreturn(CPUArchState *env)
5236
{
5237
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5238
    return -TARGET_ENOSYS;
5239
}
5240

    
5241
#endif
5242

    
5243
void process_pending_signals(CPUArchState *cpu_env)
5244
{
5245
    int sig;
5246
    abi_ulong handler;
5247
    sigset_t set, old_set;
5248
    target_sigset_t target_old_set;
5249
    struct emulated_sigtable *k;
5250
    struct target_sigaction *sa;
5251
    struct sigqueue *q;
5252
    TaskState *ts = cpu_env->opaque;
5253

    
5254
    if (!ts->signal_pending)
5255
        return;
5256

    
5257
    /* FIXME: This is not threadsafe.  */
5258
    k = ts->sigtab;
5259
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
5260
        if (k->pending)
5261
            goto handle_signal;
5262
        k++;
5263
    }
5264
    /* if no signal is pending, just return */
5265
    ts->signal_pending = 0;
5266
    return;
5267

    
5268
 handle_signal:
5269
#ifdef DEBUG_SIGNAL
5270
    fprintf(stderr, "qemu: process signal %d\n", sig);
5271
#endif
5272
    /* dequeue signal */
5273
    q = k->first;
5274
    k->first = q->next;
5275
    if (!k->first)
5276
        k->pending = 0;
5277

    
5278
    sig = gdb_handlesig (cpu_env, sig);
5279
    if (!sig) {
5280
        sa = NULL;
5281
        handler = TARGET_SIG_IGN;
5282
    } else {
5283
        sa = &sigact_table[sig - 1];
5284
        handler = sa->_sa_handler;
5285
    }
5286

    
5287
    if (handler == TARGET_SIG_DFL) {
5288
        /* default handler : ignore some signal. The other are job control or fatal */
5289
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5290
            kill(getpid(),SIGSTOP);
5291
        } else if (sig != TARGET_SIGCHLD &&
5292
                   sig != TARGET_SIGURG &&
5293
                   sig != TARGET_SIGWINCH &&
5294
                   sig != TARGET_SIGCONT) {
5295
            force_sig(sig);
5296
        }
5297
    } else if (handler == TARGET_SIG_IGN) {
5298
        /* ignore sig */
5299
    } else if (handler == TARGET_SIG_ERR) {
5300
        force_sig(sig);
5301
    } else {
5302
        /* compute the blocked signals during the handler execution */
5303
        target_to_host_sigset(&set, &sa->sa_mask);
5304
        /* SA_NODEFER indicates that the current signal should not be
5305
           blocked during the handler */
5306
        if (!(sa->sa_flags & TARGET_SA_NODEFER))
5307
            sigaddset(&set, target_to_host_signal(sig));
5308

    
5309
        /* block signals in the handler using Linux */
5310
        sigprocmask(SIG_BLOCK, &set, &old_set);
5311
        /* save the previous blocked signal state to restore it at the
5312
           end of the signal execution (see do_sigreturn) */
5313
        host_to_target_sigset_internal(&target_old_set, &old_set);
5314

    
5315
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
5316
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
5317
        {
5318
            CPUX86State *env = cpu_env;
5319
            if (env->eflags & VM_MASK)
5320
                save_v86_state(env);
5321
        }
5322
#endif
5323
        /* prepare the stack frame of the virtual CPU */
5324
        if (sa->sa_flags & TARGET_SA_SIGINFO)
5325
            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5326
        else
5327
            setup_frame(sig, sa, &target_old_set, cpu_env);
5328
        if (sa->sa_flags & TARGET_SA_RESETHAND)
5329
            sa->_sa_handler = TARGET_SIG_DFL;
5330
    }
5331
    if (q != &k->info)
5332
        free_sigqueue(cpu_env, q);
5333
}