~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/ubuntu/Don-t-block-SIGSEGV-at-more-places.patch/linux-user/signal.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn, dann frazier, Serge Hallyn
  • Date: 2014-03-06 16:15:50 UTC
  • Revision ID: package-import@ubuntu.com-20140306161550-83y1d9kr1t4t19tz
Tags: 1.7.0+dfsg-3ubuntu5
[ dann frazier ]
* Add patches from the susematz tree to avoid intermittent segfaults:
   - ubuntu/signal-added-a-wrapper-for-sigprocmask-function.patch
   - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
   - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch

[ Serge Hallyn ]
* Modify do_sigprocmask to only change behavior for aarch64.
  (LP: #1285363)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 < 0 || 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 < 0 || 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 = host_to_target_signal(info->si_signo);
 
206
    tinfo->si_signo = sig;
 
207
    tinfo->si_errno = 0;
 
208
    tinfo->si_code = info->si_code;
 
209
 
 
210
    if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
 
211
        || sig == TARGET_SIGBUS || sig == TARGET_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 == TARGET_SIGIO) {
 
216
        tinfo->_sifields._sigpoll._band = info->si_band;
 
217
        tinfo->_sifields._sigpoll._fd = info->si_fd;
 
218
    } else if (sig == TARGET_SIGCHLD) {
 
219
        tinfo->_sifields._sigchld._pid = info->si_pid;
 
220
        tinfo->_sifields._sigchld._uid = info->si_uid;
 
221
        tinfo->_sifields._sigchld._status
 
222
            = host_to_target_waitstatus(info->si_status);
 
223
        tinfo->_sifields._sigchld._utime = info->si_utime;
 
224
        tinfo->_sifields._sigchld._stime = info->si_stime;
 
225
    } else if (sig >= TARGET_SIGRTMIN) {
 
226
        tinfo->_sifields._rt._pid = info->si_pid;
 
227
        tinfo->_sifields._rt._uid = info->si_uid;
 
228
        /* XXX: potential problem if 64 bit */
 
229
        tinfo->_sifields._rt._sigval.sival_ptr
 
230
            = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
 
231
    }
 
232
}
 
233
 
 
234
static void tswap_siginfo(target_siginfo_t *tinfo,
 
235
                          const target_siginfo_t *info)
 
236
{
 
237
    int sig = info->si_signo;
 
238
    tinfo->si_signo = tswap32(sig);
 
239
    tinfo->si_errno = tswap32(info->si_errno);
 
240
    tinfo->si_code = tswap32(info->si_code);
 
241
 
 
242
    if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
 
243
        || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
 
244
        tinfo->_sifields._sigfault._addr
 
245
            = tswapal(info->_sifields._sigfault._addr);
 
246
    } else if (sig == TARGET_SIGIO) {
 
247
        tinfo->_sifields._sigpoll._band
 
248
            = tswap32(info->_sifields._sigpoll._band);
 
249
        tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
 
250
    } else if (sig == TARGET_SIGCHLD) {
 
251
        tinfo->_sifields._sigchld._pid
 
252
            = tswap32(info->_sifields._sigchld._pid);
 
253
        tinfo->_sifields._sigchld._uid
 
254
            = tswap32(info->_sifields._sigchld._uid);
 
255
        tinfo->_sifields._sigchld._status
 
256
            = tswap32(info->_sifields._sigchld._status);
 
257
        tinfo->_sifields._sigchld._utime
 
258
            = tswapal(info->_sifields._sigchld._utime);
 
259
        tinfo->_sifields._sigchld._stime
 
260
            = tswapal(info->_sifields._sigchld._stime);
 
261
    } else if (sig >= TARGET_SIGRTMIN) {
 
262
        tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
 
263
        tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
 
264
        tinfo->_sifields._rt._sigval.sival_ptr
 
265
            = tswapal(info->_sifields._rt._sigval.sival_ptr);
 
266
    }
 
267
}
 
268
 
 
269
 
 
270
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
 
271
{
 
272
    host_to_target_siginfo_noswap(tinfo, info);
 
273
    tswap_siginfo(tinfo, tinfo);
 
274
}
 
275
 
 
276
/* XXX: we support only POSIX RT signals are used. */
 
277
/* XXX: find a solution for 64 bit (additional malloced data is needed) */
 
278
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
 
279
{
 
280
    info->si_signo = tswap32(tinfo->si_signo);
 
281
    info->si_errno = tswap32(tinfo->si_errno);
 
282
    info->si_code = tswap32(tinfo->si_code);
 
283
    info->si_pid = tswap32(tinfo->_sifields._rt._pid);
 
284
    info->si_uid = tswap32(tinfo->_sifields._rt._uid);
 
285
    info->si_value.sival_ptr =
 
286
            (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
 
287
}
 
288
 
 
289
static int fatal_signal (int sig)
 
290
{
 
291
    switch (sig) {
 
292
    case TARGET_SIGCHLD:
 
293
    case TARGET_SIGURG:
 
294
    case TARGET_SIGWINCH:
 
295
        /* Ignored by default.  */
 
296
        return 0;
 
297
    case TARGET_SIGCONT:
 
298
    case TARGET_SIGSTOP:
 
299
    case TARGET_SIGTSTP:
 
300
    case TARGET_SIGTTIN:
 
301
    case TARGET_SIGTTOU:
 
302
        /* Job control signals.  */
 
303
        return 0;
 
304
    default:
 
305
        return 1;
 
306
    }
 
307
}
 
308
 
 
309
/* returns 1 if given signal should dump core if not handled */
 
310
static int core_dump_signal(int sig)
 
311
{
 
312
    switch (sig) {
 
313
    case TARGET_SIGABRT:
 
314
    case TARGET_SIGFPE:
 
315
    case TARGET_SIGILL:
 
316
    case TARGET_SIGQUIT:
 
317
    case TARGET_SIGSEGV:
 
318
    case TARGET_SIGTRAP:
 
319
    case TARGET_SIGBUS:
 
320
        return (1);
 
321
    default:
 
322
        return (0);
 
323
    }
 
324
}
 
325
 
 
326
void signal_init(void)
 
327
{
 
328
    struct sigaction act;
 
329
    struct sigaction oact;
 
330
    int i, j;
 
331
    int host_sig;
 
332
 
 
333
    /* generate signal conversion tables */
 
334
    for(i = 1; i < _NSIG; i++) {
 
335
        if (host_to_target_signal_table[i] == 0)
 
336
            host_to_target_signal_table[i] = i;
 
337
    }
 
338
    for(i = 1; i < _NSIG; i++) {
 
339
        j = host_to_target_signal_table[i];
 
340
        target_to_host_signal_table[j] = i;
 
341
    }
 
342
 
 
343
    /* set all host signal handlers. ALL signals are blocked during
 
344
       the handlers to serialize them. */
 
345
    memset(sigact_table, 0, sizeof(sigact_table));
 
346
 
 
347
    sigfillset(&act.sa_mask);
 
348
    act.sa_flags = SA_SIGINFO;
 
349
    act.sa_sigaction = host_signal_handler;
 
350
    for(i = 1; i <= TARGET_NSIG; i++) {
 
351
        host_sig = target_to_host_signal(i);
 
352
        sigaction(host_sig, NULL, &oact);
 
353
        if (oact.sa_sigaction == (void *)SIG_IGN) {
 
354
            sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
 
355
        } else if (oact.sa_sigaction == (void *)SIG_DFL) {
 
356
            sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
 
357
        }
 
358
        /* If there's already a handler installed then something has
 
359
           gone horribly wrong, so don't even try to handle that case.  */
 
360
        /* Install some handlers for our own use.  We need at least
 
361
           SIGSEGV and SIGBUS, to detect exceptions.  We can not just
 
362
           trap all signals because it affects syscall interrupt
 
363
           behavior.  But do trap all default-fatal signals.  */
 
364
        if (fatal_signal (i))
 
365
            sigaction(host_sig, &act, NULL);
 
366
    }
 
367
}
 
368
 
 
369
/* signal queue handling */
 
370
 
 
371
static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
 
372
{
 
373
    TaskState *ts = env->opaque;
 
374
    struct sigqueue *q = ts->first_free;
 
375
    if (!q)
 
376
        return NULL;
 
377
    ts->first_free = q->next;
 
378
    return q;
 
379
}
 
380
 
 
381
static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
 
382
{
 
383
    TaskState *ts = env->opaque;
 
384
    q->next = ts->first_free;
 
385
    ts->first_free = q;
 
386
}
 
387
 
 
388
/* abort execution with signal */
 
389
static void QEMU_NORETURN force_sig(int target_sig)
 
390
{
 
391
    CPUArchState *env = thread_cpu->env_ptr;
 
392
    TaskState *ts = (TaskState *)env->opaque;
 
393
    int host_sig, core_dumped = 0;
 
394
    struct sigaction act;
 
395
    host_sig = target_to_host_signal(target_sig);
 
396
    gdb_signalled(env, target_sig);
 
397
 
 
398
    /* dump core if supported by target binary format */
 
399
    if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
 
400
        stop_all_tasks();
 
401
        core_dumped =
 
402
            ((*ts->bprm->core_dump)(target_sig, env) == 0);
 
403
    }
 
404
    if (core_dumped) {
 
405
        /* we already dumped the core of target process, we don't want
 
406
         * a coredump of qemu itself */
 
407
        struct rlimit nodump;
 
408
        getrlimit(RLIMIT_CORE, &nodump);
 
409
        nodump.rlim_cur=0;
 
410
        setrlimit(RLIMIT_CORE, &nodump);
 
411
        (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
 
412
            target_sig, strsignal(host_sig), "core dumped" );
 
413
    }
 
414
 
 
415
    /* The proper exit code for dying from an uncaught signal is
 
416
     * -<signal>.  The kernel doesn't allow exit() or _exit() to pass
 
417
     * a negative value.  To get the proper exit code we need to
 
418
     * actually die from an uncaught signal.  Here the default signal
 
419
     * handler is installed, we send ourself a signal and we wait for
 
420
     * it to arrive. */
 
421
    sigfillset(&act.sa_mask);
 
422
    act.sa_handler = SIG_DFL;
 
423
    sigaction(host_sig, &act, NULL);
 
424
 
 
425
    /* For some reason raise(host_sig) doesn't send the signal when
 
426
     * statically linked on x86-64. */
 
427
    kill(getpid(), host_sig);
 
428
 
 
429
    /* Make sure the signal isn't masked (just reuse the mask inside
 
430
    of act) */
 
431
    sigdelset(&act.sa_mask, host_sig);
 
432
    sigsuspend(&act.sa_mask);
 
433
 
 
434
    /* unreachable */
 
435
    abort();
 
436
}
 
437
 
 
438
/* queue a signal so that it will be send to the virtual CPU as soon
 
439
   as possible */
 
440
int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
 
441
{
 
442
    TaskState *ts = env->opaque;
 
443
    struct emulated_sigtable *k;
 
444
    struct sigqueue *q, **pq;
 
445
    abi_ulong handler;
 
446
    int queue;
 
447
 
 
448
#if defined(DEBUG_SIGNAL)
 
449
    fprintf(stderr, "queue_signal: sig=%d\n",
 
450
            sig);
 
451
#endif
 
452
    k = &ts->sigtab[sig - 1];
 
453
    queue = gdb_queuesig ();
 
454
    handler = sigact_table[sig - 1]._sa_handler;
 
455
    if (!queue && handler == TARGET_SIG_DFL) {
 
456
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
 
457
            kill(getpid(),SIGSTOP);
 
458
            return 0;
 
459
        } else
 
460
        /* default handler : ignore some signal. The other are fatal */
 
461
        if (sig != TARGET_SIGCHLD &&
 
462
            sig != TARGET_SIGURG &&
 
463
            sig != TARGET_SIGWINCH &&
 
464
            sig != TARGET_SIGCONT) {
 
465
            force_sig(sig);
 
466
        } else {
 
467
            return 0; /* indicate ignored */
 
468
        }
 
469
    } else if (!queue && handler == TARGET_SIG_IGN) {
 
470
        /* ignore signal */
 
471
        return 0;
 
472
    } else if (!queue && handler == TARGET_SIG_ERR) {
 
473
        force_sig(sig);
 
474
    } else {
 
475
        pq = &k->first;
 
476
        if (sig < TARGET_SIGRTMIN) {
 
477
            /* if non real time signal, we queue exactly one signal */
 
478
            if (!k->pending)
 
479
                q = &k->info;
 
480
            else
 
481
                return 0;
 
482
        } else {
 
483
            if (!k->pending) {
 
484
                /* first signal */
 
485
                q = &k->info;
 
486
            } else {
 
487
                q = alloc_sigqueue(env);
 
488
                if (!q)
 
489
                    return -EAGAIN;
 
490
                while (*pq != NULL)
 
491
                    pq = &(*pq)->next;
 
492
            }
 
493
        }
 
494
        *pq = q;
 
495
        q->info = *info;
 
496
        q->next = NULL;
 
497
        k->pending = 1;
 
498
        /* signal that a new signal is pending */
 
499
        ts->signal_pending = 1;
 
500
        return 1; /* indicates that the signal was queued */
 
501
    }
 
502
}
 
503
 
 
504
static void host_signal_handler(int host_signum, siginfo_t *info,
 
505
                                void *puc)
 
506
{
 
507
    CPUArchState *env = thread_cpu->env_ptr;
 
508
    int sig;
 
509
    target_siginfo_t tinfo;
 
510
 
 
511
    /* the CPU emulator uses some host signals to detect exceptions,
 
512
       we forward to it some signals */
 
513
    if ((host_signum == SIGSEGV || host_signum == SIGBUS)
 
514
        && info->si_code > 0) {
 
515
        if (cpu_signal_handler(host_signum, info, puc))
 
516
            return;
 
517
    }
 
518
 
 
519
    /* get target signal number */
 
520
    sig = host_to_target_signal(host_signum);
 
521
    if (sig < 1 || sig > TARGET_NSIG)
 
522
        return;
 
523
#if defined(DEBUG_SIGNAL)
 
524
    fprintf(stderr, "qemu: got signal %d\n", sig);
 
525
#endif
 
526
    host_to_target_siginfo_noswap(&tinfo, info);
 
527
    if (queue_signal(env, sig, &tinfo) == 1) {
 
528
        /* interrupt the virtual CPU as soon as possible */
 
529
        cpu_exit(thread_cpu);
 
530
    }
 
531
}
 
532
 
 
533
/* do_sigaltstack() returns target values and errnos. */
 
534
/* compare linux/kernel/signal.c:do_sigaltstack() */
 
535
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
 
536
{
 
537
    int ret;
 
538
    struct target_sigaltstack oss;
 
539
 
 
540
    /* XXX: test errors */
 
541
    if(uoss_addr)
 
542
    {
 
543
        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
 
544
        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
 
545
        __put_user(sas_ss_flags(sp), &oss.ss_flags);
 
546
    }
 
547
 
 
548
    if(uss_addr)
 
549
    {
 
550
        struct target_sigaltstack *uss;
 
551
        struct target_sigaltstack ss;
 
552
 
 
553
        ret = -TARGET_EFAULT;
 
554
        if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
 
555
            || __get_user(ss.ss_sp, &uss->ss_sp)
 
556
            || __get_user(ss.ss_size, &uss->ss_size)
 
557
            || __get_user(ss.ss_flags, &uss->ss_flags))
 
558
            goto out;
 
559
        unlock_user_struct(uss, uss_addr, 0);
 
560
 
 
561
        ret = -TARGET_EPERM;
 
562
        if (on_sig_stack(sp))
 
563
            goto out;
 
564
 
 
565
        ret = -TARGET_EINVAL;
 
566
        if (ss.ss_flags != TARGET_SS_DISABLE
 
567
            && ss.ss_flags != TARGET_SS_ONSTACK
 
568
            && ss.ss_flags != 0)
 
569
            goto out;
 
570
 
 
571
        if (ss.ss_flags == TARGET_SS_DISABLE) {
 
572
            ss.ss_size = 0;
 
573
            ss.ss_sp = 0;
 
574
        } else {
 
575
            ret = -TARGET_ENOMEM;
 
576
            if (ss.ss_size < MINSIGSTKSZ)
 
577
                goto out;
 
578
        }
 
579
 
 
580
        target_sigaltstack_used.ss_sp = ss.ss_sp;
 
581
        target_sigaltstack_used.ss_size = ss.ss_size;
 
582
    }
 
583
 
 
584
    if (uoss_addr) {
 
585
        ret = -TARGET_EFAULT;
 
586
        if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
 
587
            goto out;
 
588
    }
 
589
 
 
590
    ret = 0;
 
591
out:
 
592
    return ret;
 
593
}
 
594
 
 
595
/* do_sigaction() return host values and errnos */
 
596
int do_sigaction(int sig, const struct target_sigaction *act,
 
597
                 struct target_sigaction *oact)
 
598
{
 
599
    struct target_sigaction *k;
 
600
    struct sigaction act1;
 
601
    int host_sig;
 
602
    int ret = 0;
 
603
 
 
604
    if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
 
605
        return -EINVAL;
 
606
    k = &sigact_table[sig - 1];
 
607
#if defined(DEBUG_SIGNAL)
 
608
    fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
 
609
            sig, act, oact);
 
610
#endif
 
611
    if (oact) {
 
612
        __put_user(k->_sa_handler, &oact->_sa_handler);
 
613
        __put_user(k->sa_flags, &oact->sa_flags);
 
614
#if !defined(TARGET_MIPS)
 
615
        __put_user(k->sa_restorer, &oact->sa_restorer);
 
616
#endif
 
617
        /* Not swapped.  */
 
618
        oact->sa_mask = k->sa_mask;
 
619
    }
 
620
    if (act) {
 
621
        /* FIXME: This is not threadsafe.  */
 
622
        __get_user(k->_sa_handler, &act->_sa_handler);
 
623
        __get_user(k->sa_flags, &act->sa_flags);
 
624
#if !defined(TARGET_MIPS)
 
625
        __get_user(k->sa_restorer, &act->sa_restorer);
 
626
#endif
 
627
        /* To be swapped in target_to_host_sigset.  */
 
628
        k->sa_mask = act->sa_mask;
 
629
 
 
630
        /* we update the host linux signal state */
 
631
        host_sig = target_to_host_signal(sig);
 
632
        if (host_sig != SIGSEGV && host_sig != SIGBUS) {
 
633
            sigfillset(&act1.sa_mask);
 
634
            act1.sa_flags = SA_SIGINFO;
 
635
            if (k->sa_flags & TARGET_SA_RESTART)
 
636
                act1.sa_flags |= SA_RESTART;
 
637
            /* NOTE: it is important to update the host kernel signal
 
638
               ignore state to avoid getting unexpected interrupted
 
639
               syscalls */
 
640
            if (k->_sa_handler == TARGET_SIG_IGN) {
 
641
                act1.sa_sigaction = (void *)SIG_IGN;
 
642
            } else if (k->_sa_handler == TARGET_SIG_DFL) {
 
643
                if (fatal_signal (sig))
 
644
                    act1.sa_sigaction = host_signal_handler;
 
645
                else
 
646
                    act1.sa_sigaction = (void *)SIG_DFL;
 
647
            } else {
 
648
                act1.sa_sigaction = host_signal_handler;
 
649
            }
 
650
            ret = sigaction(host_sig, &act1, NULL);
 
651
        }
 
652
    }
 
653
    return ret;
 
654
}
 
655
 
 
656
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
 
657
                                       const target_siginfo_t *info)
 
658
{
 
659
    tswap_siginfo(tinfo, info);
 
660
    return 0;
 
661
}
 
662
 
 
663
static inline int current_exec_domain_sig(int sig)
 
664
{
 
665
    return /* current->exec_domain && current->exec_domain->signal_invmap
 
666
              && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
 
667
}
 
668
 
 
669
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
 
670
 
 
671
/* from the Linux kernel */
 
672
 
 
673
struct target_fpreg {
 
674
        uint16_t significand[4];
 
675
        uint16_t exponent;
 
676
};
 
677
 
 
678
struct target_fpxreg {
 
679
        uint16_t significand[4];
 
680
        uint16_t exponent;
 
681
        uint16_t padding[3];
 
682
};
 
683
 
 
684
struct target_xmmreg {
 
685
        abi_ulong element[4];
 
686
};
 
687
 
 
688
struct target_fpstate {
 
689
        /* Regular FPU environment */
 
690
        abi_ulong       cw;
 
691
        abi_ulong       sw;
 
692
        abi_ulong       tag;
 
693
        abi_ulong       ipoff;
 
694
        abi_ulong       cssel;
 
695
        abi_ulong       dataoff;
 
696
        abi_ulong       datasel;
 
697
        struct target_fpreg     _st[8];
 
698
        uint16_t        status;
 
699
        uint16_t        magic;          /* 0xffff = regular FPU data only */
 
700
 
 
701
        /* FXSR FPU environment */
 
702
        abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
 
703
        abi_ulong       mxcsr;
 
704
        abi_ulong       reserved;
 
705
        struct target_fpxreg    _fxsr_st[8];    /* FXSR FPU reg data is ignored */
 
706
        struct target_xmmreg    _xmm[8];
 
707
        abi_ulong       padding[56];
 
708
};
 
709
 
 
710
#define X86_FXSR_MAGIC          0x0000
 
711
 
 
712
struct target_sigcontext {
 
713
        uint16_t gs, __gsh;
 
714
        uint16_t fs, __fsh;
 
715
        uint16_t es, __esh;
 
716
        uint16_t ds, __dsh;
 
717
        abi_ulong edi;
 
718
        abi_ulong esi;
 
719
        abi_ulong ebp;
 
720
        abi_ulong esp;
 
721
        abi_ulong ebx;
 
722
        abi_ulong edx;
 
723
        abi_ulong ecx;
 
724
        abi_ulong eax;
 
725
        abi_ulong trapno;
 
726
        abi_ulong err;
 
727
        abi_ulong eip;
 
728
        uint16_t cs, __csh;
 
729
        abi_ulong eflags;
 
730
        abi_ulong esp_at_signal;
 
731
        uint16_t ss, __ssh;
 
732
        abi_ulong fpstate; /* pointer */
 
733
        abi_ulong oldmask;
 
734
        abi_ulong cr2;
 
735
};
 
736
 
 
737
struct target_ucontext {
 
738
        abi_ulong         tuc_flags;
 
739
        abi_ulong         tuc_link;
 
740
        target_stack_t    tuc_stack;
 
741
        struct target_sigcontext tuc_mcontext;
 
742
        target_sigset_t   tuc_sigmask;  /* mask last for extensibility */
 
743
};
 
744
 
 
745
struct sigframe
 
746
{
 
747
    abi_ulong pretcode;
 
748
    int sig;
 
749
    struct target_sigcontext sc;
 
750
    struct target_fpstate fpstate;
 
751
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
 
752
    char retcode[8];
 
753
};
 
754
 
 
755
struct rt_sigframe
 
756
{
 
757
    abi_ulong pretcode;
 
758
    int sig;
 
759
    abi_ulong pinfo;
 
760
    abi_ulong puc;
 
761
    struct target_siginfo info;
 
762
    struct target_ucontext uc;
 
763
    struct target_fpstate fpstate;
 
764
    char retcode[8];
 
765
};
 
766
 
 
767
/*
 
768
 * Set up a signal frame.
 
769
 */
 
770
 
 
771
/* XXX: save x87 state */
 
772
static int
 
773
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
 
774
                 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
 
775
{
 
776
        int err = 0;
 
777
        uint16_t magic;
 
778
 
 
779
        /* already locked in setup_frame() */
 
780
        err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
 
781
        err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
 
782
        err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
 
783
        err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
 
784
        err |= __put_user(env->regs[R_EDI], &sc->edi);
 
785
        err |= __put_user(env->regs[R_ESI], &sc->esi);
 
786
        err |= __put_user(env->regs[R_EBP], &sc->ebp);
 
787
        err |= __put_user(env->regs[R_ESP], &sc->esp);
 
788
        err |= __put_user(env->regs[R_EBX], &sc->ebx);
 
789
        err |= __put_user(env->regs[R_EDX], &sc->edx);
 
790
        err |= __put_user(env->regs[R_ECX], &sc->ecx);
 
791
        err |= __put_user(env->regs[R_EAX], &sc->eax);
 
792
        err |= __put_user(env->exception_index, &sc->trapno);
 
793
        err |= __put_user(env->error_code, &sc->err);
 
794
        err |= __put_user(env->eip, &sc->eip);
 
795
        err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
 
796
        err |= __put_user(env->eflags, &sc->eflags);
 
797
        err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
 
798
        err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
 
799
 
 
800
        cpu_x86_fsave(env, fpstate_addr, 1);
 
801
        fpstate->status = fpstate->sw;
 
802
        magic = 0xffff;
 
803
        err |= __put_user(magic, &fpstate->magic);
 
804
        err |= __put_user(fpstate_addr, &sc->fpstate);
 
805
 
 
806
        /* non-iBCS2 extensions.. */
 
807
        err |= __put_user(mask, &sc->oldmask);
 
808
        err |= __put_user(env->cr[2], &sc->cr2);
 
809
        return err;
 
810
}
 
811
 
 
812
/*
 
813
 * Determine which stack to use..
 
814
 */
 
815
 
 
816
static inline abi_ulong
 
817
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
 
818
{
 
819
        unsigned long esp;
 
820
 
 
821
        /* Default to using normal stack */
 
822
        esp = env->regs[R_ESP];
 
823
        /* This is the X/Open sanctioned signal stack switching.  */
 
824
        if (ka->sa_flags & TARGET_SA_ONSTACK) {
 
825
            if (sas_ss_flags(esp) == 0)
 
826
                esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
827
        }
 
828
 
 
829
        /* This is the legacy signal stack switching. */
 
830
        else
 
831
        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
 
832
            !(ka->sa_flags & TARGET_SA_RESTORER) &&
 
833
            ka->sa_restorer) {
 
834
            esp = (unsigned long) ka->sa_restorer;
 
835
        }
 
836
        return (esp - frame_size) & -8ul;
 
837
}
 
838
 
 
839
/* compare linux/arch/i386/kernel/signal.c:setup_frame() */
 
840
static void setup_frame(int sig, struct target_sigaction *ka,
 
841
                        target_sigset_t *set, CPUX86State *env)
 
842
{
 
843
        abi_ulong frame_addr;
 
844
        struct sigframe *frame;
 
845
        int i, err = 0;
 
846
 
 
847
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
848
 
 
849
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
850
                goto give_sigsegv;
 
851
 
 
852
        err |= __put_user(current_exec_domain_sig(sig),
 
853
                          &frame->sig);
 
854
        if (err)
 
855
                goto give_sigsegv;
 
856
 
 
857
        setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
 
858
                         frame_addr + offsetof(struct sigframe, fpstate));
 
859
        if (err)
 
860
                goto give_sigsegv;
 
861
 
 
862
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
863
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
 
864
                goto give_sigsegv;
 
865
        }
 
866
 
 
867
        /* Set up to return from userspace.  If provided, use a stub
 
868
           already in userspace.  */
 
869
        if (ka->sa_flags & TARGET_SA_RESTORER) {
 
870
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
 
871
        } else {
 
872
                uint16_t val16;
 
873
                abi_ulong retcode_addr;
 
874
                retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
 
875
                err |= __put_user(retcode_addr, &frame->pretcode);
 
876
                /* This is popl %eax ; movl $,%eax ; int $0x80 */
 
877
                val16 = 0xb858;
 
878
                err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
 
879
                err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
 
880
                val16 = 0x80cd;
 
881
                err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
 
882
        }
 
883
 
 
884
        if (err)
 
885
                goto give_sigsegv;
 
886
 
 
887
        /* Set up registers for signal handler */
 
888
        env->regs[R_ESP] = frame_addr;
 
889
        env->eip = ka->_sa_handler;
 
890
 
 
891
        cpu_x86_load_seg(env, R_DS, __USER_DS);
 
892
        cpu_x86_load_seg(env, R_ES, __USER_DS);
 
893
        cpu_x86_load_seg(env, R_SS, __USER_DS);
 
894
        cpu_x86_load_seg(env, R_CS, __USER_CS);
 
895
        env->eflags &= ~TF_MASK;
 
896
 
 
897
        unlock_user_struct(frame, frame_addr, 1);
 
898
 
 
899
        return;
 
900
 
 
901
give_sigsegv:
 
902
        unlock_user_struct(frame, frame_addr, 1);
 
903
        if (sig == TARGET_SIGSEGV)
 
904
                ka->_sa_handler = TARGET_SIG_DFL;
 
905
        force_sig(TARGET_SIGSEGV /* , current */);
 
906
}
 
907
 
 
908
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
 
909
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
910
                           target_siginfo_t *info,
 
911
                           target_sigset_t *set, CPUX86State *env)
 
912
{
 
913
        abi_ulong frame_addr, addr;
 
914
        struct rt_sigframe *frame;
 
915
        int i, err = 0;
 
916
 
 
917
        frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
918
 
 
919
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
920
                goto give_sigsegv;
 
921
 
 
922
        err |= __put_user(current_exec_domain_sig(sig),
 
923
                          &frame->sig);
 
924
        addr = frame_addr + offsetof(struct rt_sigframe, info);
 
925
        err |= __put_user(addr, &frame->pinfo);
 
926
        addr = frame_addr + offsetof(struct rt_sigframe, uc);
 
927
        err |= __put_user(addr, &frame->puc);
 
928
        err |= copy_siginfo_to_user(&frame->info, info);
 
929
        if (err)
 
930
                goto give_sigsegv;
 
931
 
 
932
        /* Create the ucontext.  */
 
933
        err |= __put_user(0, &frame->uc.tuc_flags);
 
934
        err |= __put_user(0, &frame->uc.tuc_link);
 
935
        err |= __put_user(target_sigaltstack_used.ss_sp,
 
936
                          &frame->uc.tuc_stack.ss_sp);
 
937
        err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
 
938
                          &frame->uc.tuc_stack.ss_flags);
 
939
        err |= __put_user(target_sigaltstack_used.ss_size,
 
940
                          &frame->uc.tuc_stack.ss_size);
 
941
        err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
 
942
                                env, set->sig[0], 
 
943
                                frame_addr + offsetof(struct rt_sigframe, fpstate));
 
944
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
945
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
 
946
                goto give_sigsegv;
 
947
        }
 
948
 
 
949
        /* Set up to return from userspace.  If provided, use a stub
 
950
           already in userspace.  */
 
951
        if (ka->sa_flags & TARGET_SA_RESTORER) {
 
952
                err |= __put_user(ka->sa_restorer, &frame->pretcode);
 
953
        } else {
 
954
                uint16_t val16;
 
955
                addr = frame_addr + offsetof(struct rt_sigframe, retcode);
 
956
                err |= __put_user(addr, &frame->pretcode);
 
957
                /* This is movl $,%eax ; int $0x80 */
 
958
                err |= __put_user(0xb8, (char *)(frame->retcode+0));
 
959
                err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
 
960
                val16 = 0x80cd;
 
961
                err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
 
962
        }
 
963
 
 
964
        if (err)
 
965
                goto give_sigsegv;
 
966
 
 
967
        /* Set up registers for signal handler */
 
968
        env->regs[R_ESP] = frame_addr;
 
969
        env->eip = ka->_sa_handler;
 
970
 
 
971
        cpu_x86_load_seg(env, R_DS, __USER_DS);
 
972
        cpu_x86_load_seg(env, R_ES, __USER_DS);
 
973
        cpu_x86_load_seg(env, R_SS, __USER_DS);
 
974
        cpu_x86_load_seg(env, R_CS, __USER_CS);
 
975
        env->eflags &= ~TF_MASK;
 
976
 
 
977
        unlock_user_struct(frame, frame_addr, 1);
 
978
 
 
979
        return;
 
980
 
 
981
give_sigsegv:
 
982
        unlock_user_struct(frame, frame_addr, 1);
 
983
        if (sig == TARGET_SIGSEGV)
 
984
                ka->_sa_handler = TARGET_SIG_DFL;
 
985
        force_sig(TARGET_SIGSEGV /* , current */);
 
986
}
 
987
 
 
988
static int
 
989
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
 
990
{
 
991
        unsigned int err = 0;
 
992
        abi_ulong fpstate_addr;
 
993
        unsigned int tmpflags;
 
994
 
 
995
        cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
 
996
        cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
 
997
        cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
 
998
        cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
 
999
 
 
1000
        env->regs[R_EDI] = tswapl(sc->edi);
 
1001
        env->regs[R_ESI] = tswapl(sc->esi);
 
1002
        env->regs[R_EBP] = tswapl(sc->ebp);
 
1003
        env->regs[R_ESP] = tswapl(sc->esp);
 
1004
        env->regs[R_EBX] = tswapl(sc->ebx);
 
1005
        env->regs[R_EDX] = tswapl(sc->edx);
 
1006
        env->regs[R_ECX] = tswapl(sc->ecx);
 
1007
        env->eip = tswapl(sc->eip);
 
1008
 
 
1009
        cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
 
1010
        cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
 
1011
 
 
1012
        tmpflags = tswapl(sc->eflags);
 
1013
        env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
 
1014
        //              regs->orig_eax = -1;            /* disable syscall checks */
 
1015
 
 
1016
        fpstate_addr = tswapl(sc->fpstate);
 
1017
        if (fpstate_addr != 0) {
 
1018
                if (!access_ok(VERIFY_READ, fpstate_addr, 
 
1019
                               sizeof(struct target_fpstate)))
 
1020
                        goto badframe;
 
1021
                cpu_x86_frstor(env, fpstate_addr, 1);
 
1022
        }
 
1023
 
 
1024
        *peax = tswapl(sc->eax);
 
1025
        return err;
 
1026
badframe:
 
1027
        return 1;
 
1028
}
 
1029
 
 
1030
long do_sigreturn(CPUX86State *env)
 
1031
{
 
1032
    struct sigframe *frame;
 
1033
    abi_ulong frame_addr = env->regs[R_ESP] - 8;
 
1034
    target_sigset_t target_set;
 
1035
    sigset_t set;
 
1036
    int eax, i;
 
1037
 
 
1038
#if defined(DEBUG_SIGNAL)
 
1039
    fprintf(stderr, "do_sigreturn\n");
 
1040
#endif
 
1041
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
1042
        goto badframe;
 
1043
    /* set blocked signals */
 
1044
    if (__get_user(target_set.sig[0], &frame->sc.oldmask))
 
1045
        goto badframe;
 
1046
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
1047
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
 
1048
            goto badframe;
 
1049
    }
 
1050
 
 
1051
    target_to_host_sigset_internal(&set, &target_set);
 
1052
    sigprocmask(SIG_SETMASK, &set, NULL);
 
1053
 
 
1054
    /* restore registers */
 
1055
    if (restore_sigcontext(env, &frame->sc, &eax))
 
1056
        goto badframe;
 
1057
    unlock_user_struct(frame, frame_addr, 0);
 
1058
    return eax;
 
1059
 
 
1060
badframe:
 
1061
    unlock_user_struct(frame, frame_addr, 0);
 
1062
    force_sig(TARGET_SIGSEGV);
 
1063
    return 0;
 
1064
}
 
1065
 
 
1066
long do_rt_sigreturn(CPUX86State *env)
 
1067
{
 
1068
        abi_ulong frame_addr;
 
1069
        struct rt_sigframe *frame;
 
1070
        sigset_t set;
 
1071
        int eax;
 
1072
 
 
1073
        frame_addr = env->regs[R_ESP] - 4;
 
1074
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
1075
                goto badframe;
 
1076
        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
 
1077
        sigprocmask(SIG_SETMASK, &set, NULL);
 
1078
 
 
1079
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
 
1080
                goto badframe;
 
1081
 
 
1082
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
 
1083
                           get_sp_from_cpustate(env)) == -EFAULT)
 
1084
                goto badframe;
 
1085
 
 
1086
        unlock_user_struct(frame, frame_addr, 0);
 
1087
        return eax;
 
1088
 
 
1089
badframe:
 
1090
        unlock_user_struct(frame, frame_addr, 0);
 
1091
        force_sig(TARGET_SIGSEGV);
 
1092
        return 0;
 
1093
}
 
1094
 
 
1095
#elif defined(TARGET_AARCH64)
 
1096
 
 
1097
struct target_sigcontext {
 
1098
    uint64_t fault_address;
 
1099
    /* AArch64 registers */
 
1100
    uint64_t regs[31];
 
1101
    uint64_t sp;
 
1102
    uint64_t pc;
 
1103
    uint64_t pstate;
 
1104
    /* 4K reserved for FP/SIMD state and future expansion */
 
1105
    char __reserved[4096] __attribute__((__aligned__(16)));
 
1106
};
 
1107
 
 
1108
struct target_ucontext {
 
1109
    abi_ulong tuc_flags;
 
1110
    abi_ulong tuc_link;
 
1111
    target_stack_t tuc_stack;
 
1112
    target_sigset_t tuc_sigmask;
 
1113
    /* glibc uses a 1024-bit sigset_t */
 
1114
    char __unused[1024 / 8 - sizeof(target_sigset_t)];
 
1115
    /* last for future expansion */
 
1116
    struct target_sigcontext tuc_mcontext;
 
1117
};
 
1118
 
 
1119
/*
 
1120
 * Header to be used at the beginning of structures extending the user
 
1121
 * context. Such structures must be placed after the rt_sigframe on the stack
 
1122
 * and be 16-byte aligned. The last structure must be a dummy one with the
 
1123
 * magic and size set to 0.
 
1124
 */
 
1125
struct target_aarch64_ctx {
 
1126
    uint32_t magic;
 
1127
    uint32_t size;
 
1128
};
 
1129
 
 
1130
#define TARGET_FPSIMD_MAGIC 0x46508001
 
1131
 
 
1132
struct target_fpsimd_context {
 
1133
    struct target_aarch64_ctx head;
 
1134
    uint32_t fpsr;
 
1135
    uint32_t fpcr;
 
1136
    uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
 
1137
};
 
1138
 
 
1139
/*
 
1140
 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
 
1141
 * user space as it will change with the addition of new context. User space
 
1142
 * should check the magic/size information.
 
1143
 */
 
1144
struct target_aux_context {
 
1145
    struct target_fpsimd_context fpsimd;
 
1146
    /* additional context to be added before "end" */
 
1147
    struct target_aarch64_ctx end;
 
1148
};
 
1149
 
 
1150
struct target_rt_sigframe {
 
1151
    struct target_siginfo info;
 
1152
    struct target_ucontext uc;
 
1153
    uint64_t fp;
 
1154
    uint64_t lr;
 
1155
    uint32_t tramp[2];
 
1156
};
 
1157
 
 
1158
static int target_setup_sigframe(struct target_rt_sigframe *sf,
 
1159
                                 CPUARMState *env, target_sigset_t *set)
 
1160
{
 
1161
    int i;
 
1162
    struct target_aux_context *aux =
 
1163
        (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
 
1164
 
 
1165
    /* set up the stack frame for unwinding */
 
1166
    __put_user(env->xregs[29], &sf->fp);
 
1167
    __put_user(env->xregs[30], &sf->lr);
 
1168
 
 
1169
    for (i = 0; i < 31; i++) {
 
1170
        __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
 
1171
    }
 
1172
    __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
 
1173
    __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
 
1174
    __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
 
1175
 
 
1176
    __put_user(/*current->thread.fault_address*/ 0,
 
1177
            &sf->uc.tuc_mcontext.fault_address);
 
1178
 
 
1179
    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
 
1180
        __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
 
1181
    }
 
1182
 
 
1183
    for (i = 0; i < 32; i++) {
 
1184
#ifdef TARGET_WORDS_BIGENDIAN
 
1185
        __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
 
1186
        __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
 
1187
#else
 
1188
        __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
 
1189
        __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
 
1190
#endif
 
1191
    }
 
1192
    __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
 
1193
    __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
 
1194
    __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
 
1195
    __put_user(sizeof(struct target_fpsimd_context),
 
1196
            &aux->fpsimd.head.size);
 
1197
 
 
1198
    /* set the "end" magic */
 
1199
    __put_user(0, &aux->end.magic);
 
1200
    __put_user(0, &aux->end.size);
 
1201
 
 
1202
    return 0;
 
1203
}
 
1204
 
 
1205
static int target_restore_sigframe(CPUARMState *env,
 
1206
                                   struct target_rt_sigframe *sf)
 
1207
{
 
1208
    sigset_t set;
 
1209
    int i;
 
1210
    struct target_aux_context *aux =
 
1211
        (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
 
1212
    uint32_t magic, size, fpsr, fpcr;
 
1213
    uint64_t pstate;
 
1214
 
 
1215
    target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
 
1216
    sigprocmask(SIG_SETMASK, &set, NULL);
 
1217
 
 
1218
    for (i = 0; i < 31; i++) {
 
1219
        __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
 
1220
    }
 
1221
 
 
1222
    __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
 
1223
    __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
 
1224
    __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
 
1225
    pstate_write(env, pstate);
 
1226
 
 
1227
    __get_user(magic, &aux->fpsimd.head.magic);
 
1228
    __get_user(size, &aux->fpsimd.head.size);
 
1229
 
 
1230
    if (magic != TARGET_FPSIMD_MAGIC
 
1231
        || size != sizeof(struct target_fpsimd_context)) {
 
1232
        return 1;
 
1233
    }
 
1234
 
 
1235
    for (i = 0; i < 32 * 2; i++) {
 
1236
        __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]);
 
1237
    }
 
1238
    __get_user(fpsr, &aux->fpsimd.fpsr);
 
1239
    vfp_set_fpsr(env, fpsr);
 
1240
    __get_user(fpcr, &aux->fpsimd.fpcr);
 
1241
    vfp_set_fpcr(env, fpcr);
 
1242
 
 
1243
    return 0;
 
1244
}
 
1245
 
 
1246
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
 
1247
{
 
1248
    abi_ulong sp;
 
1249
 
 
1250
    sp = env->xregs[31];
 
1251
 
 
1252
    /*
 
1253
     * This is the X/Open sanctioned signal stack switching.
 
1254
     */
 
1255
    if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
 
1256
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
1257
    }
 
1258
 
 
1259
    sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
 
1260
 
 
1261
    return sp;
 
1262
}
 
1263
 
 
1264
static void target_setup_frame(int usig, struct target_sigaction *ka,
 
1265
                               target_siginfo_t *info, target_sigset_t *set,
 
1266
                               CPUARMState *env)
 
1267
{
 
1268
    struct target_rt_sigframe *frame;
 
1269
    abi_ulong frame_addr;
 
1270
 
 
1271
    frame_addr = get_sigframe(ka, env);
 
1272
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
 
1273
        goto give_sigsegv;
 
1274
    }
 
1275
 
 
1276
    __put_user(0, &frame->uc.tuc_flags);
 
1277
    __put_user(0, &frame->uc.tuc_link);
 
1278
 
 
1279
    __put_user(target_sigaltstack_used.ss_sp,
 
1280
                      &frame->uc.tuc_stack.ss_sp);
 
1281
    __put_user(sas_ss_flags(env->xregs[31]),
 
1282
                      &frame->uc.tuc_stack.ss_flags);
 
1283
    __put_user(target_sigaltstack_used.ss_size,
 
1284
                      &frame->uc.tuc_stack.ss_size);
 
1285
    target_setup_sigframe(frame, env, set);
 
1286
    /* mov x8,#__NR_rt_sigreturn; svc #0 */
 
1287
    __put_user(0xd2801168, &frame->tramp[0]);
 
1288
    __put_user(0xd4000001, &frame->tramp[1]);
 
1289
    env->xregs[0] = usig;
 
1290
    env->xregs[31] = frame_addr;
 
1291
    env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
 
1292
    env->pc = ka->_sa_handler;
 
1293
    env->xregs[30] = env->xregs[31] +
 
1294
        offsetof(struct target_rt_sigframe, tramp);
 
1295
    if (info) {
 
1296
        if (copy_siginfo_to_user(&frame->info, info)) {
 
1297
            goto give_sigsegv;
 
1298
        }
 
1299
        env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
 
1300
        env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
 
1301
    }
 
1302
 
 
1303
    unlock_user_struct(frame, frame_addr, 1);
 
1304
    return;
 
1305
 
 
1306
 give_sigsegv:
 
1307
    unlock_user_struct(frame, frame_addr, 1);
 
1308
    force_sig(TARGET_SIGSEGV);
 
1309
}
 
1310
 
 
1311
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
1312
                           target_siginfo_t *info, target_sigset_t *set,
 
1313
                           CPUARMState *env)
 
1314
{
 
1315
    target_setup_frame(sig, ka, info, set, env);
 
1316
}
 
1317
 
 
1318
static void setup_frame(int sig, struct target_sigaction *ka,
 
1319
                        target_sigset_t *set, CPUARMState *env)
 
1320
{
 
1321
    target_setup_frame(sig, ka, 0, set, env);
 
1322
}
 
1323
 
 
1324
long do_rt_sigreturn(CPUARMState *env)
 
1325
{
 
1326
    struct target_rt_sigframe *frame;
 
1327
    abi_ulong frame_addr = env->xregs[31];
 
1328
 
 
1329
    if (frame_addr & 15) {
 
1330
        goto badframe;
 
1331
    }
 
1332
 
 
1333
    if  (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
 
1334
        goto badframe;
 
1335
    }
 
1336
 
 
1337
    if (target_restore_sigframe(env, frame)) {
 
1338
        goto badframe;
 
1339
    }
 
1340
 
 
1341
    if (do_sigaltstack(frame_addr +
 
1342
            offsetof(struct target_rt_sigframe, uc.tuc_stack),
 
1343
            0, get_sp_from_cpustate(env)) == -EFAULT) {
 
1344
        goto badframe;
 
1345
    }
 
1346
 
 
1347
    unlock_user_struct(frame, frame_addr, 0);
 
1348
    return env->xregs[0];
 
1349
 
 
1350
 badframe:
 
1351
    unlock_user_struct(frame, frame_addr, 0);
 
1352
    force_sig(TARGET_SIGSEGV);
 
1353
    return 0;
 
1354
}
 
1355
 
 
1356
long do_sigreturn(CPUARMState *env)
 
1357
{
 
1358
    return do_rt_sigreturn(env);
 
1359
}
 
1360
 
 
1361
#elif defined(TARGET_ARM)
 
1362
 
 
1363
struct target_sigcontext {
 
1364
        abi_ulong trap_no;
 
1365
        abi_ulong error_code;
 
1366
        abi_ulong oldmask;
 
1367
        abi_ulong arm_r0;
 
1368
        abi_ulong arm_r1;
 
1369
        abi_ulong arm_r2;
 
1370
        abi_ulong arm_r3;
 
1371
        abi_ulong arm_r4;
 
1372
        abi_ulong arm_r5;
 
1373
        abi_ulong arm_r6;
 
1374
        abi_ulong arm_r7;
 
1375
        abi_ulong arm_r8;
 
1376
        abi_ulong arm_r9;
 
1377
        abi_ulong arm_r10;
 
1378
        abi_ulong arm_fp;
 
1379
        abi_ulong arm_ip;
 
1380
        abi_ulong arm_sp;
 
1381
        abi_ulong arm_lr;
 
1382
        abi_ulong arm_pc;
 
1383
        abi_ulong arm_cpsr;
 
1384
        abi_ulong fault_address;
 
1385
};
 
1386
 
 
1387
struct target_ucontext_v1 {
 
1388
    abi_ulong tuc_flags;
 
1389
    abi_ulong tuc_link;
 
1390
    target_stack_t tuc_stack;
 
1391
    struct target_sigcontext tuc_mcontext;
 
1392
    target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
 
1393
};
 
1394
 
 
1395
struct target_ucontext_v2 {
 
1396
    abi_ulong tuc_flags;
 
1397
    abi_ulong tuc_link;
 
1398
    target_stack_t tuc_stack;
 
1399
    struct target_sigcontext tuc_mcontext;
 
1400
    target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
 
1401
    char __unused[128 - sizeof(target_sigset_t)];
 
1402
    abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
 
1403
};
 
1404
 
 
1405
struct target_user_vfp {
 
1406
    uint64_t fpregs[32];
 
1407
    abi_ulong fpscr;
 
1408
};
 
1409
 
 
1410
struct target_user_vfp_exc {
 
1411
    abi_ulong fpexc;
 
1412
    abi_ulong fpinst;
 
1413
    abi_ulong fpinst2;
 
1414
};
 
1415
 
 
1416
struct target_vfp_sigframe {
 
1417
    abi_ulong magic;
 
1418
    abi_ulong size;
 
1419
    struct target_user_vfp ufp;
 
1420
    struct target_user_vfp_exc ufp_exc;
 
1421
} __attribute__((__aligned__(8)));
 
1422
 
 
1423
struct target_iwmmxt_sigframe {
 
1424
    abi_ulong magic;
 
1425
    abi_ulong size;
 
1426
    uint64_t regs[16];
 
1427
    /* Note that not all the coprocessor control registers are stored here */
 
1428
    uint32_t wcssf;
 
1429
    uint32_t wcasf;
 
1430
    uint32_t wcgr0;
 
1431
    uint32_t wcgr1;
 
1432
    uint32_t wcgr2;
 
1433
    uint32_t wcgr3;
 
1434
} __attribute__((__aligned__(8)));
 
1435
 
 
1436
#define TARGET_VFP_MAGIC 0x56465001
 
1437
#define TARGET_IWMMXT_MAGIC 0x12ef842a
 
1438
 
 
1439
struct sigframe_v1
 
1440
{
 
1441
    struct target_sigcontext sc;
 
1442
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
 
1443
    abi_ulong retcode;
 
1444
};
 
1445
 
 
1446
struct sigframe_v2
 
1447
{
 
1448
    struct target_ucontext_v2 uc;
 
1449
    abi_ulong retcode;
 
1450
};
 
1451
 
 
1452
struct rt_sigframe_v1
 
1453
{
 
1454
    abi_ulong pinfo;
 
1455
    abi_ulong puc;
 
1456
    struct target_siginfo info;
 
1457
    struct target_ucontext_v1 uc;
 
1458
    abi_ulong retcode;
 
1459
};
 
1460
 
 
1461
struct rt_sigframe_v2
 
1462
{
 
1463
    struct target_siginfo info;
 
1464
    struct target_ucontext_v2 uc;
 
1465
    abi_ulong retcode;
 
1466
};
 
1467
 
 
1468
#define TARGET_CONFIG_CPU_32 1
 
1469
 
 
1470
/*
 
1471
 * For ARM syscalls, we encode the syscall number into the instruction.
 
1472
 */
 
1473
#define SWI_SYS_SIGRETURN       (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
 
1474
#define SWI_SYS_RT_SIGRETURN    (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
 
1475
 
 
1476
/*
 
1477
 * For Thumb syscalls, we pass the syscall number via r7.  We therefore
 
1478
 * need two 16-bit instructions.
 
1479
 */
 
1480
#define SWI_THUMB_SIGRETURN     (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
 
1481
#define SWI_THUMB_RT_SIGRETURN  (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
 
1482
 
 
1483
static const abi_ulong retcodes[4] = {
 
1484
        SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
 
1485
        SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
 
1486
};
 
1487
 
 
1488
 
 
1489
#define __get_user_error(x,p,e) __get_user(x, p)
 
1490
 
 
1491
static inline int valid_user_regs(CPUARMState *regs)
 
1492
{
 
1493
    return 1;
 
1494
}
 
1495
 
 
1496
static void
 
1497
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
 
1498
                 CPUARMState *env, abi_ulong mask)
 
1499
{
 
1500
        __put_user(env->regs[0], &sc->arm_r0);
 
1501
        __put_user(env->regs[1], &sc->arm_r1);
 
1502
        __put_user(env->regs[2], &sc->arm_r2);
 
1503
        __put_user(env->regs[3], &sc->arm_r3);
 
1504
        __put_user(env->regs[4], &sc->arm_r4);
 
1505
        __put_user(env->regs[5], &sc->arm_r5);
 
1506
        __put_user(env->regs[6], &sc->arm_r6);
 
1507
        __put_user(env->regs[7], &sc->arm_r7);
 
1508
        __put_user(env->regs[8], &sc->arm_r8);
 
1509
        __put_user(env->regs[9], &sc->arm_r9);
 
1510
        __put_user(env->regs[10], &sc->arm_r10);
 
1511
        __put_user(env->regs[11], &sc->arm_fp);
 
1512
        __put_user(env->regs[12], &sc->arm_ip);
 
1513
        __put_user(env->regs[13], &sc->arm_sp);
 
1514
        __put_user(env->regs[14], &sc->arm_lr);
 
1515
        __put_user(env->regs[15], &sc->arm_pc);
 
1516
#ifdef TARGET_CONFIG_CPU_32
 
1517
        __put_user(cpsr_read(env), &sc->arm_cpsr);
 
1518
#endif
 
1519
 
 
1520
        __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
 
1521
        __put_user(/* current->thread.error_code */ 0, &sc->error_code);
 
1522
        __put_user(/* current->thread.address */ 0, &sc->fault_address);
 
1523
        __put_user(mask, &sc->oldmask);
 
1524
}
 
1525
 
 
1526
static inline abi_ulong
 
1527
get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
 
1528
{
 
1529
        unsigned long sp = regs->regs[13];
 
1530
 
 
1531
        /*
 
1532
         * This is the X/Open sanctioned signal stack switching.
 
1533
         */
 
1534
        if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
 
1535
            sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
1536
        /*
 
1537
         * ATPCS B01 mandates 8-byte alignment
 
1538
         */
 
1539
        return (sp - framesize) & ~7;
 
1540
}
 
1541
 
 
1542
static int
 
1543
setup_return(CPUARMState *env, struct target_sigaction *ka,
 
1544
             abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
 
1545
{
 
1546
        abi_ulong handler = ka->_sa_handler;
 
1547
        abi_ulong retcode;
 
1548
        int thumb = handler & 1;
 
1549
        uint32_t cpsr = cpsr_read(env);
 
1550
 
 
1551
        cpsr &= ~CPSR_IT;
 
1552
        if (thumb) {
 
1553
                cpsr |= CPSR_T;
 
1554
        } else {
 
1555
                cpsr &= ~CPSR_T;
 
1556
        }
 
1557
 
 
1558
        if (ka->sa_flags & TARGET_SA_RESTORER) {
 
1559
                retcode = ka->sa_restorer;
 
1560
        } else {
 
1561
                unsigned int idx = thumb;
 
1562
 
 
1563
                if (ka->sa_flags & TARGET_SA_SIGINFO)
 
1564
                        idx += 2;
 
1565
 
 
1566
                if (__put_user(retcodes[idx], rc))
 
1567
                        return 1;
 
1568
 
 
1569
                retcode = rc_addr + thumb;
 
1570
        }
 
1571
 
 
1572
        env->regs[0] = usig;
 
1573
        env->regs[13] = frame_addr;
 
1574
        env->regs[14] = retcode;
 
1575
        env->regs[15] = handler & (thumb ? ~1 : ~3);
 
1576
        cpsr_write(env, cpsr, 0xffffffff);
 
1577
 
 
1578
        return 0;
 
1579
}
 
1580
 
 
1581
static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
 
1582
{
 
1583
    int i;
 
1584
    struct target_vfp_sigframe *vfpframe;
 
1585
    vfpframe = (struct target_vfp_sigframe *)regspace;
 
1586
    __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
 
1587
    __put_user(sizeof(*vfpframe), &vfpframe->size);
 
1588
    for (i = 0; i < 32; i++) {
 
1589
        __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
 
1590
    }
 
1591
    __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
 
1592
    __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
 
1593
    __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
 
1594
    __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
 
1595
    return (abi_ulong*)(vfpframe+1);
 
1596
}
 
1597
 
 
1598
static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
 
1599
                                           CPUARMState *env)
 
1600
{
 
1601
    int i;
 
1602
    struct target_iwmmxt_sigframe *iwmmxtframe;
 
1603
    iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
 
1604
    __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
 
1605
    __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
 
1606
    for (i = 0; i < 16; i++) {
 
1607
        __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
 
1608
    }
 
1609
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
 
1610
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
 
1611
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
 
1612
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
 
1613
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
 
1614
    __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
 
1615
    return (abi_ulong*)(iwmmxtframe+1);
 
1616
}
 
1617
 
 
1618
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
 
1619
                              target_sigset_t *set, CPUARMState *env)
 
1620
{
 
1621
    struct target_sigaltstack stack;
 
1622
    int i;
 
1623
    abi_ulong *regspace;
 
1624
 
 
1625
    /* Clear all the bits of the ucontext we don't use.  */
 
1626
    memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
 
1627
 
 
1628
    memset(&stack, 0, sizeof(stack));
 
1629
    __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
 
1630
    __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
 
1631
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
 
1632
    memcpy(&uc->tuc_stack, &stack, sizeof(stack));
 
1633
 
 
1634
    setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
 
1635
    /* Save coprocessor signal frame.  */
 
1636
    regspace = uc->tuc_regspace;
 
1637
    if (arm_feature(env, ARM_FEATURE_VFP)) {
 
1638
        regspace = setup_sigframe_v2_vfp(regspace, env);
 
1639
    }
 
1640
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 
1641
        regspace = setup_sigframe_v2_iwmmxt(regspace, env);
 
1642
    }
 
1643
 
 
1644
    /* Write terminating magic word */
 
1645
    __put_user(0, regspace);
 
1646
 
 
1647
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
1648
        __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
 
1649
    }
 
1650
}
 
1651
 
 
1652
/* compare linux/arch/arm/kernel/signal.c:setup_frame() */
 
1653
static void setup_frame_v1(int usig, struct target_sigaction *ka,
 
1654
                           target_sigset_t *set, CPUARMState *regs)
 
1655
{
 
1656
        struct sigframe_v1 *frame;
 
1657
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
 
1658
        int i;
 
1659
 
 
1660
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
1661
                return;
 
1662
 
 
1663
        setup_sigcontext(&frame->sc, regs, set->sig[0]);
 
1664
 
 
1665
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
1666
            if (__put_user(set->sig[i], &frame->extramask[i - 1]))
 
1667
                goto end;
 
1668
        }
 
1669
 
 
1670
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
 
1671
                     frame_addr + offsetof(struct sigframe_v1, retcode));
 
1672
 
 
1673
end:
 
1674
        unlock_user_struct(frame, frame_addr, 1);
 
1675
}
 
1676
 
 
1677
static void setup_frame_v2(int usig, struct target_sigaction *ka,
 
1678
                           target_sigset_t *set, CPUARMState *regs)
 
1679
{
 
1680
        struct sigframe_v2 *frame;
 
1681
        abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
 
1682
 
 
1683
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
1684
                return;
 
1685
 
 
1686
        setup_sigframe_v2(&frame->uc, set, regs);
 
1687
 
 
1688
        setup_return(regs, ka, &frame->retcode, frame_addr, usig,
 
1689
                     frame_addr + offsetof(struct sigframe_v2, retcode));
 
1690
 
 
1691
        unlock_user_struct(frame, frame_addr, 1);
 
1692
}
 
1693
 
 
1694
static void setup_frame(int usig, struct target_sigaction *ka,
 
1695
                        target_sigset_t *set, CPUARMState *regs)
 
1696
{
 
1697
    if (get_osversion() >= 0x020612) {
 
1698
        setup_frame_v2(usig, ka, set, regs);
 
1699
    } else {
 
1700
        setup_frame_v1(usig, ka, set, regs);
 
1701
    }
 
1702
}
 
1703
 
 
1704
/* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
 
1705
static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
 
1706
                              target_siginfo_t *info,
 
1707
                              target_sigset_t *set, CPUARMState *env)
 
1708
{
 
1709
        struct rt_sigframe_v1 *frame;
 
1710
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
1711
        struct target_sigaltstack stack;
 
1712
        int i;
 
1713
        abi_ulong info_addr, uc_addr;
 
1714
 
 
1715
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
1716
            return /* 1 */;
 
1717
 
 
1718
        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
 
1719
        __put_user(info_addr, &frame->pinfo);
 
1720
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
 
1721
        __put_user(uc_addr, &frame->puc);
 
1722
        copy_siginfo_to_user(&frame->info, info);
 
1723
 
 
1724
        /* Clear all the bits of the ucontext we don't use.  */
 
1725
        memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
 
1726
 
 
1727
        memset(&stack, 0, sizeof(stack));
 
1728
        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
 
1729
        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
 
1730
        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
 
1731
        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
 
1732
 
 
1733
        setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
 
1734
        for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
1735
            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
 
1736
                goto end;
 
1737
        }
 
1738
 
 
1739
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
 
1740
                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));
 
1741
 
 
1742
        env->regs[1] = info_addr;
 
1743
        env->regs[2] = uc_addr;
 
1744
 
 
1745
end:
 
1746
        unlock_user_struct(frame, frame_addr, 1);
 
1747
}
 
1748
 
 
1749
static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
 
1750
                              target_siginfo_t *info,
 
1751
                              target_sigset_t *set, CPUARMState *env)
 
1752
{
 
1753
        struct rt_sigframe_v2 *frame;
 
1754
        abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
1755
        abi_ulong info_addr, uc_addr;
 
1756
 
 
1757
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
1758
            return /* 1 */;
 
1759
 
 
1760
        info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
 
1761
        uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
 
1762
        copy_siginfo_to_user(&frame->info, info);
 
1763
 
 
1764
        setup_sigframe_v2(&frame->uc, set, env);
 
1765
 
 
1766
        setup_return(env, ka, &frame->retcode, frame_addr, usig,
 
1767
                     frame_addr + offsetof(struct rt_sigframe_v2, retcode));
 
1768
 
 
1769
        env->regs[1] = info_addr;
 
1770
        env->regs[2] = uc_addr;
 
1771
 
 
1772
        unlock_user_struct(frame, frame_addr, 1);
 
1773
}
 
1774
 
 
1775
static void setup_rt_frame(int usig, struct target_sigaction *ka,
 
1776
                           target_siginfo_t *info,
 
1777
                           target_sigset_t *set, CPUARMState *env)
 
1778
{
 
1779
    if (get_osversion() >= 0x020612) {
 
1780
        setup_rt_frame_v2(usig, ka, info, set, env);
 
1781
    } else {
 
1782
        setup_rt_frame_v1(usig, ka, info, set, env);
 
1783
    }
 
1784
}
 
1785
 
 
1786
static int
 
1787
restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
 
1788
{
 
1789
        int err = 0;
 
1790
        uint32_t cpsr;
 
1791
 
 
1792
        __get_user_error(env->regs[0], &sc->arm_r0, err);
 
1793
        __get_user_error(env->regs[1], &sc->arm_r1, err);
 
1794
        __get_user_error(env->regs[2], &sc->arm_r2, err);
 
1795
        __get_user_error(env->regs[3], &sc->arm_r3, err);
 
1796
        __get_user_error(env->regs[4], &sc->arm_r4, err);
 
1797
        __get_user_error(env->regs[5], &sc->arm_r5, err);
 
1798
        __get_user_error(env->regs[6], &sc->arm_r6, err);
 
1799
        __get_user_error(env->regs[7], &sc->arm_r7, err);
 
1800
        __get_user_error(env->regs[8], &sc->arm_r8, err);
 
1801
        __get_user_error(env->regs[9], &sc->arm_r9, err);
 
1802
        __get_user_error(env->regs[10], &sc->arm_r10, err);
 
1803
        __get_user_error(env->regs[11], &sc->arm_fp, err);
 
1804
        __get_user_error(env->regs[12], &sc->arm_ip, err);
 
1805
        __get_user_error(env->regs[13], &sc->arm_sp, err);
 
1806
        __get_user_error(env->regs[14], &sc->arm_lr, err);
 
1807
        __get_user_error(env->regs[15], &sc->arm_pc, err);
 
1808
#ifdef TARGET_CONFIG_CPU_32
 
1809
        __get_user_error(cpsr, &sc->arm_cpsr, err);
 
1810
        cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
 
1811
#endif
 
1812
 
 
1813
        err |= !valid_user_regs(env);
 
1814
 
 
1815
        return err;
 
1816
}
 
1817
 
 
1818
static long do_sigreturn_v1(CPUARMState *env)
 
1819
{
 
1820
        abi_ulong frame_addr;
 
1821
        struct sigframe_v1 *frame = NULL;
 
1822
        target_sigset_t set;
 
1823
        sigset_t host_set;
 
1824
        int i;
 
1825
 
 
1826
        /*
 
1827
         * Since we stacked the signal on a 64-bit boundary,
 
1828
         * then 'sp' should be word aligned here.  If it's
 
1829
         * not, then the user is trying to mess with us.
 
1830
         */
 
1831
        frame_addr = env->regs[13];
 
1832
        if (frame_addr & 7) {
 
1833
            goto badframe;
 
1834
        }
 
1835
 
 
1836
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
1837
                goto badframe;
 
1838
 
 
1839
        if (__get_user(set.sig[0], &frame->sc.oldmask))
 
1840
            goto badframe;
 
1841
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
1842
            if (__get_user(set.sig[i], &frame->extramask[i - 1]))
 
1843
                goto badframe;
 
1844
        }
 
1845
 
 
1846
        target_to_host_sigset_internal(&host_set, &set);
 
1847
        sigprocmask(SIG_SETMASK, &host_set, NULL);
 
1848
 
 
1849
        if (restore_sigcontext(env, &frame->sc))
 
1850
                goto badframe;
 
1851
 
 
1852
#if 0
 
1853
        /* Send SIGTRAP if we're single-stepping */
 
1854
        if (ptrace_cancel_bpt(current))
 
1855
                send_sig(SIGTRAP, current, 1);
 
1856
#endif
 
1857
        unlock_user_struct(frame, frame_addr, 0);
 
1858
        return env->regs[0];
 
1859
 
 
1860
badframe:
 
1861
        unlock_user_struct(frame, frame_addr, 0);
 
1862
        force_sig(TARGET_SIGSEGV /* , current */);
 
1863
        return 0;
 
1864
}
 
1865
 
 
1866
static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
 
1867
{
 
1868
    int i;
 
1869
    abi_ulong magic, sz;
 
1870
    uint32_t fpscr, fpexc;
 
1871
    struct target_vfp_sigframe *vfpframe;
 
1872
    vfpframe = (struct target_vfp_sigframe *)regspace;
 
1873
 
 
1874
    __get_user(magic, &vfpframe->magic);
 
1875
    __get_user(sz, &vfpframe->size);
 
1876
    if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
 
1877
        return 0;
 
1878
    }
 
1879
    for (i = 0; i < 32; i++) {
 
1880
        __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
 
1881
    }
 
1882
    __get_user(fpscr, &vfpframe->ufp.fpscr);
 
1883
    vfp_set_fpscr(env, fpscr);
 
1884
    __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
 
1885
    /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
 
1886
     * and the exception flag is cleared
 
1887
     */
 
1888
    fpexc |= (1 << 30);
 
1889
    fpexc &= ~((1 << 31) | (1 << 28));
 
1890
    env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
 
1891
    __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
 
1892
    __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
 
1893
    return (abi_ulong*)(vfpframe + 1);
 
1894
}
 
1895
 
 
1896
static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
 
1897
                                             abi_ulong *regspace)
 
1898
{
 
1899
    int i;
 
1900
    abi_ulong magic, sz;
 
1901
    struct target_iwmmxt_sigframe *iwmmxtframe;
 
1902
    iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
 
1903
 
 
1904
    __get_user(magic, &iwmmxtframe->magic);
 
1905
    __get_user(sz, &iwmmxtframe->size);
 
1906
    if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
 
1907
        return 0;
 
1908
    }
 
1909
    for (i = 0; i < 16; i++) {
 
1910
        __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
 
1911
    }
 
1912
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
 
1913
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
 
1914
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
 
1915
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
 
1916
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
 
1917
    __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
 
1918
    return (abi_ulong*)(iwmmxtframe + 1);
 
1919
}
 
1920
 
 
1921
static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
 
1922
                                 struct target_ucontext_v2 *uc)
 
1923
{
 
1924
    sigset_t host_set;
 
1925
    abi_ulong *regspace;
 
1926
 
 
1927
    target_to_host_sigset(&host_set, &uc->tuc_sigmask);
 
1928
    sigprocmask(SIG_SETMASK, &host_set, NULL);
 
1929
 
 
1930
    if (restore_sigcontext(env, &uc->tuc_mcontext))
 
1931
        return 1;
 
1932
 
 
1933
    /* Restore coprocessor signal frame */
 
1934
    regspace = uc->tuc_regspace;
 
1935
    if (arm_feature(env, ARM_FEATURE_VFP)) {
 
1936
        regspace = restore_sigframe_v2_vfp(env, regspace);
 
1937
        if (!regspace) {
 
1938
            return 1;
 
1939
        }
 
1940
    }
 
1941
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
 
1942
        regspace = restore_sigframe_v2_iwmmxt(env, regspace);
 
1943
        if (!regspace) {
 
1944
            return 1;
 
1945
        }
 
1946
    }
 
1947
 
 
1948
    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
 
1949
        return 1;
 
1950
 
 
1951
#if 0
 
1952
    /* Send SIGTRAP if we're single-stepping */
 
1953
    if (ptrace_cancel_bpt(current))
 
1954
            send_sig(SIGTRAP, current, 1);
 
1955
#endif
 
1956
 
 
1957
    return 0;
 
1958
}
 
1959
 
 
1960
static long do_sigreturn_v2(CPUARMState *env)
 
1961
{
 
1962
        abi_ulong frame_addr;
 
1963
        struct sigframe_v2 *frame = NULL;
 
1964
 
 
1965
        /*
 
1966
         * Since we stacked the signal on a 64-bit boundary,
 
1967
         * then 'sp' should be word aligned here.  If it's
 
1968
         * not, then the user is trying to mess with us.
 
1969
         */
 
1970
        frame_addr = env->regs[13];
 
1971
        if (frame_addr & 7) {
 
1972
            goto badframe;
 
1973
        }
 
1974
 
 
1975
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
1976
                goto badframe;
 
1977
 
 
1978
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
 
1979
                goto badframe;
 
1980
 
 
1981
        unlock_user_struct(frame, frame_addr, 0);
 
1982
        return env->regs[0];
 
1983
 
 
1984
badframe:
 
1985
        unlock_user_struct(frame, frame_addr, 0);
 
1986
        force_sig(TARGET_SIGSEGV /* , current */);
 
1987
        return 0;
 
1988
}
 
1989
 
 
1990
long do_sigreturn(CPUARMState *env)
 
1991
{
 
1992
    if (get_osversion() >= 0x020612) {
 
1993
        return do_sigreturn_v2(env);
 
1994
    } else {
 
1995
        return do_sigreturn_v1(env);
 
1996
    }
 
1997
}
 
1998
 
 
1999
static long do_rt_sigreturn_v1(CPUARMState *env)
 
2000
{
 
2001
        abi_ulong frame_addr;
 
2002
        struct rt_sigframe_v1 *frame = NULL;
 
2003
        sigset_t host_set;
 
2004
 
 
2005
        /*
 
2006
         * Since we stacked the signal on a 64-bit boundary,
 
2007
         * then 'sp' should be word aligned here.  If it's
 
2008
         * not, then the user is trying to mess with us.
 
2009
         */
 
2010
        frame_addr = env->regs[13];
 
2011
        if (frame_addr & 7) {
 
2012
            goto badframe;
 
2013
        }
 
2014
 
 
2015
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
2016
                goto badframe;
 
2017
 
 
2018
        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
 
2019
        sigprocmask(SIG_SETMASK, &host_set, NULL);
 
2020
 
 
2021
        if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
 
2022
                goto badframe;
 
2023
 
 
2024
        if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
 
2025
                goto badframe;
 
2026
 
 
2027
#if 0
 
2028
        /* Send SIGTRAP if we're single-stepping */
 
2029
        if (ptrace_cancel_bpt(current))
 
2030
                send_sig(SIGTRAP, current, 1);
 
2031
#endif
 
2032
        unlock_user_struct(frame, frame_addr, 0);
 
2033
        return env->regs[0];
 
2034
 
 
2035
badframe:
 
2036
        unlock_user_struct(frame, frame_addr, 0);
 
2037
        force_sig(TARGET_SIGSEGV /* , current */);
 
2038
        return 0;
 
2039
}
 
2040
 
 
2041
static long do_rt_sigreturn_v2(CPUARMState *env)
 
2042
{
 
2043
        abi_ulong frame_addr;
 
2044
        struct rt_sigframe_v2 *frame = NULL;
 
2045
 
 
2046
        /*
 
2047
         * Since we stacked the signal on a 64-bit boundary,
 
2048
         * then 'sp' should be word aligned here.  If it's
 
2049
         * not, then the user is trying to mess with us.
 
2050
         */
 
2051
        frame_addr = env->regs[13];
 
2052
        if (frame_addr & 7) {
 
2053
            goto badframe;
 
2054
        }
 
2055
 
 
2056
        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
2057
                goto badframe;
 
2058
 
 
2059
        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
 
2060
                goto badframe;
 
2061
 
 
2062
        unlock_user_struct(frame, frame_addr, 0);
 
2063
        return env->regs[0];
 
2064
 
 
2065
badframe:
 
2066
        unlock_user_struct(frame, frame_addr, 0);
 
2067
        force_sig(TARGET_SIGSEGV /* , current */);
 
2068
        return 0;
 
2069
}
 
2070
 
 
2071
long do_rt_sigreturn(CPUARMState *env)
 
2072
{
 
2073
    if (get_osversion() >= 0x020612) {
 
2074
        return do_rt_sigreturn_v2(env);
 
2075
    } else {
 
2076
        return do_rt_sigreturn_v1(env);
 
2077
    }
 
2078
}
 
2079
 
 
2080
#elif defined(TARGET_SPARC)
 
2081
 
 
2082
#define __SUNOS_MAXWIN   31
 
2083
 
 
2084
/* This is what SunOS does, so shall I. */
 
2085
struct target_sigcontext {
 
2086
        abi_ulong sigc_onstack;      /* state to restore */
 
2087
 
 
2088
        abi_ulong sigc_mask;         /* sigmask to restore */
 
2089
        abi_ulong sigc_sp;           /* stack pointer */
 
2090
        abi_ulong sigc_pc;           /* program counter */
 
2091
        abi_ulong sigc_npc;          /* next program counter */
 
2092
        abi_ulong sigc_psr;          /* for condition codes etc */
 
2093
        abi_ulong sigc_g1;           /* User uses these two registers */
 
2094
        abi_ulong sigc_o0;           /* within the trampoline code. */
 
2095
 
 
2096
        /* Now comes information regarding the users window set
 
2097
         * at the time of the signal.
 
2098
         */
 
2099
        abi_ulong sigc_oswins;       /* outstanding windows */
 
2100
 
 
2101
        /* stack ptrs for each regwin buf */
 
2102
        char *sigc_spbuf[__SUNOS_MAXWIN];
 
2103
 
 
2104
        /* Windows to restore after signal */
 
2105
        struct {
 
2106
                abi_ulong locals[8];
 
2107
                abi_ulong ins[8];
 
2108
        } sigc_wbuf[__SUNOS_MAXWIN];
 
2109
};
 
2110
/* A Sparc stack frame */
 
2111
struct sparc_stackf {
 
2112
        abi_ulong locals[8];
 
2113
        abi_ulong ins[8];
 
2114
        /* It's simpler to treat fp and callers_pc as elements of ins[]
 
2115
         * since we never need to access them ourselves.
 
2116
         */
 
2117
        char *structptr;
 
2118
        abi_ulong xargs[6];
 
2119
        abi_ulong xxargs[1];
 
2120
};
 
2121
 
 
2122
typedef struct {
 
2123
        struct {
 
2124
                abi_ulong psr;
 
2125
                abi_ulong pc;
 
2126
                abi_ulong npc;
 
2127
                abi_ulong y;
 
2128
                abi_ulong u_regs[16]; /* globals and ins */
 
2129
        }               si_regs;
 
2130
        int             si_mask;
 
2131
} __siginfo_t;
 
2132
 
 
2133
typedef struct {
 
2134
        abi_ulong       si_float_regs[32];
 
2135
        unsigned   long si_fsr;
 
2136
        unsigned   long si_fpqdepth;
 
2137
        struct {
 
2138
                unsigned long *insn_addr;
 
2139
                unsigned long insn;
 
2140
        } si_fpqueue [16];
 
2141
} qemu_siginfo_fpu_t;
 
2142
 
 
2143
 
 
2144
struct target_signal_frame {
 
2145
        struct sparc_stackf     ss;
 
2146
        __siginfo_t             info;
 
2147
        abi_ulong               fpu_save;
 
2148
        abi_ulong               insns[2] __attribute__ ((aligned (8)));
 
2149
        abi_ulong               extramask[TARGET_NSIG_WORDS - 1];
 
2150
        abi_ulong               extra_size; /* Should be 0 */
 
2151
        qemu_siginfo_fpu_t      fpu_state;
 
2152
};
 
2153
struct target_rt_signal_frame {
 
2154
        struct sparc_stackf     ss;
 
2155
        siginfo_t               info;
 
2156
        abi_ulong               regs[20];
 
2157
        sigset_t                mask;
 
2158
        abi_ulong               fpu_save;
 
2159
        unsigned int            insns[2];
 
2160
        stack_t                 stack;
 
2161
        unsigned int            extra_size; /* Should be 0 */
 
2162
        qemu_siginfo_fpu_t      fpu_state;
 
2163
};
 
2164
 
 
2165
#define UREG_O0        16
 
2166
#define UREG_O6        22
 
2167
#define UREG_I0        0
 
2168
#define UREG_I1        1
 
2169
#define UREG_I2        2
 
2170
#define UREG_I3        3
 
2171
#define UREG_I4        4
 
2172
#define UREG_I5        5
 
2173
#define UREG_I6        6
 
2174
#define UREG_I7        7
 
2175
#define UREG_L0        8
 
2176
#define UREG_FP        UREG_I6
 
2177
#define UREG_SP        UREG_O6
 
2178
 
 
2179
static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
 
2180
                                     CPUSPARCState *env,
 
2181
                                     unsigned long framesize)
 
2182
{
 
2183
        abi_ulong sp;
 
2184
 
 
2185
        sp = env->regwptr[UREG_FP];
 
2186
 
 
2187
        /* This is the X/Open sanctioned signal stack switching.  */
 
2188
        if (sa->sa_flags & TARGET_SA_ONSTACK) {
 
2189
            if (!on_sig_stack(sp)
 
2190
                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
 
2191
                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
2192
        }
 
2193
        return sp - framesize;
 
2194
}
 
2195
 
 
2196
static int
 
2197
setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
 
2198
{
 
2199
        int err = 0, i;
 
2200
 
 
2201
        err |= __put_user(env->psr, &si->si_regs.psr);
 
2202
        err |= __put_user(env->pc, &si->si_regs.pc);
 
2203
        err |= __put_user(env->npc, &si->si_regs.npc);
 
2204
        err |= __put_user(env->y, &si->si_regs.y);
 
2205
        for (i=0; i < 8; i++) {
 
2206
                err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
 
2207
        }
 
2208
        for (i=0; i < 8; i++) {
 
2209
                err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
 
2210
        }
 
2211
        err |= __put_user(mask, &si->si_mask);
 
2212
        return err;
 
2213
}
 
2214
 
 
2215
#if 0
 
2216
static int
 
2217
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
 
2218
                 CPUSPARCState *env, unsigned long mask)
 
2219
{
 
2220
        int err = 0;
 
2221
 
 
2222
        err |= __put_user(mask, &sc->sigc_mask);
 
2223
        err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
 
2224
        err |= __put_user(env->pc, &sc->sigc_pc);
 
2225
        err |= __put_user(env->npc, &sc->sigc_npc);
 
2226
        err |= __put_user(env->psr, &sc->sigc_psr);
 
2227
        err |= __put_user(env->gregs[1], &sc->sigc_g1);
 
2228
        err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
 
2229
 
 
2230
        return err;
 
2231
}
 
2232
#endif
 
2233
#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
 
2234
 
 
2235
static void setup_frame(int sig, struct target_sigaction *ka,
 
2236
                        target_sigset_t *set, CPUSPARCState *env)
 
2237
{
 
2238
        abi_ulong sf_addr;
 
2239
        struct target_signal_frame *sf;
 
2240
        int sigframe_size, err, i;
 
2241
 
 
2242
        /* 1. Make sure everything is clean */
 
2243
        //synchronize_user_stack();
 
2244
 
 
2245
        sigframe_size = NF_ALIGNEDSZ;
 
2246
        sf_addr = get_sigframe(ka, env, sigframe_size);
 
2247
 
 
2248
        sf = lock_user(VERIFY_WRITE, sf_addr, 
 
2249
                       sizeof(struct target_signal_frame), 0);
 
2250
        if (!sf)
 
2251
                goto sigsegv;
 
2252
                
 
2253
        //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
 
2254
#if 0
 
2255
        if (invalid_frame_pointer(sf, sigframe_size))
 
2256
                goto sigill_and_return;
 
2257
#endif
 
2258
        /* 2. Save the current process state */
 
2259
        err = setup___siginfo(&sf->info, env, set->sig[0]);
 
2260
        err |= __put_user(0, &sf->extra_size);
 
2261
 
 
2262
        //err |= save_fpu_state(regs, &sf->fpu_state);
 
2263
        //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
 
2264
 
 
2265
        err |= __put_user(set->sig[0], &sf->info.si_mask);
 
2266
        for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
 
2267
                err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
 
2268
        }
 
2269
 
 
2270
        for (i = 0; i < 8; i++) {
 
2271
                err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
 
2272
        }
 
2273
        for (i = 0; i < 8; i++) {
 
2274
                err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
 
2275
        }
 
2276
        if (err)
 
2277
                goto sigsegv;
 
2278
 
 
2279
        /* 3. signal handler back-trampoline and parameters */
 
2280
        env->regwptr[UREG_FP] = sf_addr;
 
2281
        env->regwptr[UREG_I0] = sig;
 
2282
        env->regwptr[UREG_I1] = sf_addr + 
 
2283
                offsetof(struct target_signal_frame, info);
 
2284
        env->regwptr[UREG_I2] = sf_addr + 
 
2285
                offsetof(struct target_signal_frame, info);
 
2286
 
 
2287
        /* 4. signal handler */
 
2288
        env->pc = ka->_sa_handler;
 
2289
        env->npc = (env->pc + 4);
 
2290
        /* 5. return to kernel instructions */
 
2291
        if (ka->sa_restorer)
 
2292
                env->regwptr[UREG_I7] = ka->sa_restorer;
 
2293
        else {
 
2294
                uint32_t val32;
 
2295
 
 
2296
                env->regwptr[UREG_I7] = sf_addr + 
 
2297
                        offsetof(struct target_signal_frame, insns) - 2 * 4;
 
2298
 
 
2299
                /* mov __NR_sigreturn, %g1 */
 
2300
                val32 = 0x821020d8;
 
2301
                err |= __put_user(val32, &sf->insns[0]);
 
2302
 
 
2303
                /* t 0x10 */
 
2304
                val32 = 0x91d02010;
 
2305
                err |= __put_user(val32, &sf->insns[1]);
 
2306
                if (err)
 
2307
                        goto sigsegv;
 
2308
 
 
2309
                /* Flush instruction space. */
 
2310
                //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
 
2311
                //              tb_flush(env);
 
2312
        }
 
2313
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
 
2314
        return;
 
2315
#if 0
 
2316
sigill_and_return:
 
2317
        force_sig(TARGET_SIGILL);
 
2318
#endif
 
2319
sigsegv:
 
2320
        //fprintf(stderr, "force_sig\n");
 
2321
        unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
 
2322
        force_sig(TARGET_SIGSEGV);
 
2323
}
 
2324
static inline int
 
2325
restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
 
2326
{
 
2327
        int err;
 
2328
#if 0
 
2329
#ifdef CONFIG_SMP
 
2330
        if (current->flags & PF_USEDFPU)
 
2331
                regs->psr &= ~PSR_EF;
 
2332
#else
 
2333
        if (current == last_task_used_math) {
 
2334
                last_task_used_math = 0;
 
2335
                regs->psr &= ~PSR_EF;
 
2336
        }
 
2337
#endif
 
2338
        current->used_math = 1;
 
2339
        current->flags &= ~PF_USEDFPU;
 
2340
#endif
 
2341
#if 0
 
2342
        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
 
2343
                return -EFAULT;
 
2344
#endif
 
2345
 
 
2346
        /* XXX: incorrect */
 
2347
        err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],
 
2348
                             (sizeof(abi_ulong) * 32));
 
2349
        err |= __get_user(env->fsr, &fpu->si_fsr);
 
2350
#if 0
 
2351
        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
 
2352
        if (current->thread.fpqdepth != 0)
 
2353
                err |= __copy_from_user(&current->thread.fpqueue[0],
 
2354
                                        &fpu->si_fpqueue[0],
 
2355
                                        ((sizeof(unsigned long) +
 
2356
                                        (sizeof(unsigned long *)))*16));
 
2357
#endif
 
2358
        return err;
 
2359
}
 
2360
 
 
2361
 
 
2362
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
2363
                           target_siginfo_t *info,
 
2364
                           target_sigset_t *set, CPUSPARCState *env)
 
2365
{
 
2366
    fprintf(stderr, "setup_rt_frame: not implemented\n");
 
2367
}
 
2368
 
 
2369
long do_sigreturn(CPUSPARCState *env)
 
2370
{
 
2371
        abi_ulong sf_addr;
 
2372
        struct target_signal_frame *sf;
 
2373
        uint32_t up_psr, pc, npc;
 
2374
        target_sigset_t set;
 
2375
        sigset_t host_set;
 
2376
        int err, i;
 
2377
 
 
2378
        sf_addr = env->regwptr[UREG_FP];
 
2379
        if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
 
2380
                goto segv_and_exit;
 
2381
#if 0
 
2382
        fprintf(stderr, "sigreturn\n");
 
2383
        fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
 
2384
#endif
 
2385
        //cpu_dump_state(env, stderr, fprintf, 0);
 
2386
 
 
2387
        /* 1. Make sure we are not getting garbage from the user */
 
2388
 
 
2389
        if (sf_addr & 3)
 
2390
                goto segv_and_exit;
 
2391
 
 
2392
        err = __get_user(pc,  &sf->info.si_regs.pc);
 
2393
        err |= __get_user(npc, &sf->info.si_regs.npc);
 
2394
 
 
2395
        if ((pc | npc) & 3)
 
2396
                goto segv_and_exit;
 
2397
 
 
2398
        /* 2. Restore the state */
 
2399
        err |= __get_user(up_psr, &sf->info.si_regs.psr);
 
2400
 
 
2401
        /* User can only change condition codes and FPU enabling in %psr. */
 
2402
        env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
 
2403
                  | (env->psr & ~(PSR_ICC /* | PSR_EF */));
 
2404
 
 
2405
        env->pc = pc;
 
2406
        env->npc = npc;
 
2407
        err |= __get_user(env->y, &sf->info.si_regs.y);
 
2408
        for (i=0; i < 8; i++) {
 
2409
                err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
 
2410
        }
 
2411
        for (i=0; i < 8; i++) {
 
2412
                err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
 
2413
        }
 
2414
 
 
2415
        /* FIXME: implement FPU save/restore:
 
2416
         * __get_user(fpu_save, &sf->fpu_save);
 
2417
         * if (fpu_save)
 
2418
         *        err |= restore_fpu_state(env, fpu_save);
 
2419
         */
 
2420
 
 
2421
        /* This is pretty much atomic, no amount locking would prevent
 
2422
         * the races which exist anyways.
 
2423
         */
 
2424
        err |= __get_user(set.sig[0], &sf->info.si_mask);
 
2425
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
2426
            err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
 
2427
        }
 
2428
 
 
2429
        target_to_host_sigset_internal(&host_set, &set);
 
2430
        sigprocmask(SIG_SETMASK, &host_set, NULL);
 
2431
 
 
2432
        if (err)
 
2433
                goto segv_and_exit;
 
2434
        unlock_user_struct(sf, sf_addr, 0);
 
2435
        return env->regwptr[0];
 
2436
 
 
2437
segv_and_exit:
 
2438
        unlock_user_struct(sf, sf_addr, 0);
 
2439
        force_sig(TARGET_SIGSEGV);
 
2440
}
 
2441
 
 
2442
long do_rt_sigreturn(CPUSPARCState *env)
 
2443
{
 
2444
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
 
2445
    return -TARGET_ENOSYS;
 
2446
}
 
2447
 
 
2448
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
 
2449
#define MC_TSTATE 0
 
2450
#define MC_PC 1
 
2451
#define MC_NPC 2
 
2452
#define MC_Y 3
 
2453
#define MC_G1 4
 
2454
#define MC_G2 5
 
2455
#define MC_G3 6
 
2456
#define MC_G4 7
 
2457
#define MC_G5 8
 
2458
#define MC_G6 9
 
2459
#define MC_G7 10
 
2460
#define MC_O0 11
 
2461
#define MC_O1 12
 
2462
#define MC_O2 13
 
2463
#define MC_O3 14
 
2464
#define MC_O4 15
 
2465
#define MC_O5 16
 
2466
#define MC_O6 17
 
2467
#define MC_O7 18
 
2468
#define MC_NGREG 19
 
2469
 
 
2470
typedef abi_ulong target_mc_greg_t;
 
2471
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
 
2472
 
 
2473
struct target_mc_fq {
 
2474
    abi_ulong *mcfq_addr;
 
2475
    uint32_t mcfq_insn;
 
2476
};
 
2477
 
 
2478
struct target_mc_fpu {
 
2479
    union {
 
2480
        uint32_t sregs[32];
 
2481
        uint64_t dregs[32];
 
2482
        //uint128_t qregs[16];
 
2483
    } mcfpu_fregs;
 
2484
    abi_ulong mcfpu_fsr;
 
2485
    abi_ulong mcfpu_fprs;
 
2486
    abi_ulong mcfpu_gsr;
 
2487
    struct target_mc_fq *mcfpu_fq;
 
2488
    unsigned char mcfpu_qcnt;
 
2489
    unsigned char mcfpu_qentsz;
 
2490
    unsigned char mcfpu_enab;
 
2491
};
 
2492
typedef struct target_mc_fpu target_mc_fpu_t;
 
2493
 
 
2494
typedef struct {
 
2495
    target_mc_gregset_t mc_gregs;
 
2496
    target_mc_greg_t mc_fp;
 
2497
    target_mc_greg_t mc_i7;
 
2498
    target_mc_fpu_t mc_fpregs;
 
2499
} target_mcontext_t;
 
2500
 
 
2501
struct target_ucontext {
 
2502
    struct target_ucontext *tuc_link;
 
2503
    abi_ulong tuc_flags;
 
2504
    target_sigset_t tuc_sigmask;
 
2505
    target_mcontext_t tuc_mcontext;
 
2506
};
 
2507
 
 
2508
/* A V9 register window */
 
2509
struct target_reg_window {
 
2510
    abi_ulong locals[8];
 
2511
    abi_ulong ins[8];
 
2512
};
 
2513
 
 
2514
#define TARGET_STACK_BIAS 2047
 
2515
 
 
2516
/* {set, get}context() needed for 64-bit SparcLinux userland. */
 
2517
void sparc64_set_context(CPUSPARCState *env)
 
2518
{
 
2519
    abi_ulong ucp_addr;
 
2520
    struct target_ucontext *ucp;
 
2521
    target_mc_gregset_t *grp;
 
2522
    abi_ulong pc, npc, tstate;
 
2523
    abi_ulong fp, i7, w_addr;
 
2524
    int err;
 
2525
    unsigned int i;
 
2526
 
 
2527
    ucp_addr = env->regwptr[UREG_I0];
 
2528
    if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
 
2529
        goto do_sigsegv;
 
2530
    grp  = &ucp->tuc_mcontext.mc_gregs;
 
2531
    err  = __get_user(pc, &((*grp)[MC_PC]));
 
2532
    err |= __get_user(npc, &((*grp)[MC_NPC]));
 
2533
    if (err || ((pc | npc) & 3))
 
2534
        goto do_sigsegv;
 
2535
    if (env->regwptr[UREG_I1]) {
 
2536
        target_sigset_t target_set;
 
2537
        sigset_t set;
 
2538
 
 
2539
        if (TARGET_NSIG_WORDS == 1) {
 
2540
            if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
 
2541
                goto do_sigsegv;
 
2542
        } else {
 
2543
            abi_ulong *src, *dst;
 
2544
            src = ucp->tuc_sigmask.sig;
 
2545
            dst = target_set.sig;
 
2546
            for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
 
2547
                 i++, dst++, src++)
 
2548
                err |= __get_user(*dst, src);
 
2549
            if (err)
 
2550
                goto do_sigsegv;
 
2551
        }
 
2552
        target_to_host_sigset_internal(&set, &target_set);
 
2553
        sigprocmask(SIG_SETMASK, &set, NULL);
 
2554
    }
 
2555
    env->pc = pc;
 
2556
    env->npc = npc;
 
2557
    err |= __get_user(env->y, &((*grp)[MC_Y]));
 
2558
    err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
 
2559
    env->asi = (tstate >> 24) & 0xff;
 
2560
    cpu_put_ccr(env, tstate >> 32);
 
2561
    cpu_put_cwp64(env, tstate & 0x1f);
 
2562
    err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
 
2563
    err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
 
2564
    err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
 
2565
    err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
 
2566
    err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
 
2567
    err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
 
2568
    err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
 
2569
    err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
 
2570
    err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
 
2571
    err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
 
2572
    err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
 
2573
    err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
 
2574
    err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
 
2575
    err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
 
2576
    err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
 
2577
 
 
2578
    err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
 
2579
    err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
 
2580
 
 
2581
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
 
2582
    if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
 
2583
                 abi_ulong) != 0)
 
2584
        goto do_sigsegv;
 
2585
    if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
 
2586
                 abi_ulong) != 0)
 
2587
        goto do_sigsegv;
 
2588
    /* FIXME this does not match how the kernel handles the FPU in
 
2589
     * its sparc64_set_context implementation. In particular the FPU
 
2590
     * is only restored if fenab is non-zero in:
 
2591
     *   __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
 
2592
     */
 
2593
    err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
 
2594
    {
 
2595
        uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
 
2596
        for (i = 0; i < 64; i++, src++) {
 
2597
            if (i & 1) {
 
2598
                err |= __get_user(env->fpr[i/2].l.lower, src);
 
2599
            } else {
 
2600
                err |= __get_user(env->fpr[i/2].l.upper, src);
 
2601
            }
 
2602
        }
 
2603
    }
 
2604
    err |= __get_user(env->fsr,
 
2605
                      &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
 
2606
    err |= __get_user(env->gsr,
 
2607
                      &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
 
2608
    if (err)
 
2609
        goto do_sigsegv;
 
2610
    unlock_user_struct(ucp, ucp_addr, 0);
 
2611
    return;
 
2612
 do_sigsegv:
 
2613
    unlock_user_struct(ucp, ucp_addr, 0);
 
2614
    force_sig(TARGET_SIGSEGV);
 
2615
}
 
2616
 
 
2617
void sparc64_get_context(CPUSPARCState *env)
 
2618
{
 
2619
    abi_ulong ucp_addr;
 
2620
    struct target_ucontext *ucp;
 
2621
    target_mc_gregset_t *grp;
 
2622
    target_mcontext_t *mcp;
 
2623
    abi_ulong fp, i7, w_addr;
 
2624
    int err;
 
2625
    unsigned int i;
 
2626
    target_sigset_t target_set;
 
2627
    sigset_t set;
 
2628
 
 
2629
    ucp_addr = env->regwptr[UREG_I0];
 
2630
    if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
 
2631
        goto do_sigsegv;
 
2632
    
 
2633
    mcp = &ucp->tuc_mcontext;
 
2634
    grp = &mcp->mc_gregs;
 
2635
 
 
2636
    /* Skip over the trap instruction, first. */
 
2637
    env->pc = env->npc;
 
2638
    env->npc += 4;
 
2639
 
 
2640
    err = 0;
 
2641
 
 
2642
    sigprocmask(0, NULL, &set);
 
2643
    host_to_target_sigset_internal(&target_set, &set);
 
2644
    if (TARGET_NSIG_WORDS == 1) {
 
2645
        err |= __put_user(target_set.sig[0],
 
2646
                          (abi_ulong *)&ucp->tuc_sigmask);
 
2647
    } else {
 
2648
        abi_ulong *src, *dst;
 
2649
        src = target_set.sig;
 
2650
        dst = ucp->tuc_sigmask.sig;
 
2651
        for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
 
2652
             i++, dst++, src++)
 
2653
            err |= __put_user(*src, dst);
 
2654
        if (err)
 
2655
            goto do_sigsegv;
 
2656
    }
 
2657
 
 
2658
    /* XXX: tstate must be saved properly */
 
2659
    //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
 
2660
    err |= __put_user(env->pc, &((*grp)[MC_PC]));
 
2661
    err |= __put_user(env->npc, &((*grp)[MC_NPC]));
 
2662
    err |= __put_user(env->y, &((*grp)[MC_Y]));
 
2663
    err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
 
2664
    err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
 
2665
    err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
 
2666
    err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
 
2667
    err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
 
2668
    err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
 
2669
    err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
 
2670
    err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
 
2671
    err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
 
2672
    err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
 
2673
    err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
 
2674
    err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
 
2675
    err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
 
2676
    err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
 
2677
    err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
 
2678
 
 
2679
    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
 
2680
    fp = i7 = 0;
 
2681
    if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
 
2682
                 abi_ulong) != 0)
 
2683
        goto do_sigsegv;
 
2684
    if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
 
2685
                 abi_ulong) != 0)
 
2686
        goto do_sigsegv;
 
2687
    err |= __put_user(fp, &(mcp->mc_fp));
 
2688
    err |= __put_user(i7, &(mcp->mc_i7));
 
2689
 
 
2690
    {
 
2691
        uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
 
2692
        for (i = 0; i < 64; i++, dst++) {
 
2693
            if (i & 1) {
 
2694
                err |= __put_user(env->fpr[i/2].l.lower, dst);
 
2695
            } else {
 
2696
                err |= __put_user(env->fpr[i/2].l.upper, dst);
 
2697
            }
 
2698
        }
 
2699
    }
 
2700
    err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
 
2701
    err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
 
2702
    err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
 
2703
 
 
2704
    if (err)
 
2705
        goto do_sigsegv;
 
2706
    unlock_user_struct(ucp, ucp_addr, 1);
 
2707
    return;
 
2708
 do_sigsegv:
 
2709
    unlock_user_struct(ucp, ucp_addr, 1);
 
2710
    force_sig(TARGET_SIGSEGV);
 
2711
}
 
2712
#endif
 
2713
#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
 
2714
 
 
2715
# if defined(TARGET_ABI_MIPSO32)
 
2716
struct target_sigcontext {
 
2717
    uint32_t   sc_regmask;     /* Unused */
 
2718
    uint32_t   sc_status;
 
2719
    uint64_t   sc_pc;
 
2720
    uint64_t   sc_regs[32];
 
2721
    uint64_t   sc_fpregs[32];
 
2722
    uint32_t   sc_ownedfp;     /* Unused */
 
2723
    uint32_t   sc_fpc_csr;
 
2724
    uint32_t   sc_fpc_eir;     /* Unused */
 
2725
    uint32_t   sc_used_math;
 
2726
    uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
 
2727
    uint32_t   pad0;
 
2728
    uint64_t   sc_mdhi;
 
2729
    uint64_t   sc_mdlo;
 
2730
    target_ulong   sc_hi1;         /* Was sc_cause */
 
2731
    target_ulong   sc_lo1;         /* Was sc_badvaddr */
 
2732
    target_ulong   sc_hi2;         /* Was sc_sigset[4] */
 
2733
    target_ulong   sc_lo2;
 
2734
    target_ulong   sc_hi3;
 
2735
    target_ulong   sc_lo3;
 
2736
};
 
2737
# else /* N32 || N64 */
 
2738
struct target_sigcontext {
 
2739
    uint64_t sc_regs[32];
 
2740
    uint64_t sc_fpregs[32];
 
2741
    uint64_t sc_mdhi;
 
2742
    uint64_t sc_hi1;
 
2743
    uint64_t sc_hi2;
 
2744
    uint64_t sc_hi3;
 
2745
    uint64_t sc_mdlo;
 
2746
    uint64_t sc_lo1;
 
2747
    uint64_t sc_lo2;
 
2748
    uint64_t sc_lo3;
 
2749
    uint64_t sc_pc;
 
2750
    uint32_t sc_fpc_csr;
 
2751
    uint32_t sc_used_math;
 
2752
    uint32_t sc_dsp;
 
2753
    uint32_t sc_reserved;
 
2754
};
 
2755
# endif /* O32 */
 
2756
 
 
2757
struct sigframe {
 
2758
    uint32_t sf_ass[4];                 /* argument save space for o32 */
 
2759
    uint32_t sf_code[2];                        /* signal trampoline */
 
2760
    struct target_sigcontext sf_sc;
 
2761
    target_sigset_t sf_mask;
 
2762
};
 
2763
 
 
2764
struct target_ucontext {
 
2765
    target_ulong tuc_flags;
 
2766
    target_ulong tuc_link;
 
2767
    target_stack_t tuc_stack;
 
2768
    target_ulong pad0;
 
2769
    struct target_sigcontext tuc_mcontext;
 
2770
    target_sigset_t tuc_sigmask;
 
2771
};
 
2772
 
 
2773
struct target_rt_sigframe {
 
2774
    uint32_t rs_ass[4];               /* argument save space for o32 */
 
2775
    uint32_t rs_code[2];              /* signal trampoline */
 
2776
    struct target_siginfo rs_info;
 
2777
    struct target_ucontext rs_uc;
 
2778
};
 
2779
 
 
2780
/* Install trampoline to jump back from signal handler */
 
2781
static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
 
2782
{
 
2783
    int err = 0;
 
2784
 
 
2785
    /*
 
2786
     * Set up the return code ...
 
2787
     *
 
2788
     *         li      v0, __NR__foo_sigreturn
 
2789
     *         syscall
 
2790
     */
 
2791
 
 
2792
    err |= __put_user(0x24020000 + syscall, tramp + 0);
 
2793
    err |= __put_user(0x0000000c          , tramp + 1);
 
2794
    return err;
 
2795
}
 
2796
 
 
2797
static inline int
 
2798
setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
 
2799
{
 
2800
    int err = 0;
 
2801
    int i;
 
2802
 
 
2803
    err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
 
2804
    regs->hflags &= ~MIPS_HFLAG_BMASK;
 
2805
 
 
2806
    __put_user(0, &sc->sc_regs[0]);
 
2807
    for (i = 1; i < 32; ++i) {
 
2808
        err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
 
2809
    }
 
2810
 
 
2811
    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
 
2812
    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
 
2813
 
 
2814
    /* Rather than checking for dsp existence, always copy.  The storage
 
2815
       would just be garbage otherwise.  */
 
2816
    err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
 
2817
    err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
 
2818
    err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
 
2819
    err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
 
2820
    err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
 
2821
    err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
 
2822
    {
 
2823
        uint32_t dsp = cpu_rddsp(0x3ff, regs);
 
2824
        err |= __put_user(dsp, &sc->sc_dsp);
 
2825
    }
 
2826
 
 
2827
    err |= __put_user(1, &sc->sc_used_math);
 
2828
 
 
2829
    for (i = 0; i < 32; ++i) {
 
2830
        err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
 
2831
    }
 
2832
 
 
2833
    return err;
 
2834
}
 
2835
 
 
2836
static inline int
 
2837
restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
 
2838
{
 
2839
    int err = 0;
 
2840
    int i;
 
2841
 
 
2842
    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
 
2843
 
 
2844
    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
 
2845
    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
 
2846
 
 
2847
    for (i = 1; i < 32; ++i) {
 
2848
        err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
 
2849
    }
 
2850
 
 
2851
    err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
 
2852
    err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
 
2853
    err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
 
2854
    err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
 
2855
    err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
 
2856
    err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
 
2857
    {
 
2858
        uint32_t dsp;
 
2859
        err |= __get_user(dsp, &sc->sc_dsp);
 
2860
        cpu_wrdsp(dsp, 0x3ff, regs);
 
2861
    }
 
2862
 
 
2863
    for (i = 0; i < 32; ++i) {
 
2864
        err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
 
2865
    }
 
2866
 
 
2867
    return err;
 
2868
}
 
2869
 
 
2870
/*
 
2871
 * Determine which stack to use..
 
2872
 */
 
2873
static inline abi_ulong
 
2874
get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
 
2875
{
 
2876
    unsigned long sp;
 
2877
 
 
2878
    /* Default to using normal stack */
 
2879
    sp = regs->active_tc.gpr[29];
 
2880
 
 
2881
    /*
 
2882
     * FPU emulator may have its own trampoline active just
 
2883
     * above the user stack, 16-bytes before the next lowest
 
2884
     * 16 byte boundary.  Try to avoid trashing it.
 
2885
     */
 
2886
    sp -= 32;
 
2887
 
 
2888
    /* This is the X/Open sanctioned signal stack switching.  */
 
2889
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
 
2890
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
2891
    }
 
2892
 
 
2893
    return (sp - frame_size) & ~7;
 
2894
}
 
2895
 
 
2896
static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
 
2897
{
 
2898
    if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
 
2899
        env->hflags &= ~MIPS_HFLAG_M16;
 
2900
        env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
 
2901
        env->active_tc.PC &= ~(target_ulong) 1;
 
2902
    }
 
2903
}
 
2904
 
 
2905
# if defined(TARGET_ABI_MIPSO32)
 
2906
/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
 
2907
static void setup_frame(int sig, struct target_sigaction * ka,
 
2908
                        target_sigset_t *set, CPUMIPSState *regs)
 
2909
{
 
2910
    struct sigframe *frame;
 
2911
    abi_ulong frame_addr;
 
2912
    int i;
 
2913
 
 
2914
    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
 
2915
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
2916
        goto give_sigsegv;
 
2917
 
 
2918
    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
 
2919
 
 
2920
    if(setup_sigcontext(regs, &frame->sf_sc))
 
2921
        goto give_sigsegv;
 
2922
 
 
2923
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
2924
        if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
 
2925
            goto give_sigsegv;
 
2926
    }
 
2927
 
 
2928
    /*
 
2929
    * Arguments to signal handler:
 
2930
    *
 
2931
    *   a0 = signal number
 
2932
    *   a1 = 0 (should be cause)
 
2933
    *   a2 = pointer to struct sigcontext
 
2934
    *
 
2935
    * $25 and PC point to the signal handler, $29 points to the
 
2936
    * struct sigframe.
 
2937
    */
 
2938
    regs->active_tc.gpr[ 4] = sig;
 
2939
    regs->active_tc.gpr[ 5] = 0;
 
2940
    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
 
2941
    regs->active_tc.gpr[29] = frame_addr;
 
2942
    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
 
2943
    /* The original kernel code sets CP0_EPC to the handler
 
2944
    * since it returns to userland using eret
 
2945
    * we cannot do this here, and we must set PC directly */
 
2946
    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
 
2947
    mips_set_hflags_isa_mode_from_pc(regs);
 
2948
    unlock_user_struct(frame, frame_addr, 1);
 
2949
    return;
 
2950
 
 
2951
give_sigsegv:
 
2952
    unlock_user_struct(frame, frame_addr, 1);
 
2953
    force_sig(TARGET_SIGSEGV/*, current*/);
 
2954
}
 
2955
 
 
2956
long do_sigreturn(CPUMIPSState *regs)
 
2957
{
 
2958
    struct sigframe *frame;
 
2959
    abi_ulong frame_addr;
 
2960
    sigset_t blocked;
 
2961
    target_sigset_t target_set;
 
2962
    int i;
 
2963
 
 
2964
#if defined(DEBUG_SIGNAL)
 
2965
    fprintf(stderr, "do_sigreturn\n");
 
2966
#endif
 
2967
    frame_addr = regs->active_tc.gpr[29];
 
2968
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
2969
        goto badframe;
 
2970
 
 
2971
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
2972
        if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
 
2973
            goto badframe;
 
2974
    }
 
2975
 
 
2976
    target_to_host_sigset_internal(&blocked, &target_set);
 
2977
    sigprocmask(SIG_SETMASK, &blocked, NULL);
 
2978
 
 
2979
    if (restore_sigcontext(regs, &frame->sf_sc))
 
2980
        goto badframe;
 
2981
 
 
2982
#if 0
 
2983
    /*
 
2984
     * Don't let your children do this ...
 
2985
     */
 
2986
    __asm__ __volatile__(
 
2987
        "move\t$29, %0\n\t"
 
2988
        "j\tsyscall_exit"
 
2989
        :/* no outputs */
 
2990
        :"r" (&regs));
 
2991
    /* Unreached */
 
2992
#endif
 
2993
 
 
2994
    regs->active_tc.PC = regs->CP0_EPC;
 
2995
    mips_set_hflags_isa_mode_from_pc(regs);
 
2996
    /* I am not sure this is right, but it seems to work
 
2997
    * maybe a problem with nested signals ? */
 
2998
    regs->CP0_EPC = 0;
 
2999
    return -TARGET_QEMU_ESIGRETURN;
 
3000
 
 
3001
badframe:
 
3002
    force_sig(TARGET_SIGSEGV/*, current*/);
 
3003
    return 0;
 
3004
}
 
3005
# endif /* O32 */
 
3006
 
 
3007
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
3008
                           target_siginfo_t *info,
 
3009
                           target_sigset_t *set, CPUMIPSState *env)
 
3010
{
 
3011
    struct target_rt_sigframe *frame;
 
3012
    abi_ulong frame_addr;
 
3013
    int i;
 
3014
 
 
3015
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
3016
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
3017
        goto give_sigsegv;
 
3018
 
 
3019
    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
 
3020
 
 
3021
    copy_siginfo_to_user(&frame->rs_info, info);
 
3022
 
 
3023
    __put_user(0, &frame->rs_uc.tuc_flags);
 
3024
    __put_user(0, &frame->rs_uc.tuc_link);
 
3025
    __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
 
3026
    __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
 
3027
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
 
3028
               &frame->rs_uc.tuc_stack.ss_flags);
 
3029
 
 
3030
    setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
 
3031
 
 
3032
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
3033
        __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
 
3034
    }
 
3035
 
 
3036
    /*
 
3037
    * Arguments to signal handler:
 
3038
    *
 
3039
    *   a0 = signal number
 
3040
    *   a1 = pointer to siginfo_t
 
3041
    *   a2 = pointer to struct ucontext
 
3042
    *
 
3043
    * $25 and PC point to the signal handler, $29 points to the
 
3044
    * struct sigframe.
 
3045
    */
 
3046
    env->active_tc.gpr[ 4] = sig;
 
3047
    env->active_tc.gpr[ 5] = frame_addr
 
3048
                             + offsetof(struct target_rt_sigframe, rs_info);
 
3049
    env->active_tc.gpr[ 6] = frame_addr
 
3050
                             + offsetof(struct target_rt_sigframe, rs_uc);
 
3051
    env->active_tc.gpr[29] = frame_addr;
 
3052
    env->active_tc.gpr[31] = frame_addr
 
3053
                             + offsetof(struct target_rt_sigframe, rs_code);
 
3054
    /* The original kernel code sets CP0_EPC to the handler
 
3055
    * since it returns to userland using eret
 
3056
    * we cannot do this here, and we must set PC directly */
 
3057
    env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
 
3058
    mips_set_hflags_isa_mode_from_pc(env);
 
3059
    unlock_user_struct(frame, frame_addr, 1);
 
3060
    return;
 
3061
 
 
3062
give_sigsegv:
 
3063
    unlock_user_struct(frame, frame_addr, 1);
 
3064
    force_sig(TARGET_SIGSEGV/*, current*/);
 
3065
}
 
3066
 
 
3067
long do_rt_sigreturn(CPUMIPSState *env)
 
3068
{
 
3069
    struct target_rt_sigframe *frame;
 
3070
    abi_ulong frame_addr;
 
3071
    sigset_t blocked;
 
3072
 
 
3073
#if defined(DEBUG_SIGNAL)
 
3074
    fprintf(stderr, "do_rt_sigreturn\n");
 
3075
#endif
 
3076
    frame_addr = env->active_tc.gpr[29];
 
3077
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
3078
        goto badframe;
 
3079
 
 
3080
    target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
 
3081
    sigprocmask(SIG_SETMASK, &blocked, NULL);
 
3082
 
 
3083
    if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
 
3084
        goto badframe;
 
3085
 
 
3086
    if (do_sigaltstack(frame_addr +
 
3087
                       offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
 
3088
                       0, get_sp_from_cpustate(env)) == -EFAULT)
 
3089
        goto badframe;
 
3090
 
 
3091
    env->active_tc.PC = env->CP0_EPC;
 
3092
    mips_set_hflags_isa_mode_from_pc(env);
 
3093
    /* I am not sure this is right, but it seems to work
 
3094
    * maybe a problem with nested signals ? */
 
3095
    env->CP0_EPC = 0;
 
3096
    return -TARGET_QEMU_ESIGRETURN;
 
3097
 
 
3098
badframe:
 
3099
    force_sig(TARGET_SIGSEGV/*, current*/);
 
3100
    return 0;
 
3101
}
 
3102
 
 
3103
#elif defined(TARGET_SH4)
 
3104
 
 
3105
/*
 
3106
 * code and data structures from linux kernel:
 
3107
 * include/asm-sh/sigcontext.h
 
3108
 * arch/sh/kernel/signal.c
 
3109
 */
 
3110
 
 
3111
struct target_sigcontext {
 
3112
    target_ulong  oldmask;
 
3113
 
 
3114
    /* CPU registers */
 
3115
    target_ulong  sc_gregs[16];
 
3116
    target_ulong  sc_pc;
 
3117
    target_ulong  sc_pr;
 
3118
    target_ulong  sc_sr;
 
3119
    target_ulong  sc_gbr;
 
3120
    target_ulong  sc_mach;
 
3121
    target_ulong  sc_macl;
 
3122
 
 
3123
    /* FPU registers */
 
3124
    target_ulong  sc_fpregs[16];
 
3125
    target_ulong  sc_xfpregs[16];
 
3126
    unsigned int sc_fpscr;
 
3127
    unsigned int sc_fpul;
 
3128
    unsigned int sc_ownedfp;
 
3129
};
 
3130
 
 
3131
struct target_sigframe
 
3132
{
 
3133
    struct target_sigcontext sc;
 
3134
    target_ulong extramask[TARGET_NSIG_WORDS-1];
 
3135
    uint16_t retcode[3];
 
3136
};
 
3137
 
 
3138
 
 
3139
struct target_ucontext {
 
3140
    target_ulong tuc_flags;
 
3141
    struct target_ucontext *tuc_link;
 
3142
    target_stack_t tuc_stack;
 
3143
    struct target_sigcontext tuc_mcontext;
 
3144
    target_sigset_t tuc_sigmask;        /* mask last for extensibility */
 
3145
};
 
3146
 
 
3147
struct target_rt_sigframe
 
3148
{
 
3149
    struct target_siginfo info;
 
3150
    struct target_ucontext uc;
 
3151
    uint16_t retcode[3];
 
3152
};
 
3153
 
 
3154
 
 
3155
#define MOVW(n)  (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
 
3156
#define TRAP_NOARG 0xc310         /* Syscall w/no args (NR in R3) SH3/4 */
 
3157
 
 
3158
static abi_ulong get_sigframe(struct target_sigaction *ka,
 
3159
                         unsigned long sp, size_t frame_size)
 
3160
{
 
3161
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
 
3162
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
3163
    }
 
3164
 
 
3165
    return (sp - frame_size) & -8ul;
 
3166
}
 
3167
 
 
3168
static int setup_sigcontext(struct target_sigcontext *sc,
 
3169
                            CPUSH4State *regs, unsigned long mask)
 
3170
{
 
3171
    int err = 0;
 
3172
    int i;
 
3173
 
 
3174
#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
 
3175
    COPY(gregs[0]); COPY(gregs[1]);
 
3176
    COPY(gregs[2]); COPY(gregs[3]);
 
3177
    COPY(gregs[4]); COPY(gregs[5]);
 
3178
    COPY(gregs[6]); COPY(gregs[7]);
 
3179
    COPY(gregs[8]); COPY(gregs[9]);
 
3180
    COPY(gregs[10]); COPY(gregs[11]);
 
3181
    COPY(gregs[12]); COPY(gregs[13]);
 
3182
    COPY(gregs[14]); COPY(gregs[15]);
 
3183
    COPY(gbr); COPY(mach);
 
3184
    COPY(macl); COPY(pr);
 
3185
    COPY(sr); COPY(pc);
 
3186
#undef COPY
 
3187
 
 
3188
    for (i=0; i<16; i++) {
 
3189
        err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
 
3190
    }
 
3191
    err |= __put_user(regs->fpscr, &sc->sc_fpscr);
 
3192
    err |= __put_user(regs->fpul, &sc->sc_fpul);
 
3193
 
 
3194
    /* non-iBCS2 extensions.. */
 
3195
    err |= __put_user(mask, &sc->oldmask);
 
3196
 
 
3197
    return err;
 
3198
}
 
3199
 
 
3200
static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
 
3201
                              target_ulong *r0_p)
 
3202
{
 
3203
    unsigned int err = 0;
 
3204
    int i;
 
3205
 
 
3206
#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
 
3207
    COPY(gregs[1]);
 
3208
    COPY(gregs[2]); COPY(gregs[3]);
 
3209
    COPY(gregs[4]); COPY(gregs[5]);
 
3210
    COPY(gregs[6]); COPY(gregs[7]);
 
3211
    COPY(gregs[8]); COPY(gregs[9]);
 
3212
    COPY(gregs[10]); COPY(gregs[11]);
 
3213
    COPY(gregs[12]); COPY(gregs[13]);
 
3214
    COPY(gregs[14]); COPY(gregs[15]);
 
3215
    COPY(gbr); COPY(mach);
 
3216
    COPY(macl); COPY(pr);
 
3217
    COPY(sr); COPY(pc);
 
3218
#undef COPY
 
3219
 
 
3220
    for (i=0; i<16; i++) {
 
3221
        err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
 
3222
    }
 
3223
    err |= __get_user(regs->fpscr, &sc->sc_fpscr);
 
3224
    err |= __get_user(regs->fpul, &sc->sc_fpul);
 
3225
 
 
3226
    regs->tra = -1;         /* disable syscall checks */
 
3227
    err |= __get_user(*r0_p, &sc->sc_gregs[0]);
 
3228
    return err;
 
3229
}
 
3230
 
 
3231
static void setup_frame(int sig, struct target_sigaction *ka,
 
3232
                        target_sigset_t *set, CPUSH4State *regs)
 
3233
{
 
3234
    struct target_sigframe *frame;
 
3235
    abi_ulong frame_addr;
 
3236
    int i;
 
3237
    int err = 0;
 
3238
    int signal;
 
3239
 
 
3240
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
 
3241
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
3242
        goto give_sigsegv;
 
3243
 
 
3244
    signal = current_exec_domain_sig(sig);
 
3245
 
 
3246
    err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
 
3247
 
 
3248
    for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
 
3249
        err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
 
3250
    }
 
3251
 
 
3252
    /* Set up to return from userspace.  If provided, use a stub
 
3253
       already in userspace.  */
 
3254
    if (ka->sa_flags & TARGET_SA_RESTORER) {
 
3255
        regs->pr = (unsigned long) ka->sa_restorer;
 
3256
    } else {
 
3257
        /* Generate return code (system call to sigreturn) */
 
3258
        err |= __put_user(MOVW(2), &frame->retcode[0]);
 
3259
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
 
3260
        err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
 
3261
        regs->pr = (unsigned long) frame->retcode;
 
3262
    }
 
3263
 
 
3264
    if (err)
 
3265
        goto give_sigsegv;
 
3266
 
 
3267
    /* Set up registers for signal handler */
 
3268
    regs->gregs[15] = frame_addr;
 
3269
    regs->gregs[4] = signal; /* Arg for signal handler */
 
3270
    regs->gregs[5] = 0;
 
3271
    regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
 
3272
    regs->pc = (unsigned long) ka->_sa_handler;
 
3273
 
 
3274
    unlock_user_struct(frame, frame_addr, 1);
 
3275
    return;
 
3276
 
 
3277
give_sigsegv:
 
3278
    unlock_user_struct(frame, frame_addr, 1);
 
3279
    force_sig(TARGET_SIGSEGV);
 
3280
}
 
3281
 
 
3282
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
3283
                           target_siginfo_t *info,
 
3284
                           target_sigset_t *set, CPUSH4State *regs)
 
3285
{
 
3286
    struct target_rt_sigframe *frame;
 
3287
    abi_ulong frame_addr;
 
3288
    int i;
 
3289
    int err = 0;
 
3290
    int signal;
 
3291
 
 
3292
    frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
 
3293
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
3294
        goto give_sigsegv;
 
3295
 
 
3296
    signal = current_exec_domain_sig(sig);
 
3297
 
 
3298
    err |= copy_siginfo_to_user(&frame->info, info);
 
3299
 
 
3300
    /* Create the ucontext.  */
 
3301
    err |= __put_user(0, &frame->uc.tuc_flags);
 
3302
    err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
 
3303
    err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
 
3304
                      &frame->uc.tuc_stack.ss_sp);
 
3305
    err |= __put_user(sas_ss_flags(regs->gregs[15]),
 
3306
                      &frame->uc.tuc_stack.ss_flags);
 
3307
    err |= __put_user(target_sigaltstack_used.ss_size,
 
3308
                      &frame->uc.tuc_stack.ss_size);
 
3309
    err |= setup_sigcontext(&frame->uc.tuc_mcontext,
 
3310
                            regs, set->sig[0]);
 
3311
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
3312
        err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
 
3313
    }
 
3314
 
 
3315
    /* Set up to return from userspace.  If provided, use a stub
 
3316
       already in userspace.  */
 
3317
    if (ka->sa_flags & TARGET_SA_RESTORER) {
 
3318
        regs->pr = (unsigned long) ka->sa_restorer;
 
3319
    } else {
 
3320
        /* Generate return code (system call to sigreturn) */
 
3321
        err |= __put_user(MOVW(2), &frame->retcode[0]);
 
3322
        err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
 
3323
        err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
 
3324
        regs->pr = (unsigned long) frame->retcode;
 
3325
    }
 
3326
 
 
3327
    if (err)
 
3328
        goto give_sigsegv;
 
3329
 
 
3330
    /* Set up registers for signal handler */
 
3331
    regs->gregs[15] = frame_addr;
 
3332
    regs->gregs[4] = signal; /* Arg for signal handler */
 
3333
    regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
 
3334
    regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
 
3335
    regs->pc = (unsigned long) ka->_sa_handler;
 
3336
 
 
3337
    unlock_user_struct(frame, frame_addr, 1);
 
3338
    return;
 
3339
 
 
3340
give_sigsegv:
 
3341
    unlock_user_struct(frame, frame_addr, 1);
 
3342
    force_sig(TARGET_SIGSEGV);
 
3343
}
 
3344
 
 
3345
long do_sigreturn(CPUSH4State *regs)
 
3346
{
 
3347
    struct target_sigframe *frame;
 
3348
    abi_ulong frame_addr;
 
3349
    sigset_t blocked;
 
3350
    target_sigset_t target_set;
 
3351
    target_ulong r0;
 
3352
    int i;
 
3353
    int err = 0;
 
3354
 
 
3355
#if defined(DEBUG_SIGNAL)
 
3356
    fprintf(stderr, "do_sigreturn\n");
 
3357
#endif
 
3358
    frame_addr = regs->gregs[15];
 
3359
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
3360
        goto badframe;
 
3361
 
 
3362
    err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
 
3363
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
3364
        err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
 
3365
    }
 
3366
 
 
3367
    if (err)
 
3368
        goto badframe;
 
3369
 
 
3370
    target_to_host_sigset_internal(&blocked, &target_set);
 
3371
    sigprocmask(SIG_SETMASK, &blocked, NULL);
 
3372
 
 
3373
    if (restore_sigcontext(regs, &frame->sc, &r0))
 
3374
        goto badframe;
 
3375
 
 
3376
    unlock_user_struct(frame, frame_addr, 0);
 
3377
    return r0;
 
3378
 
 
3379
badframe:
 
3380
    unlock_user_struct(frame, frame_addr, 0);
 
3381
    force_sig(TARGET_SIGSEGV);
 
3382
    return 0;
 
3383
}
 
3384
 
 
3385
long do_rt_sigreturn(CPUSH4State *regs)
 
3386
{
 
3387
    struct target_rt_sigframe *frame;
 
3388
    abi_ulong frame_addr;
 
3389
    sigset_t blocked;
 
3390
    target_ulong r0;
 
3391
 
 
3392
#if defined(DEBUG_SIGNAL)
 
3393
    fprintf(stderr, "do_rt_sigreturn\n");
 
3394
#endif
 
3395
    frame_addr = regs->gregs[15];
 
3396
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
3397
        goto badframe;
 
3398
 
 
3399
    target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
 
3400
    sigprocmask(SIG_SETMASK, &blocked, NULL);
 
3401
 
 
3402
    if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
 
3403
        goto badframe;
 
3404
 
 
3405
    if (do_sigaltstack(frame_addr +
 
3406
                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
 
3407
                       0, get_sp_from_cpustate(regs)) == -EFAULT)
 
3408
        goto badframe;
 
3409
 
 
3410
    unlock_user_struct(frame, frame_addr, 0);
 
3411
    return r0;
 
3412
 
 
3413
badframe:
 
3414
    unlock_user_struct(frame, frame_addr, 0);
 
3415
    force_sig(TARGET_SIGSEGV);
 
3416
    return 0;
 
3417
}
 
3418
#elif defined(TARGET_MICROBLAZE)
 
3419
 
 
3420
struct target_sigcontext {
 
3421
    struct target_pt_regs regs;  /* needs to be first */
 
3422
    uint32_t oldmask;
 
3423
};
 
3424
 
 
3425
struct target_stack_t {
 
3426
    abi_ulong ss_sp;
 
3427
    int ss_flags;
 
3428
    unsigned int ss_size;
 
3429
};
 
3430
 
 
3431
struct target_ucontext {
 
3432
    abi_ulong tuc_flags;
 
3433
    abi_ulong tuc_link;
 
3434
    struct target_stack_t tuc_stack;
 
3435
    struct target_sigcontext tuc_mcontext;
 
3436
    uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
 
3437
};
 
3438
 
 
3439
/* Signal frames. */
 
3440
struct target_signal_frame {
 
3441
    struct target_ucontext uc;
 
3442
    uint32_t extramask[TARGET_NSIG_WORDS - 1];
 
3443
    uint32_t tramp[2];
 
3444
};
 
3445
 
 
3446
struct rt_signal_frame {
 
3447
    siginfo_t info;
 
3448
    struct ucontext uc;
 
3449
    uint32_t tramp[2];
 
3450
};
 
3451
 
 
3452
static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
 
3453
{
 
3454
    __put_user(env->regs[0], &sc->regs.r0);
 
3455
    __put_user(env->regs[1], &sc->regs.r1);
 
3456
    __put_user(env->regs[2], &sc->regs.r2);
 
3457
    __put_user(env->regs[3], &sc->regs.r3);
 
3458
    __put_user(env->regs[4], &sc->regs.r4);
 
3459
    __put_user(env->regs[5], &sc->regs.r5);
 
3460
    __put_user(env->regs[6], &sc->regs.r6);
 
3461
    __put_user(env->regs[7], &sc->regs.r7);
 
3462
    __put_user(env->regs[8], &sc->regs.r8);
 
3463
    __put_user(env->regs[9], &sc->regs.r9);
 
3464
    __put_user(env->regs[10], &sc->regs.r10);
 
3465
    __put_user(env->regs[11], &sc->regs.r11);
 
3466
    __put_user(env->regs[12], &sc->regs.r12);
 
3467
    __put_user(env->regs[13], &sc->regs.r13);
 
3468
    __put_user(env->regs[14], &sc->regs.r14);
 
3469
    __put_user(env->regs[15], &sc->regs.r15);
 
3470
    __put_user(env->regs[16], &sc->regs.r16);
 
3471
    __put_user(env->regs[17], &sc->regs.r17);
 
3472
    __put_user(env->regs[18], &sc->regs.r18);
 
3473
    __put_user(env->regs[19], &sc->regs.r19);
 
3474
    __put_user(env->regs[20], &sc->regs.r20);
 
3475
    __put_user(env->regs[21], &sc->regs.r21);
 
3476
    __put_user(env->regs[22], &sc->regs.r22);
 
3477
    __put_user(env->regs[23], &sc->regs.r23);
 
3478
    __put_user(env->regs[24], &sc->regs.r24);
 
3479
    __put_user(env->regs[25], &sc->regs.r25);
 
3480
    __put_user(env->regs[26], &sc->regs.r26);
 
3481
    __put_user(env->regs[27], &sc->regs.r27);
 
3482
    __put_user(env->regs[28], &sc->regs.r28);
 
3483
    __put_user(env->regs[29], &sc->regs.r29);
 
3484
    __put_user(env->regs[30], &sc->regs.r30);
 
3485
    __put_user(env->regs[31], &sc->regs.r31);
 
3486
    __put_user(env->sregs[SR_PC], &sc->regs.pc);
 
3487
}
 
3488
 
 
3489
static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
 
3490
{
 
3491
    __get_user(env->regs[0], &sc->regs.r0);
 
3492
    __get_user(env->regs[1], &sc->regs.r1);
 
3493
    __get_user(env->regs[2], &sc->regs.r2);
 
3494
    __get_user(env->regs[3], &sc->regs.r3);
 
3495
    __get_user(env->regs[4], &sc->regs.r4);
 
3496
    __get_user(env->regs[5], &sc->regs.r5);
 
3497
    __get_user(env->regs[6], &sc->regs.r6);
 
3498
    __get_user(env->regs[7], &sc->regs.r7);
 
3499
    __get_user(env->regs[8], &sc->regs.r8);
 
3500
    __get_user(env->regs[9], &sc->regs.r9);
 
3501
    __get_user(env->regs[10], &sc->regs.r10);
 
3502
    __get_user(env->regs[11], &sc->regs.r11);
 
3503
    __get_user(env->regs[12], &sc->regs.r12);
 
3504
    __get_user(env->regs[13], &sc->regs.r13);
 
3505
    __get_user(env->regs[14], &sc->regs.r14);
 
3506
    __get_user(env->regs[15], &sc->regs.r15);
 
3507
    __get_user(env->regs[16], &sc->regs.r16);
 
3508
    __get_user(env->regs[17], &sc->regs.r17);
 
3509
    __get_user(env->regs[18], &sc->regs.r18);
 
3510
    __get_user(env->regs[19], &sc->regs.r19);
 
3511
    __get_user(env->regs[20], &sc->regs.r20);
 
3512
    __get_user(env->regs[21], &sc->regs.r21);
 
3513
    __get_user(env->regs[22], &sc->regs.r22);
 
3514
    __get_user(env->regs[23], &sc->regs.r23);
 
3515
    __get_user(env->regs[24], &sc->regs.r24);
 
3516
    __get_user(env->regs[25], &sc->regs.r25);
 
3517
    __get_user(env->regs[26], &sc->regs.r26);
 
3518
    __get_user(env->regs[27], &sc->regs.r27);
 
3519
    __get_user(env->regs[28], &sc->regs.r28);
 
3520
    __get_user(env->regs[29], &sc->regs.r29);
 
3521
    __get_user(env->regs[30], &sc->regs.r30);
 
3522
    __get_user(env->regs[31], &sc->regs.r31);
 
3523
    __get_user(env->sregs[SR_PC], &sc->regs.pc);
 
3524
}
 
3525
 
 
3526
static abi_ulong get_sigframe(struct target_sigaction *ka,
 
3527
                              CPUMBState *env, int frame_size)
 
3528
{
 
3529
    abi_ulong sp = env->regs[1];
 
3530
 
 
3531
    if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
 
3532
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
3533
 
 
3534
    return ((sp - frame_size) & -8UL);
 
3535
}
 
3536
 
 
3537
static void setup_frame(int sig, struct target_sigaction *ka,
 
3538
                        target_sigset_t *set, CPUMBState *env)
 
3539
{
 
3540
    struct target_signal_frame *frame;
 
3541
    abi_ulong frame_addr;
 
3542
    int err = 0;
 
3543
    int i;
 
3544
 
 
3545
    frame_addr = get_sigframe(ka, env, sizeof *frame);
 
3546
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
3547
        goto badframe;
 
3548
 
 
3549
    /* Save the mask.  */
 
3550
    err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
 
3551
    if (err)
 
3552
        goto badframe;
 
3553
 
 
3554
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
3555
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
 
3556
            goto badframe;
 
3557
    }
 
3558
 
 
3559
    setup_sigcontext(&frame->uc.tuc_mcontext, env);
 
3560
 
 
3561
    /* Set up to return from userspace. If provided, use a stub
 
3562
       already in userspace. */
 
3563
    /* minus 8 is offset to cater for "rtsd r15,8" offset */
 
3564
    if (ka->sa_flags & TARGET_SA_RESTORER) {
 
3565
        env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
 
3566
    } else {
 
3567
        uint32_t t;
 
3568
        /* Note, these encodings are _big endian_! */
 
3569
        /* addi r12, r0, __NR_sigreturn */
 
3570
        t = 0x31800000UL | TARGET_NR_sigreturn;
 
3571
        err |= __put_user(t, frame->tramp + 0);
 
3572
        /* brki r14, 0x8 */
 
3573
        t = 0xb9cc0008UL;
 
3574
        err |= __put_user(t, frame->tramp + 1);
 
3575
 
 
3576
        /* Return from sighandler will jump to the tramp.
 
3577
           Negative 8 offset because return is rtsd r15, 8 */
 
3578
        env->regs[15] = ((unsigned long)frame->tramp) - 8;
 
3579
    }
 
3580
 
 
3581
    if (err)
 
3582
        goto badframe;
 
3583
 
 
3584
    /* Set up registers for signal handler */
 
3585
    env->regs[1] = frame_addr;
 
3586
    /* Signal handler args: */
 
3587
    env->regs[5] = sig; /* Arg 0: signum */
 
3588
    env->regs[6] = 0;
 
3589
    /* arg 1: sigcontext */
 
3590
    env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
 
3591
 
 
3592
    /* Offset of 4 to handle microblaze rtid r14, 0 */
 
3593
    env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
 
3594
 
 
3595
    unlock_user_struct(frame, frame_addr, 1);
 
3596
    return;
 
3597
  badframe:
 
3598
    unlock_user_struct(frame, frame_addr, 1);
 
3599
    force_sig(TARGET_SIGSEGV);
 
3600
}
 
3601
 
 
3602
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
3603
                           target_siginfo_t *info,
 
3604
                           target_sigset_t *set, CPUMBState *env)
 
3605
{
 
3606
    fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
 
3607
}
 
3608
 
 
3609
long do_sigreturn(CPUMBState *env)
 
3610
{
 
3611
    struct target_signal_frame *frame;
 
3612
    abi_ulong frame_addr;
 
3613
    target_sigset_t target_set;
 
3614
    sigset_t set;
 
3615
    int i;
 
3616
 
 
3617
    frame_addr = env->regs[R_SP];
 
3618
    /* Make sure the guest isn't playing games.  */
 
3619
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
 
3620
        goto badframe;
 
3621
 
 
3622
    /* Restore blocked signals */
 
3623
    if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
 
3624
        goto badframe;
 
3625
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
3626
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
 
3627
            goto badframe;
 
3628
    }
 
3629
    target_to_host_sigset_internal(&set, &target_set);
 
3630
    sigprocmask(SIG_SETMASK, &set, NULL);
 
3631
 
 
3632
    restore_sigcontext(&frame->uc.tuc_mcontext, env);
 
3633
    /* We got here through a sigreturn syscall, our path back is via an
 
3634
       rtb insn so setup r14 for that.  */
 
3635
    env->regs[14] = env->sregs[SR_PC];
 
3636
 
 
3637
    unlock_user_struct(frame, frame_addr, 0);
 
3638
    return env->regs[10];
 
3639
  badframe:
 
3640
    unlock_user_struct(frame, frame_addr, 0);
 
3641
    force_sig(TARGET_SIGSEGV);
 
3642
}
 
3643
 
 
3644
long do_rt_sigreturn(CPUMBState *env)
 
3645
{
 
3646
    fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
 
3647
    return -TARGET_ENOSYS;
 
3648
}
 
3649
 
 
3650
#elif defined(TARGET_CRIS)
 
3651
 
 
3652
struct target_sigcontext {
 
3653
        struct target_pt_regs regs;  /* needs to be first */
 
3654
        uint32_t oldmask;
 
3655
        uint32_t usp;    /* usp before stacking this gunk on it */
 
3656
};
 
3657
 
 
3658
/* Signal frames. */
 
3659
struct target_signal_frame {
 
3660
        struct target_sigcontext sc;
 
3661
        uint32_t extramask[TARGET_NSIG_WORDS - 1];
 
3662
        uint8_t retcode[8];       /* Trampoline code. */
 
3663
};
 
3664
 
 
3665
struct rt_signal_frame {
 
3666
        siginfo_t *pinfo;
 
3667
        void *puc;
 
3668
        siginfo_t info;
 
3669
        struct ucontext uc;
 
3670
        uint8_t retcode[8];       /* Trampoline code. */
 
3671
};
 
3672
 
 
3673
static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
 
3674
{
 
3675
        __put_user(env->regs[0], &sc->regs.r0);
 
3676
        __put_user(env->regs[1], &sc->regs.r1);
 
3677
        __put_user(env->regs[2], &sc->regs.r2);
 
3678
        __put_user(env->regs[3], &sc->regs.r3);
 
3679
        __put_user(env->regs[4], &sc->regs.r4);
 
3680
        __put_user(env->regs[5], &sc->regs.r5);
 
3681
        __put_user(env->regs[6], &sc->regs.r6);
 
3682
        __put_user(env->regs[7], &sc->regs.r7);
 
3683
        __put_user(env->regs[8], &sc->regs.r8);
 
3684
        __put_user(env->regs[9], &sc->regs.r9);
 
3685
        __put_user(env->regs[10], &sc->regs.r10);
 
3686
        __put_user(env->regs[11], &sc->regs.r11);
 
3687
        __put_user(env->regs[12], &sc->regs.r12);
 
3688
        __put_user(env->regs[13], &sc->regs.r13);
 
3689
        __put_user(env->regs[14], &sc->usp);
 
3690
        __put_user(env->regs[15], &sc->regs.acr);
 
3691
        __put_user(env->pregs[PR_MOF], &sc->regs.mof);
 
3692
        __put_user(env->pregs[PR_SRP], &sc->regs.srp);
 
3693
        __put_user(env->pc, &sc->regs.erp);
 
3694
}
 
3695
 
 
3696
static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
 
3697
{
 
3698
        __get_user(env->regs[0], &sc->regs.r0);
 
3699
        __get_user(env->regs[1], &sc->regs.r1);
 
3700
        __get_user(env->regs[2], &sc->regs.r2);
 
3701
        __get_user(env->regs[3], &sc->regs.r3);
 
3702
        __get_user(env->regs[4], &sc->regs.r4);
 
3703
        __get_user(env->regs[5], &sc->regs.r5);
 
3704
        __get_user(env->regs[6], &sc->regs.r6);
 
3705
        __get_user(env->regs[7], &sc->regs.r7);
 
3706
        __get_user(env->regs[8], &sc->regs.r8);
 
3707
        __get_user(env->regs[9], &sc->regs.r9);
 
3708
        __get_user(env->regs[10], &sc->regs.r10);
 
3709
        __get_user(env->regs[11], &sc->regs.r11);
 
3710
        __get_user(env->regs[12], &sc->regs.r12);
 
3711
        __get_user(env->regs[13], &sc->regs.r13);
 
3712
        __get_user(env->regs[14], &sc->usp);
 
3713
        __get_user(env->regs[15], &sc->regs.acr);
 
3714
        __get_user(env->pregs[PR_MOF], &sc->regs.mof);
 
3715
        __get_user(env->pregs[PR_SRP], &sc->regs.srp);
 
3716
        __get_user(env->pc, &sc->regs.erp);
 
3717
}
 
3718
 
 
3719
static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
 
3720
{
 
3721
        abi_ulong sp;
 
3722
        /* Align the stack downwards to 4.  */
 
3723
        sp = (env->regs[R_SP] & ~3);
 
3724
        return sp - framesize;
 
3725
}
 
3726
 
 
3727
static void setup_frame(int sig, struct target_sigaction *ka,
 
3728
                        target_sigset_t *set, CPUCRISState *env)
 
3729
{
 
3730
        struct target_signal_frame *frame;
 
3731
        abi_ulong frame_addr;
 
3732
        int err = 0;
 
3733
        int i;
 
3734
 
 
3735
        frame_addr = get_sigframe(env, sizeof *frame);
 
3736
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
3737
                goto badframe;
 
3738
 
 
3739
        /*
 
3740
         * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
 
3741
         * use this trampoline anymore but it sets it up for GDB.
 
3742
         * In QEMU, using the trampoline simplifies things a bit so we use it.
 
3743
         *
 
3744
         * This is movu.w __NR_sigreturn, r9; break 13;
 
3745
         */
 
3746
        err |= __put_user(0x9c5f, frame->retcode+0);
 
3747
        err |= __put_user(TARGET_NR_sigreturn, 
 
3748
                          frame->retcode+2);
 
3749
        err |= __put_user(0xe93d, frame->retcode+4);
 
3750
 
 
3751
        /* Save the mask.  */
 
3752
        err |= __put_user(set->sig[0], &frame->sc.oldmask);
 
3753
        if (err)
 
3754
                goto badframe;
 
3755
 
 
3756
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
3757
                if (__put_user(set->sig[i], &frame->extramask[i - 1]))
 
3758
                        goto badframe;
 
3759
        }
 
3760
 
 
3761
        setup_sigcontext(&frame->sc, env);
 
3762
 
 
3763
        /* Move the stack and setup the arguments for the handler.  */
 
3764
        env->regs[R_SP] = frame_addr;
 
3765
        env->regs[10] = sig;
 
3766
        env->pc = (unsigned long) ka->_sa_handler;
 
3767
        /* Link SRP so the guest returns through the trampoline.  */
 
3768
        env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
 
3769
 
 
3770
        unlock_user_struct(frame, frame_addr, 1);
 
3771
        return;
 
3772
  badframe:
 
3773
        unlock_user_struct(frame, frame_addr, 1);
 
3774
        force_sig(TARGET_SIGSEGV);
 
3775
}
 
3776
 
 
3777
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
3778
                           target_siginfo_t *info,
 
3779
                           target_sigset_t *set, CPUCRISState *env)
 
3780
{
 
3781
    fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
 
3782
}
 
3783
 
 
3784
long do_sigreturn(CPUCRISState *env)
 
3785
{
 
3786
        struct target_signal_frame *frame;
 
3787
        abi_ulong frame_addr;
 
3788
        target_sigset_t target_set;
 
3789
        sigset_t set;
 
3790
        int i;
 
3791
 
 
3792
        frame_addr = env->regs[R_SP];
 
3793
        /* Make sure the guest isn't playing games.  */
 
3794
        if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
 
3795
                goto badframe;
 
3796
 
 
3797
        /* Restore blocked signals */
 
3798
        if (__get_user(target_set.sig[0], &frame->sc.oldmask))
 
3799
                goto badframe;
 
3800
        for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
3801
                if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
 
3802
                        goto badframe;
 
3803
        }
 
3804
        target_to_host_sigset_internal(&set, &target_set);
 
3805
        sigprocmask(SIG_SETMASK, &set, NULL);
 
3806
 
 
3807
        restore_sigcontext(&frame->sc, env);
 
3808
        unlock_user_struct(frame, frame_addr, 0);
 
3809
        return env->regs[10];
 
3810
  badframe:
 
3811
        unlock_user_struct(frame, frame_addr, 0);
 
3812
        force_sig(TARGET_SIGSEGV);
 
3813
}
 
3814
 
 
3815
long do_rt_sigreturn(CPUCRISState *env)
 
3816
{
 
3817
    fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
 
3818
    return -TARGET_ENOSYS;
 
3819
}
 
3820
 
 
3821
#elif defined(TARGET_OPENRISC)
 
3822
 
 
3823
struct target_sigcontext {
 
3824
    struct target_pt_regs regs;
 
3825
    abi_ulong oldmask;
 
3826
    abi_ulong usp;
 
3827
};
 
3828
 
 
3829
struct target_ucontext {
 
3830
    abi_ulong tuc_flags;
 
3831
    abi_ulong tuc_link;
 
3832
    target_stack_t tuc_stack;
 
3833
    struct target_sigcontext tuc_mcontext;
 
3834
    target_sigset_t tuc_sigmask;   /* mask last for extensibility */
 
3835
};
 
3836
 
 
3837
struct target_rt_sigframe {
 
3838
    abi_ulong pinfo;
 
3839
    uint64_t puc;
 
3840
    struct target_siginfo info;
 
3841
    struct target_sigcontext sc;
 
3842
    struct target_ucontext uc;
 
3843
    unsigned char retcode[16];  /* trampoline code */
 
3844
};
 
3845
 
 
3846
/* This is the asm-generic/ucontext.h version */
 
3847
#if 0
 
3848
static int restore_sigcontext(CPUOpenRISCState *regs,
 
3849
                              struct target_sigcontext *sc)
 
3850
{
 
3851
    unsigned int err = 0;
 
3852
    unsigned long old_usp;
 
3853
 
 
3854
    /* Alwys make any pending restarted system call return -EINTR */
 
3855
    current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
3856
 
 
3857
    /* restore the regs from &sc->regs (same as sc, since regs is first)
 
3858
     * (sc is already checked for VERIFY_READ since the sigframe was
 
3859
     *  checked in sys_sigreturn previously)
 
3860
     */
 
3861
 
 
3862
    if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
 
3863
        goto badframe;
 
3864
    }
 
3865
 
 
3866
    /* make sure the U-flag is set so user-mode cannot fool us */
 
3867
 
 
3868
    regs->sr &= ~SR_SM;
 
3869
 
 
3870
    /* restore the old USP as it was before we stacked the sc etc.
 
3871
     * (we cannot just pop the sigcontext since we aligned the sp and
 
3872
     *  stuff after pushing it)
 
3873
     */
 
3874
 
 
3875
    err |= __get_user(old_usp, &sc->usp);
 
3876
    phx_signal("old_usp 0x%lx", old_usp);
 
3877
 
 
3878
    __PHX__ REALLY           /* ??? */
 
3879
    wrusp(old_usp);
 
3880
    regs->gpr[1] = old_usp;
 
3881
 
 
3882
    /* TODO: the other ports use regs->orig_XX to disable syscall checks
 
3883
     * after this completes, but we don't use that mechanism. maybe we can
 
3884
     * use it now ?
 
3885
     */
 
3886
 
 
3887
    return err;
 
3888
 
 
3889
badframe:
 
3890
    return 1;
 
3891
}
 
3892
#endif
 
3893
 
 
3894
/* Set up a signal frame.  */
 
3895
 
 
3896
static int setup_sigcontext(struct target_sigcontext *sc,
 
3897
                            CPUOpenRISCState *regs,
 
3898
                            unsigned long mask)
 
3899
{
 
3900
    int err = 0;
 
3901
    unsigned long usp = regs->gpr[1];
 
3902
 
 
3903
    /* copy the regs. they are first in sc so we can use sc directly */
 
3904
 
 
3905
    /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
 
3906
 
 
3907
    /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
 
3908
       the signal handler. The frametype will be restored to its previous
 
3909
       value in restore_sigcontext. */
 
3910
    /*regs->frametype = CRIS_FRAME_NORMAL;*/
 
3911
 
 
3912
    /* then some other stuff */
 
3913
    err |= __put_user(mask, &sc->oldmask);
 
3914
    err |= __put_user(usp, &sc->usp); return err;
 
3915
}
 
3916
 
 
3917
static inline unsigned long align_sigframe(unsigned long sp)
 
3918
{
 
3919
    unsigned long i;
 
3920
    i = sp & ~3UL;
 
3921
    return i;
 
3922
}
 
3923
 
 
3924
static inline abi_ulong get_sigframe(struct target_sigaction *ka,
 
3925
                                     CPUOpenRISCState *regs,
 
3926
                                     size_t frame_size)
 
3927
{
 
3928
    unsigned long sp = regs->gpr[1];
 
3929
    int onsigstack = on_sig_stack(sp);
 
3930
 
 
3931
    /* redzone */
 
3932
    /* This is the X/Open sanctioned signal stack switching.  */
 
3933
    if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
 
3934
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
3935
    }
 
3936
 
 
3937
    sp = align_sigframe(sp - frame_size);
 
3938
 
 
3939
    /*
 
3940
     * If we are on the alternate signal stack and would overflow it, don't.
 
3941
     * Return an always-bogus address instead so we will die with SIGSEGV.
 
3942
     */
 
3943
 
 
3944
    if (onsigstack && !likely(on_sig_stack(sp))) {
 
3945
        return -1L;
 
3946
    }
 
3947
 
 
3948
    return sp;
 
3949
}
 
3950
 
 
3951
static void setup_frame(int sig, struct target_sigaction *ka,
 
3952
                        target_sigset_t *set, CPUOpenRISCState *env)
 
3953
{
 
3954
    qemu_log("Not implement.\n");
 
3955
}
 
3956
 
 
3957
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
3958
                           target_siginfo_t *info,
 
3959
                           target_sigset_t *set, CPUOpenRISCState *env)
 
3960
{
 
3961
    int err = 0;
 
3962
    abi_ulong frame_addr;
 
3963
    unsigned long return_ip;
 
3964
    struct target_rt_sigframe *frame;
 
3965
    abi_ulong info_addr, uc_addr;
 
3966
 
 
3967
    frame_addr = get_sigframe(ka, env, sizeof *frame);
 
3968
 
 
3969
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
3970
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
 
3971
        goto give_sigsegv;
 
3972
    }
 
3973
 
 
3974
    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
 
3975
    err |= __put_user(info_addr, &frame->pinfo);
 
3976
    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
 
3977
    err |= __put_user(uc_addr, &frame->puc);
 
3978
 
 
3979
    if (ka->sa_flags & SA_SIGINFO) {
 
3980
        err |= copy_siginfo_to_user(&frame->info, info);
 
3981
    }
 
3982
    if (err) {
 
3983
        goto give_sigsegv;
 
3984
    }
 
3985
 
 
3986
    /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
 
3987
    err |= __put_user(0, &frame->uc.tuc_flags);
 
3988
    err |= __put_user(0, &frame->uc.tuc_link);
 
3989
    err |= __put_user(target_sigaltstack_used.ss_sp,
 
3990
                      &frame->uc.tuc_stack.ss_sp);
 
3991
    err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
 
3992
    err |= __put_user(target_sigaltstack_used.ss_size,
 
3993
                      &frame->uc.tuc_stack.ss_size);
 
3994
    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
 
3995
 
 
3996
    /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
 
3997
 
 
3998
    if (err) {
 
3999
        goto give_sigsegv;
 
4000
    }
 
4001
 
 
4002
    /* trampoline - the desired return ip is the retcode itself */
 
4003
    return_ip = (unsigned long)&frame->retcode;
 
4004
    /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
 
4005
    err |= __put_user(0xa960, (short *)(frame->retcode + 0));
 
4006
    err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
 
4007
    err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
 
4008
    err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
 
4009
 
 
4010
    if (err) {
 
4011
        goto give_sigsegv;
 
4012
    }
 
4013
 
 
4014
    /* TODO what is the current->exec_domain stuff and invmap ? */
 
4015
 
 
4016
    /* Set up registers for signal handler */
 
4017
    env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
 
4018
    env->gpr[9] = (unsigned long)return_ip;     /* what we enter LATER */
 
4019
    env->gpr[3] = (unsigned long)sig;           /* arg 1: signo */
 
4020
    env->gpr[4] = (unsigned long)&frame->info;  /* arg 2: (siginfo_t*) */
 
4021
    env->gpr[5] = (unsigned long)&frame->uc;    /* arg 3: ucontext */
 
4022
 
 
4023
    /* actually move the usp to reflect the stacked frame */
 
4024
    env->gpr[1] = (unsigned long)frame;
 
4025
 
 
4026
    return;
 
4027
 
 
4028
give_sigsegv:
 
4029
    unlock_user_struct(frame, frame_addr, 1);
 
4030
    if (sig == TARGET_SIGSEGV) {
 
4031
        ka->_sa_handler = TARGET_SIG_DFL;
 
4032
    }
 
4033
    force_sig(TARGET_SIGSEGV);
 
4034
}
 
4035
 
 
4036
long do_sigreturn(CPUOpenRISCState *env)
 
4037
{
 
4038
 
 
4039
    qemu_log("do_sigreturn: not implemented\n");
 
4040
    return -TARGET_ENOSYS;
 
4041
}
 
4042
 
 
4043
long do_rt_sigreturn(CPUOpenRISCState *env)
 
4044
{
 
4045
    qemu_log("do_rt_sigreturn: not implemented\n");
 
4046
    return -TARGET_ENOSYS;
 
4047
}
 
4048
/* TARGET_OPENRISC */
 
4049
 
 
4050
#elif defined(TARGET_S390X)
 
4051
 
 
4052
#define __NUM_GPRS 16
 
4053
#define __NUM_FPRS 16
 
4054
#define __NUM_ACRS 16
 
4055
 
 
4056
#define S390_SYSCALL_SIZE   2
 
4057
#define __SIGNAL_FRAMESIZE      160 /* FIXME: 31-bit mode -> 96 */
 
4058
 
 
4059
#define _SIGCONTEXT_NSIG        64
 
4060
#define _SIGCONTEXT_NSIG_BPW    64 /* FIXME: 31-bit mode -> 32 */
 
4061
#define _SIGCONTEXT_NSIG_WORDS  (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
 
4062
#define _SIGMASK_COPY_SIZE    (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
 
4063
#define PSW_ADDR_AMODE            0x0000000000000000UL /* 0x80000000UL for 31-bit */
 
4064
#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
 
4065
 
 
4066
typedef struct {
 
4067
    target_psw_t psw;
 
4068
    target_ulong gprs[__NUM_GPRS];
 
4069
    unsigned int acrs[__NUM_ACRS];
 
4070
} target_s390_regs_common;
 
4071
 
 
4072
typedef struct {
 
4073
    unsigned int fpc;
 
4074
    double   fprs[__NUM_FPRS];
 
4075
} target_s390_fp_regs;
 
4076
 
 
4077
typedef struct {
 
4078
    target_s390_regs_common regs;
 
4079
    target_s390_fp_regs     fpregs;
 
4080
} target_sigregs;
 
4081
 
 
4082
struct target_sigcontext {
 
4083
    target_ulong   oldmask[_SIGCONTEXT_NSIG_WORDS];
 
4084
    target_sigregs *sregs;
 
4085
};
 
4086
 
 
4087
typedef struct {
 
4088
    uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
 
4089
    struct target_sigcontext sc;
 
4090
    target_sigregs sregs;
 
4091
    int signo;
 
4092
    uint8_t retcode[S390_SYSCALL_SIZE];
 
4093
} sigframe;
 
4094
 
 
4095
struct target_ucontext {
 
4096
    target_ulong tuc_flags;
 
4097
    struct target_ucontext *tuc_link;
 
4098
    target_stack_t tuc_stack;
 
4099
    target_sigregs tuc_mcontext;
 
4100
    target_sigset_t tuc_sigmask;   /* mask last for extensibility */
 
4101
};
 
4102
 
 
4103
typedef struct {
 
4104
    uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
 
4105
    uint8_t retcode[S390_SYSCALL_SIZE];
 
4106
    struct target_siginfo info;
 
4107
    struct target_ucontext uc;
 
4108
} rt_sigframe;
 
4109
 
 
4110
static inline abi_ulong
 
4111
get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
 
4112
{
 
4113
    abi_ulong sp;
 
4114
 
 
4115
    /* Default to using normal stack */
 
4116
    sp = env->regs[15];
 
4117
 
 
4118
    /* This is the X/Open sanctioned signal stack switching.  */
 
4119
    if (ka->sa_flags & TARGET_SA_ONSTACK) {
 
4120
        if (!sas_ss_flags(sp)) {
 
4121
            sp = target_sigaltstack_used.ss_sp +
 
4122
                 target_sigaltstack_used.ss_size;
 
4123
        }
 
4124
    }
 
4125
 
 
4126
    /* This is the legacy signal stack switching. */
 
4127
    else if (/* FIXME !user_mode(regs) */ 0 &&
 
4128
             !(ka->sa_flags & TARGET_SA_RESTORER) &&
 
4129
             ka->sa_restorer) {
 
4130
        sp = (abi_ulong) ka->sa_restorer;
 
4131
    }
 
4132
 
 
4133
    return (sp - frame_size) & -8ul;
 
4134
}
 
4135
 
 
4136
static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
 
4137
{
 
4138
    int i;
 
4139
    //save_access_regs(current->thread.acrs); FIXME
 
4140
 
 
4141
    /* Copy a 'clean' PSW mask to the user to avoid leaking
 
4142
       information about whether PER is currently on.  */
 
4143
    __put_user(env->psw.mask, &sregs->regs.psw.mask);
 
4144
    __put_user(env->psw.addr, &sregs->regs.psw.addr);
 
4145
    for (i = 0; i < 16; i++) {
 
4146
        __put_user(env->regs[i], &sregs->regs.gprs[i]);
 
4147
    }
 
4148
    for (i = 0; i < 16; i++) {
 
4149
        __put_user(env->aregs[i], &sregs->regs.acrs[i]);
 
4150
    }
 
4151
    /*
 
4152
     * We have to store the fp registers to current->thread.fp_regs
 
4153
     * to merge them with the emulated registers.
 
4154
     */
 
4155
    //save_fp_regs(&current->thread.fp_regs); FIXME
 
4156
    for (i = 0; i < 16; i++) {
 
4157
        __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
 
4158
    }
 
4159
}
 
4160
 
 
4161
static void setup_frame(int sig, struct target_sigaction *ka,
 
4162
                        target_sigset_t *set, CPUS390XState *env)
 
4163
{
 
4164
    sigframe *frame;
 
4165
    abi_ulong frame_addr;
 
4166
 
 
4167
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
4168
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
 
4169
             (unsigned long long)frame_addr);
 
4170
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
 
4171
            goto give_sigsegv;
 
4172
    }
 
4173
 
 
4174
    qemu_log("%s: 1\n", __FUNCTION__);
 
4175
    if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
 
4176
              goto give_sigsegv;
 
4177
    }
 
4178
 
 
4179
    save_sigregs(env, &frame->sregs);
 
4180
 
 
4181
    __put_user((abi_ulong)(unsigned long)&frame->sregs,
 
4182
               (abi_ulong *)&frame->sc.sregs);
 
4183
 
 
4184
    /* Set up to return from userspace.  If provided, use a stub
 
4185
       already in userspace.  */
 
4186
    if (ka->sa_flags & TARGET_SA_RESTORER) {
 
4187
            env->regs[14] = (unsigned long)
 
4188
                    ka->sa_restorer | PSW_ADDR_AMODE;
 
4189
    } else {
 
4190
            env->regs[14] = (unsigned long)
 
4191
                    frame->retcode | PSW_ADDR_AMODE;
 
4192
            if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
 
4193
                           (uint16_t *)(frame->retcode)))
 
4194
                    goto give_sigsegv;
 
4195
    }
 
4196
 
 
4197
    /* Set up backchain. */
 
4198
    if (__put_user(env->regs[15], (abi_ulong *) frame)) {
 
4199
            goto give_sigsegv;
 
4200
    }
 
4201
 
 
4202
    /* Set up registers for signal handler */
 
4203
    env->regs[15] = frame_addr;
 
4204
    env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
 
4205
 
 
4206
    env->regs[2] = sig; //map_signal(sig);
 
4207
    env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
 
4208
 
 
4209
    /* We forgot to include these in the sigcontext.
 
4210
       To avoid breaking binary compatibility, they are passed as args. */
 
4211
    env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
 
4212
    env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
 
4213
 
 
4214
    /* Place signal number on stack to allow backtrace from handler.  */
 
4215
    if (__put_user(env->regs[2], (int *) &frame->signo)) {
 
4216
            goto give_sigsegv;
 
4217
    }
 
4218
    unlock_user_struct(frame, frame_addr, 1);
 
4219
    return;
 
4220
 
 
4221
give_sigsegv:
 
4222
    qemu_log("%s: give_sigsegv\n", __FUNCTION__);
 
4223
    unlock_user_struct(frame, frame_addr, 1);
 
4224
    force_sig(TARGET_SIGSEGV);
 
4225
}
 
4226
 
 
4227
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
4228
                           target_siginfo_t *info,
 
4229
                           target_sigset_t *set, CPUS390XState *env)
 
4230
{
 
4231
    int i;
 
4232
    rt_sigframe *frame;
 
4233
    abi_ulong frame_addr;
 
4234
 
 
4235
    frame_addr = get_sigframe(ka, env, sizeof *frame);
 
4236
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
 
4237
             (unsigned long long)frame_addr);
 
4238
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
 
4239
        goto give_sigsegv;
 
4240
    }
 
4241
 
 
4242
    qemu_log("%s: 1\n", __FUNCTION__);
 
4243
    if (copy_siginfo_to_user(&frame->info, info)) {
 
4244
        goto give_sigsegv;
 
4245
    }
 
4246
 
 
4247
    /* Create the ucontext.  */
 
4248
    __put_user(0, &frame->uc.tuc_flags);
 
4249
    __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
 
4250
    __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
 
4251
    __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
 
4252
                      &frame->uc.tuc_stack.ss_flags);
 
4253
    __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
 
4254
    save_sigregs(env, &frame->uc.tuc_mcontext);
 
4255
    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
 
4256
        __put_user((abi_ulong)set->sig[i],
 
4257
        (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
 
4258
    }
 
4259
 
 
4260
    /* Set up to return from userspace.  If provided, use a stub
 
4261
       already in userspace.  */
 
4262
    if (ka->sa_flags & TARGET_SA_RESTORER) {
 
4263
        env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
 
4264
    } else {
 
4265
        env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
 
4266
        if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
 
4267
                       (uint16_t *)(frame->retcode))) {
 
4268
            goto give_sigsegv;
 
4269
        }
 
4270
    }
 
4271
 
 
4272
    /* Set up backchain. */
 
4273
    if (__put_user(env->regs[15], (abi_ulong *) frame)) {
 
4274
        goto give_sigsegv;
 
4275
    }
 
4276
 
 
4277
    /* Set up registers for signal handler */
 
4278
    env->regs[15] = frame_addr;
 
4279
    env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
 
4280
 
 
4281
    env->regs[2] = sig; //map_signal(sig);
 
4282
    env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
 
4283
    env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
 
4284
    return;
 
4285
 
 
4286
give_sigsegv:
 
4287
    qemu_log("%s: give_sigsegv\n", __FUNCTION__);
 
4288
    unlock_user_struct(frame, frame_addr, 1);
 
4289
    force_sig(TARGET_SIGSEGV);
 
4290
}
 
4291
 
 
4292
static int
 
4293
restore_sigregs(CPUS390XState *env, target_sigregs *sc)
 
4294
{
 
4295
    int err = 0;
 
4296
    int i;
 
4297
 
 
4298
    for (i = 0; i < 16; i++) {
 
4299
        err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
 
4300
    }
 
4301
 
 
4302
    err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
 
4303
    qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
 
4304
             __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
 
4305
             (unsigned long long)env->psw.addr);
 
4306
    err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
 
4307
    /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
 
4308
 
 
4309
    for (i = 0; i < 16; i++) {
 
4310
        err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
 
4311
    }
 
4312
    for (i = 0; i < 16; i++) {
 
4313
        err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
 
4314
    }
 
4315
 
 
4316
    return err;
 
4317
}
 
4318
 
 
4319
long do_sigreturn(CPUS390XState *env)
 
4320
{
 
4321
    sigframe *frame;
 
4322
    abi_ulong frame_addr = env->regs[15];
 
4323
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
 
4324
             (unsigned long long)frame_addr);
 
4325
    target_sigset_t target_set;
 
4326
    sigset_t set;
 
4327
 
 
4328
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
 
4329
        goto badframe;
 
4330
    }
 
4331
    if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
 
4332
        goto badframe;
 
4333
    }
 
4334
 
 
4335
    target_to_host_sigset_internal(&set, &target_set);
 
4336
    sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
 
4337
 
 
4338
    if (restore_sigregs(env, &frame->sregs)) {
 
4339
        goto badframe;
 
4340
    }
 
4341
 
 
4342
    unlock_user_struct(frame, frame_addr, 0);
 
4343
    return env->regs[2];
 
4344
 
 
4345
badframe:
 
4346
    unlock_user_struct(frame, frame_addr, 0);
 
4347
    force_sig(TARGET_SIGSEGV);
 
4348
    return 0;
 
4349
}
 
4350
 
 
4351
long do_rt_sigreturn(CPUS390XState *env)
 
4352
{
 
4353
    rt_sigframe *frame;
 
4354
    abi_ulong frame_addr = env->regs[15];
 
4355
    qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
 
4356
             (unsigned long long)frame_addr);
 
4357
    sigset_t set;
 
4358
 
 
4359
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
 
4360
        goto badframe;
 
4361
    }
 
4362
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
 
4363
 
 
4364
    sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
 
4365
 
 
4366
    if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
 
4367
        goto badframe;
 
4368
    }
 
4369
 
 
4370
    if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
 
4371
                       get_sp_from_cpustate(env)) == -EFAULT) {
 
4372
        goto badframe;
 
4373
    }
 
4374
    unlock_user_struct(frame, frame_addr, 0);
 
4375
    return env->regs[2];
 
4376
 
 
4377
badframe:
 
4378
    unlock_user_struct(frame, frame_addr, 0);
 
4379
    force_sig(TARGET_SIGSEGV);
 
4380
    return 0;
 
4381
}
 
4382
 
 
4383
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
 
4384
 
 
4385
/* FIXME: Many of the structures are defined for both PPC and PPC64, but
 
4386
   the signal handling is different enough that we haven't implemented
 
4387
   support for PPC64 yet.  Hence the restriction above.
 
4388
 
 
4389
   There are various #if'd blocks for code for TARGET_PPC64.  These
 
4390
   blocks should go away so that we can successfully run 32-bit and
 
4391
   64-bit binaries on a QEMU configured for PPC64.  */
 
4392
 
 
4393
/* Size of dummy stack frame allocated when calling signal handler.
 
4394
   See arch/powerpc/include/asm/ptrace.h.  */
 
4395
#if defined(TARGET_PPC64)
 
4396
#define SIGNAL_FRAMESIZE 128
 
4397
#else
 
4398
#define SIGNAL_FRAMESIZE 64
 
4399
#endif
 
4400
 
 
4401
/* See arch/powerpc/include/asm/sigcontext.h.  */
 
4402
struct target_sigcontext {
 
4403
    target_ulong _unused[4];
 
4404
    int32_t signal;
 
4405
#if defined(TARGET_PPC64)
 
4406
    int32_t pad0;
 
4407
#endif
 
4408
    target_ulong handler;
 
4409
    target_ulong oldmask;
 
4410
    target_ulong regs;      /* struct pt_regs __user * */
 
4411
    /* TODO: PPC64 includes extra bits here.  */
 
4412
};
 
4413
 
 
4414
/* Indices for target_mcontext.mc_gregs, below.
 
4415
   See arch/powerpc/include/asm/ptrace.h for details.  */
 
4416
enum {
 
4417
    TARGET_PT_R0 = 0,
 
4418
    TARGET_PT_R1 = 1,
 
4419
    TARGET_PT_R2 = 2,
 
4420
    TARGET_PT_R3 = 3,
 
4421
    TARGET_PT_R4 = 4,
 
4422
    TARGET_PT_R5 = 5,
 
4423
    TARGET_PT_R6 = 6,
 
4424
    TARGET_PT_R7 = 7,
 
4425
    TARGET_PT_R8 = 8,
 
4426
    TARGET_PT_R9 = 9,
 
4427
    TARGET_PT_R10 = 10,
 
4428
    TARGET_PT_R11 = 11,
 
4429
    TARGET_PT_R12 = 12,
 
4430
    TARGET_PT_R13 = 13,
 
4431
    TARGET_PT_R14 = 14,
 
4432
    TARGET_PT_R15 = 15,
 
4433
    TARGET_PT_R16 = 16,
 
4434
    TARGET_PT_R17 = 17,
 
4435
    TARGET_PT_R18 = 18,
 
4436
    TARGET_PT_R19 = 19,
 
4437
    TARGET_PT_R20 = 20,
 
4438
    TARGET_PT_R21 = 21,
 
4439
    TARGET_PT_R22 = 22,
 
4440
    TARGET_PT_R23 = 23,
 
4441
    TARGET_PT_R24 = 24,
 
4442
    TARGET_PT_R25 = 25,
 
4443
    TARGET_PT_R26 = 26,
 
4444
    TARGET_PT_R27 = 27,
 
4445
    TARGET_PT_R28 = 28,
 
4446
    TARGET_PT_R29 = 29,
 
4447
    TARGET_PT_R30 = 30,
 
4448
    TARGET_PT_R31 = 31,
 
4449
    TARGET_PT_NIP = 32,
 
4450
    TARGET_PT_MSR = 33,
 
4451
    TARGET_PT_ORIG_R3 = 34,
 
4452
    TARGET_PT_CTR = 35,
 
4453
    TARGET_PT_LNK = 36,
 
4454
    TARGET_PT_XER = 37,
 
4455
    TARGET_PT_CCR = 38,
 
4456
    /* Yes, there are two registers with #39.  One is 64-bit only.  */
 
4457
    TARGET_PT_MQ = 39,
 
4458
    TARGET_PT_SOFTE = 39,
 
4459
    TARGET_PT_TRAP = 40,
 
4460
    TARGET_PT_DAR = 41,
 
4461
    TARGET_PT_DSISR = 42,
 
4462
    TARGET_PT_RESULT = 43,
 
4463
    TARGET_PT_REGS_COUNT = 44
 
4464
};
 
4465
 
 
4466
/* See arch/powerpc/include/asm/ucontext.h.  Only used for 32-bit PPC;
 
4467
   on 64-bit PPC, sigcontext and mcontext are one and the same.  */
 
4468
struct target_mcontext {
 
4469
    target_ulong mc_gregs[48];
 
4470
    /* Includes fpscr.  */
 
4471
    uint64_t mc_fregs[33];
 
4472
    target_ulong mc_pad[2];
 
4473
    /* We need to handle Altivec and SPE at the same time, which no
 
4474
       kernel needs to do.  Fortunately, the kernel defines this bit to
 
4475
       be Altivec-register-large all the time, rather than trying to
 
4476
       twiddle it based on the specific platform.  */
 
4477
    union {
 
4478
        /* SPE vector registers.  One extra for SPEFSCR.  */
 
4479
        uint32_t spe[33];
 
4480
        /* Altivec vector registers.  The packing of VSCR and VRSAVE
 
4481
           varies depending on whether we're PPC64 or not: PPC64 splits
 
4482
           them apart; PPC32 stuffs them together.  */
 
4483
#if defined(TARGET_PPC64)
 
4484
#define QEMU_NVRREG 34
 
4485
#else
 
4486
#define QEMU_NVRREG 33
 
4487
#endif
 
4488
        ppc_avr_t altivec[QEMU_NVRREG];
 
4489
#undef QEMU_NVRREG
 
4490
    } mc_vregs __attribute__((__aligned__(16)));
 
4491
};
 
4492
 
 
4493
struct target_ucontext {
 
4494
    target_ulong tuc_flags;
 
4495
    target_ulong tuc_link;    /* struct ucontext __user * */
 
4496
    struct target_sigaltstack tuc_stack;
 
4497
#if !defined(TARGET_PPC64)
 
4498
    int32_t tuc_pad[7];
 
4499
    target_ulong tuc_regs;    /* struct mcontext __user *
 
4500
                                points to uc_mcontext field */
 
4501
#endif
 
4502
    target_sigset_t tuc_sigmask;
 
4503
#if defined(TARGET_PPC64)
 
4504
    target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
 
4505
    struct target_sigcontext tuc_mcontext;
 
4506
#else
 
4507
    int32_t tuc_maskext[30];
 
4508
    int32_t tuc_pad2[3];
 
4509
    struct target_mcontext tuc_mcontext;
 
4510
#endif
 
4511
};
 
4512
 
 
4513
/* See arch/powerpc/kernel/signal_32.c.  */
 
4514
struct target_sigframe {
 
4515
    struct target_sigcontext sctx;
 
4516
    struct target_mcontext mctx;
 
4517
    int32_t abigap[56];
 
4518
};
 
4519
 
 
4520
struct target_rt_sigframe {
 
4521
    struct target_siginfo info;
 
4522
    struct target_ucontext uc;
 
4523
    int32_t abigap[56];
 
4524
};
 
4525
 
 
4526
/* We use the mc_pad field for the signal return trampoline.  */
 
4527
#define tramp mc_pad
 
4528
 
 
4529
/* See arch/powerpc/kernel/signal.c.  */
 
4530
static target_ulong get_sigframe(struct target_sigaction *ka,
 
4531
                                 CPUPPCState *env,
 
4532
                                 int frame_size)
 
4533
{
 
4534
    target_ulong oldsp, newsp;
 
4535
 
 
4536
    oldsp = env->gpr[1];
 
4537
 
 
4538
    if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
 
4539
        (sas_ss_flags(oldsp) == 0)) {
 
4540
        oldsp = (target_sigaltstack_used.ss_sp
 
4541
                 + target_sigaltstack_used.ss_size);
 
4542
    }
 
4543
 
 
4544
    newsp = (oldsp - frame_size) & ~0xFUL;
 
4545
 
 
4546
    return newsp;
 
4547
}
 
4548
 
 
4549
static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
 
4550
                          int sigret)
 
4551
{
 
4552
    target_ulong msr = env->msr;
 
4553
    int i;
 
4554
    target_ulong ccr = 0;
 
4555
 
 
4556
    /* In general, the kernel attempts to be intelligent about what it
 
4557
       needs to save for Altivec/FP/SPE registers.  We don't care that
 
4558
       much, so we just go ahead and save everything.  */
 
4559
 
 
4560
    /* Save general registers.  */
 
4561
    for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
 
4562
        if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
 
4563
            return 1;
 
4564
        }
 
4565
    }
 
4566
    if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
 
4567
        || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
 
4568
        || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
 
4569
        || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
 
4570
        return 1;
 
4571
 
 
4572
    for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
 
4573
        ccr |= env->crf[i] << (32 - ((i + 1) * 4));
 
4574
    }
 
4575
    if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
 
4576
        return 1;
 
4577
 
 
4578
    /* Save Altivec registers if necessary.  */
 
4579
    if (env->insns_flags & PPC_ALTIVEC) {
 
4580
        for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
 
4581
            ppc_avr_t *avr = &env->avr[i];
 
4582
            ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
 
4583
 
 
4584
            if (__put_user(avr->u64[0], &vreg->u64[0]) ||
 
4585
                __put_user(avr->u64[1], &vreg->u64[1])) {
 
4586
                return 1;
 
4587
            }
 
4588
        }
 
4589
        /* Set MSR_VR in the saved MSR value to indicate that
 
4590
           frame->mc_vregs contains valid data.  */
 
4591
        msr |= MSR_VR;
 
4592
        if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
 
4593
                       &frame->mc_vregs.altivec[32].u32[3]))
 
4594
            return 1;
 
4595
    }
 
4596
 
 
4597
    /* Save floating point registers.  */
 
4598
    if (env->insns_flags & PPC_FLOAT) {
 
4599
        for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
 
4600
            if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
 
4601
                return 1;
 
4602
            }
 
4603
        }
 
4604
        if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
 
4605
            return 1;
 
4606
    }
 
4607
 
 
4608
    /* Save SPE registers.  The kernel only saves the high half.  */
 
4609
    if (env->insns_flags & PPC_SPE) {
 
4610
#if defined(TARGET_PPC64)
 
4611
        for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
 
4612
            if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
 
4613
                return 1;
 
4614
            }
 
4615
        }
 
4616
#else
 
4617
        for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
 
4618
            if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
 
4619
                return 1;
 
4620
            }
 
4621
        }
 
4622
#endif
 
4623
        /* Set MSR_SPE in the saved MSR value to indicate that
 
4624
           frame->mc_vregs contains valid data.  */
 
4625
        msr |= MSR_SPE;
 
4626
        if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
 
4627
            return 1;
 
4628
    }
 
4629
 
 
4630
    /* Store MSR.  */
 
4631
    if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
 
4632
        return 1;
 
4633
 
 
4634
    /* Set up the sigreturn trampoline: li r0,sigret; sc.  */
 
4635
    if (sigret) {
 
4636
        if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
 
4637
            __put_user(0x44000002UL, &frame->tramp[1])) {
 
4638
            return 1;
 
4639
        }
 
4640
    }
 
4641
 
 
4642
    return 0;
 
4643
}
 
4644
 
 
4645
static int restore_user_regs(CPUPPCState *env,
 
4646
                             struct target_mcontext *frame, int sig)
 
4647
{
 
4648
    target_ulong save_r2 = 0;
 
4649
    target_ulong msr;
 
4650
    target_ulong ccr;
 
4651
 
 
4652
    int i;
 
4653
 
 
4654
    if (!sig) {
 
4655
        save_r2 = env->gpr[2];
 
4656
    }
 
4657
 
 
4658
    /* Restore general registers.  */
 
4659
    for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
 
4660
        if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
 
4661
            return 1;
 
4662
        }
 
4663
    }
 
4664
    if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
 
4665
        || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
 
4666
        || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
 
4667
        || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
 
4668
        return 1;
 
4669
    if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
 
4670
        return 1;
 
4671
 
 
4672
    for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
 
4673
        env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
 
4674
    }
 
4675
 
 
4676
    if (!sig) {
 
4677
        env->gpr[2] = save_r2;
 
4678
    }
 
4679
    /* Restore MSR.  */
 
4680
    if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
 
4681
        return 1;
 
4682
 
 
4683
    /* If doing signal return, restore the previous little-endian mode.  */
 
4684
    if (sig)
 
4685
        env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
 
4686
 
 
4687
    /* Restore Altivec registers if necessary.  */
 
4688
    if (env->insns_flags & PPC_ALTIVEC) {
 
4689
        for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
 
4690
            ppc_avr_t *avr = &env->avr[i];
 
4691
            ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
 
4692
 
 
4693
            if (__get_user(avr->u64[0], &vreg->u64[0]) ||
 
4694
                __get_user(avr->u64[1], &vreg->u64[1])) {
 
4695
                return 1;
 
4696
            }
 
4697
        }
 
4698
        /* Set MSR_VEC in the saved MSR value to indicate that
 
4699
           frame->mc_vregs contains valid data.  */
 
4700
        if (__get_user(env->spr[SPR_VRSAVE],
 
4701
                       (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
 
4702
            return 1;
 
4703
    }
 
4704
 
 
4705
    /* Restore floating point registers.  */
 
4706
    if (env->insns_flags & PPC_FLOAT) {
 
4707
        uint64_t fpscr;
 
4708
        for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
 
4709
            if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
 
4710
                return 1;
 
4711
            }
 
4712
        }
 
4713
        if (__get_user(fpscr, &frame->mc_fregs[32]))
 
4714
            return 1;
 
4715
        env->fpscr = (uint32_t) fpscr;
 
4716
    }
 
4717
 
 
4718
    /* Save SPE registers.  The kernel only saves the high half.  */
 
4719
    if (env->insns_flags & PPC_SPE) {
 
4720
#if defined(TARGET_PPC64)
 
4721
        for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
 
4722
            uint32_t hi;
 
4723
 
 
4724
            if (__get_user(hi, &frame->mc_vregs.spe[i])) {
 
4725
                return 1;
 
4726
            }
 
4727
            env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
 
4728
        }
 
4729
#else
 
4730
        for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
 
4731
            if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
 
4732
                return 1;
 
4733
            }
 
4734
        }
 
4735
#endif
 
4736
        if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
 
4737
            return 1;
 
4738
    }
 
4739
 
 
4740
    return 0;
 
4741
}
 
4742
 
 
4743
static void setup_frame(int sig, struct target_sigaction *ka,
 
4744
                        target_sigset_t *set, CPUPPCState *env)
 
4745
{
 
4746
    struct target_sigframe *frame;
 
4747
    struct target_sigcontext *sc;
 
4748
    target_ulong frame_addr, newsp;
 
4749
    int err = 0;
 
4750
    int signal;
 
4751
 
 
4752
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
4753
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
 
4754
        goto sigsegv;
 
4755
    sc = &frame->sctx;
 
4756
 
 
4757
    signal = current_exec_domain_sig(sig);
 
4758
 
 
4759
    err |= __put_user(ka->_sa_handler, &sc->handler);
 
4760
    err |= __put_user(set->sig[0], &sc->oldmask);
 
4761
#if defined(TARGET_PPC64)
 
4762
    err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
 
4763
#else
 
4764
    err |= __put_user(set->sig[1], &sc->_unused[3]);
 
4765
#endif
 
4766
    err |= __put_user(h2g(&frame->mctx), &sc->regs);
 
4767
    err |= __put_user(sig, &sc->signal);
 
4768
 
 
4769
    /* Save user regs.  */
 
4770
    err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
 
4771
 
 
4772
    /* The kernel checks for the presence of a VDSO here.  We don't
 
4773
       emulate a vdso, so use a sigreturn system call.  */
 
4774
    env->lr = (target_ulong) h2g(frame->mctx.tramp);
 
4775
 
 
4776
    /* Turn off all fp exceptions.  */
 
4777
    env->fpscr = 0;
 
4778
 
 
4779
    /* Create a stack frame for the caller of the handler.  */
 
4780
    newsp = frame_addr - SIGNAL_FRAMESIZE;
 
4781
    err |= put_user(env->gpr[1], newsp, target_ulong);
 
4782
 
 
4783
    if (err)
 
4784
        goto sigsegv;
 
4785
 
 
4786
    /* Set up registers for signal handler.  */
 
4787
    env->gpr[1] = newsp;
 
4788
    env->gpr[3] = signal;
 
4789
    env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
 
4790
    env->nip = (target_ulong) ka->_sa_handler;
 
4791
    /* Signal handlers are entered in big-endian mode.  */
 
4792
    env->msr &= ~MSR_LE;
 
4793
 
 
4794
    unlock_user_struct(frame, frame_addr, 1);
 
4795
    return;
 
4796
 
 
4797
sigsegv:
 
4798
    unlock_user_struct(frame, frame_addr, 1);
 
4799
    qemu_log("segfaulting from setup_frame\n");
 
4800
    force_sig(TARGET_SIGSEGV);
 
4801
}
 
4802
 
 
4803
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
4804
                           target_siginfo_t *info,
 
4805
                           target_sigset_t *set, CPUPPCState *env)
 
4806
{
 
4807
    struct target_rt_sigframe *rt_sf;
 
4808
    struct target_mcontext *frame;
 
4809
    target_ulong rt_sf_addr, newsp = 0;
 
4810
    int i, err = 0;
 
4811
    int signal;
 
4812
 
 
4813
    rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
 
4814
    if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
 
4815
        goto sigsegv;
 
4816
 
 
4817
    signal = current_exec_domain_sig(sig);
 
4818
 
 
4819
    err |= copy_siginfo_to_user(&rt_sf->info, info);
 
4820
 
 
4821
    err |= __put_user(0, &rt_sf->uc.tuc_flags);
 
4822
    err |= __put_user(0, &rt_sf->uc.tuc_link);
 
4823
    err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
 
4824
                      &rt_sf->uc.tuc_stack.ss_sp);
 
4825
    err |= __put_user(sas_ss_flags(env->gpr[1]),
 
4826
                      &rt_sf->uc.tuc_stack.ss_flags);
 
4827
    err |= __put_user(target_sigaltstack_used.ss_size,
 
4828
                      &rt_sf->uc.tuc_stack.ss_size);
 
4829
    err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
 
4830
                      &rt_sf->uc.tuc_regs);
 
4831
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
4832
        err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
 
4833
    }
 
4834
 
 
4835
    frame = &rt_sf->uc.tuc_mcontext;
 
4836
    err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
 
4837
 
 
4838
    /* The kernel checks for the presence of a VDSO here.  We don't
 
4839
       emulate a vdso, so use a sigreturn system call.  */
 
4840
    env->lr = (target_ulong) h2g(frame->tramp);
 
4841
 
 
4842
    /* Turn off all fp exceptions.  */
 
4843
    env->fpscr = 0;
 
4844
 
 
4845
    /* Create a stack frame for the caller of the handler.  */
 
4846
    newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
 
4847
    err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
 
4848
 
 
4849
    if (err)
 
4850
        goto sigsegv;
 
4851
 
 
4852
    /* Set up registers for signal handler.  */
 
4853
    env->gpr[1] = newsp;
 
4854
    env->gpr[3] = (target_ulong) signal;
 
4855
    env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
 
4856
    env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
 
4857
    env->gpr[6] = (target_ulong) h2g(rt_sf);
 
4858
    env->nip = (target_ulong) ka->_sa_handler;
 
4859
    /* Signal handlers are entered in big-endian mode.  */
 
4860
    env->msr &= ~MSR_LE;
 
4861
 
 
4862
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
 
4863
    return;
 
4864
 
 
4865
sigsegv:
 
4866
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
 
4867
    qemu_log("segfaulting from setup_rt_frame\n");
 
4868
    force_sig(TARGET_SIGSEGV);
 
4869
 
 
4870
}
 
4871
 
 
4872
long do_sigreturn(CPUPPCState *env)
 
4873
{
 
4874
    struct target_sigcontext *sc = NULL;
 
4875
    struct target_mcontext *sr = NULL;
 
4876
    target_ulong sr_addr = 0, sc_addr;
 
4877
    sigset_t blocked;
 
4878
    target_sigset_t set;
 
4879
 
 
4880
    sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
 
4881
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
 
4882
        goto sigsegv;
 
4883
 
 
4884
#if defined(TARGET_PPC64)
 
4885
    set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
 
4886
#else
 
4887
    if(__get_user(set.sig[0], &sc->oldmask) ||
 
4888
       __get_user(set.sig[1], &sc->_unused[3]))
 
4889
       goto sigsegv;
 
4890
#endif
 
4891
    target_to_host_sigset_internal(&blocked, &set);
 
4892
    sigprocmask(SIG_SETMASK, &blocked, NULL);
 
4893
 
 
4894
    if (__get_user(sr_addr, &sc->regs))
 
4895
        goto sigsegv;
 
4896
    if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
 
4897
        goto sigsegv;
 
4898
    if (restore_user_regs(env, sr, 1))
 
4899
        goto sigsegv;
 
4900
 
 
4901
    unlock_user_struct(sr, sr_addr, 1);
 
4902
    unlock_user_struct(sc, sc_addr, 1);
 
4903
    return -TARGET_QEMU_ESIGRETURN;
 
4904
 
 
4905
sigsegv:
 
4906
    unlock_user_struct(sr, sr_addr, 1);
 
4907
    unlock_user_struct(sc, sc_addr, 1);
 
4908
    qemu_log("segfaulting from do_sigreturn\n");
 
4909
    force_sig(TARGET_SIGSEGV);
 
4910
    return 0;
 
4911
}
 
4912
 
 
4913
/* See arch/powerpc/kernel/signal_32.c.  */
 
4914
static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
 
4915
{
 
4916
    struct target_mcontext *mcp;
 
4917
    target_ulong mcp_addr;
 
4918
    sigset_t blocked;
 
4919
    target_sigset_t set;
 
4920
 
 
4921
    if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
 
4922
                       sizeof (set)))
 
4923
        return 1;
 
4924
 
 
4925
#if defined(TARGET_PPC64)
 
4926
    fprintf (stderr, "do_setcontext: not implemented\n");
 
4927
    return 0;
 
4928
#else
 
4929
    if (__get_user(mcp_addr, &ucp->tuc_regs))
 
4930
        return 1;
 
4931
 
 
4932
    if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
 
4933
        return 1;
 
4934
 
 
4935
    target_to_host_sigset_internal(&blocked, &set);
 
4936
    sigprocmask(SIG_SETMASK, &blocked, NULL);
 
4937
    if (restore_user_regs(env, mcp, sig))
 
4938
        goto sigsegv;
 
4939
 
 
4940
    unlock_user_struct(mcp, mcp_addr, 1);
 
4941
    return 0;
 
4942
 
 
4943
sigsegv:
 
4944
    unlock_user_struct(mcp, mcp_addr, 1);
 
4945
    return 1;
 
4946
#endif
 
4947
}
 
4948
 
 
4949
long do_rt_sigreturn(CPUPPCState *env)
 
4950
{
 
4951
    struct target_rt_sigframe *rt_sf = NULL;
 
4952
    target_ulong rt_sf_addr;
 
4953
 
 
4954
    rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
 
4955
    if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
 
4956
        goto sigsegv;
 
4957
 
 
4958
    if (do_setcontext(&rt_sf->uc, env, 1))
 
4959
        goto sigsegv;
 
4960
 
 
4961
    do_sigaltstack(rt_sf_addr
 
4962
                   + offsetof(struct target_rt_sigframe, uc.tuc_stack),
 
4963
                   0, env->gpr[1]);
 
4964
 
 
4965
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
 
4966
    return -TARGET_QEMU_ESIGRETURN;
 
4967
 
 
4968
sigsegv:
 
4969
    unlock_user_struct(rt_sf, rt_sf_addr, 1);
 
4970
    qemu_log("segfaulting from do_rt_sigreturn\n");
 
4971
    force_sig(TARGET_SIGSEGV);
 
4972
    return 0;
 
4973
}
 
4974
 
 
4975
#elif defined(TARGET_M68K)
 
4976
 
 
4977
struct target_sigcontext {
 
4978
    abi_ulong  sc_mask;
 
4979
    abi_ulong  sc_usp;
 
4980
    abi_ulong  sc_d0;
 
4981
    abi_ulong  sc_d1;
 
4982
    abi_ulong  sc_a0;
 
4983
    abi_ulong  sc_a1;
 
4984
    unsigned short sc_sr;
 
4985
    abi_ulong  sc_pc;
 
4986
};
 
4987
 
 
4988
struct target_sigframe
 
4989
{
 
4990
    abi_ulong pretcode;
 
4991
    int sig;
 
4992
    int code;
 
4993
    abi_ulong psc;
 
4994
    char retcode[8];
 
4995
    abi_ulong extramask[TARGET_NSIG_WORDS-1];
 
4996
    struct target_sigcontext sc;
 
4997
};
 
4998
 
 
4999
typedef int target_greg_t;
 
5000
#define TARGET_NGREG 18
 
5001
typedef target_greg_t target_gregset_t[TARGET_NGREG];
 
5002
 
 
5003
typedef struct target_fpregset {
 
5004
    int f_fpcntl[3];
 
5005
    int f_fpregs[8*3];
 
5006
} target_fpregset_t;
 
5007
 
 
5008
struct target_mcontext {
 
5009
    int version;
 
5010
    target_gregset_t gregs;
 
5011
    target_fpregset_t fpregs;
 
5012
};
 
5013
 
 
5014
#define TARGET_MCONTEXT_VERSION 2
 
5015
 
 
5016
struct target_ucontext {
 
5017
    abi_ulong tuc_flags;
 
5018
    abi_ulong tuc_link;
 
5019
    target_stack_t tuc_stack;
 
5020
    struct target_mcontext tuc_mcontext;
 
5021
    abi_long tuc_filler[80];
 
5022
    target_sigset_t tuc_sigmask;
 
5023
};
 
5024
 
 
5025
struct target_rt_sigframe
 
5026
{
 
5027
    abi_ulong pretcode;
 
5028
    int sig;
 
5029
    abi_ulong pinfo;
 
5030
    abi_ulong puc;
 
5031
    char retcode[8];
 
5032
    struct target_siginfo info;
 
5033
    struct target_ucontext uc;
 
5034
};
 
5035
 
 
5036
static int
 
5037
setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
 
5038
                 abi_ulong mask)
 
5039
{
 
5040
    int err = 0;
 
5041
 
 
5042
    err |= __put_user(mask, &sc->sc_mask);
 
5043
    err |= __put_user(env->aregs[7], &sc->sc_usp);
 
5044
    err |= __put_user(env->dregs[0], &sc->sc_d0);
 
5045
    err |= __put_user(env->dregs[1], &sc->sc_d1);
 
5046
    err |= __put_user(env->aregs[0], &sc->sc_a0);
 
5047
    err |= __put_user(env->aregs[1], &sc->sc_a1);
 
5048
    err |= __put_user(env->sr, &sc->sc_sr);
 
5049
    err |= __put_user(env->pc, &sc->sc_pc);
 
5050
 
 
5051
    return err;
 
5052
}
 
5053
 
 
5054
static int
 
5055
restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
 
5056
{
 
5057
    int err = 0;
 
5058
    int temp;
 
5059
 
 
5060
    err |= __get_user(env->aregs[7], &sc->sc_usp);
 
5061
    err |= __get_user(env->dregs[1], &sc->sc_d1);
 
5062
    err |= __get_user(env->aregs[0], &sc->sc_a0);
 
5063
    err |= __get_user(env->aregs[1], &sc->sc_a1);
 
5064
    err |= __get_user(env->pc, &sc->sc_pc);
 
5065
    err |= __get_user(temp, &sc->sc_sr);
 
5066
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
 
5067
 
 
5068
    *pd0 = tswapl(sc->sc_d0);
 
5069
 
 
5070
    return err;
 
5071
}
 
5072
 
 
5073
/*
 
5074
 * Determine which stack to use..
 
5075
 */
 
5076
static inline abi_ulong
 
5077
get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
 
5078
             size_t frame_size)
 
5079
{
 
5080
    unsigned long sp;
 
5081
 
 
5082
    sp = regs->aregs[7];
 
5083
 
 
5084
    /* This is the X/Open sanctioned signal stack switching.  */
 
5085
    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
 
5086
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
5087
    }
 
5088
 
 
5089
    return ((sp - frame_size) & -8UL);
 
5090
}
 
5091
 
 
5092
static void setup_frame(int sig, struct target_sigaction *ka,
 
5093
                        target_sigset_t *set, CPUM68KState *env)
 
5094
{
 
5095
    struct target_sigframe *frame;
 
5096
    abi_ulong frame_addr;
 
5097
    abi_ulong retcode_addr;
 
5098
    abi_ulong sc_addr;
 
5099
    int err = 0;
 
5100
    int i;
 
5101
 
 
5102
    frame_addr = get_sigframe(ka, env, sizeof *frame);
 
5103
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
5104
        goto give_sigsegv;
 
5105
 
 
5106
    err |= __put_user(sig, &frame->sig);
 
5107
 
 
5108
    sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
 
5109
    err |= __put_user(sc_addr, &frame->psc);
 
5110
 
 
5111
    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
 
5112
    if (err)
 
5113
        goto give_sigsegv;
 
5114
 
 
5115
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
5116
        if (__put_user(set->sig[i], &frame->extramask[i - 1]))
 
5117
            goto give_sigsegv;
 
5118
    }
 
5119
 
 
5120
    /* Set up to return from userspace.  */
 
5121
 
 
5122
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
 
5123
    err |= __put_user(retcode_addr, &frame->pretcode);
 
5124
 
 
5125
    /* moveq #,d0; trap #0 */
 
5126
 
 
5127
    err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
 
5128
                      (long *)(frame->retcode));
 
5129
 
 
5130
    if (err)
 
5131
        goto give_sigsegv;
 
5132
 
 
5133
    /* Set up to return from userspace */
 
5134
 
 
5135
    env->aregs[7] = frame_addr;
 
5136
    env->pc = ka->_sa_handler;
 
5137
 
 
5138
    unlock_user_struct(frame, frame_addr, 1);
 
5139
    return;
 
5140
 
 
5141
give_sigsegv:
 
5142
    unlock_user_struct(frame, frame_addr, 1);
 
5143
    force_sig(TARGET_SIGSEGV);
 
5144
}
 
5145
 
 
5146
static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
 
5147
                                           CPUM68KState *env)
 
5148
{
 
5149
    target_greg_t *gregs = uc->tuc_mcontext.gregs;
 
5150
    int err;
 
5151
 
 
5152
    err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
 
5153
    err |= __put_user(env->dregs[0], &gregs[0]);
 
5154
    err |= __put_user(env->dregs[1], &gregs[1]);
 
5155
    err |= __put_user(env->dregs[2], &gregs[2]);
 
5156
    err |= __put_user(env->dregs[3], &gregs[3]);
 
5157
    err |= __put_user(env->dregs[4], &gregs[4]);
 
5158
    err |= __put_user(env->dregs[5], &gregs[5]);
 
5159
    err |= __put_user(env->dregs[6], &gregs[6]);
 
5160
    err |= __put_user(env->dregs[7], &gregs[7]);
 
5161
    err |= __put_user(env->aregs[0], &gregs[8]);
 
5162
    err |= __put_user(env->aregs[1], &gregs[9]);
 
5163
    err |= __put_user(env->aregs[2], &gregs[10]);
 
5164
    err |= __put_user(env->aregs[3], &gregs[11]);
 
5165
    err |= __put_user(env->aregs[4], &gregs[12]);
 
5166
    err |= __put_user(env->aregs[5], &gregs[13]);
 
5167
    err |= __put_user(env->aregs[6], &gregs[14]);
 
5168
    err |= __put_user(env->aregs[7], &gregs[15]);
 
5169
    err |= __put_user(env->pc, &gregs[16]);
 
5170
    err |= __put_user(env->sr, &gregs[17]);
 
5171
 
 
5172
    return err;
 
5173
}
 
5174
 
 
5175
static inline int target_rt_restore_ucontext(CPUM68KState *env,
 
5176
                                             struct target_ucontext *uc,
 
5177
                                             int *pd0)
 
5178
{
 
5179
    int temp;
 
5180
    int err;
 
5181
    target_greg_t *gregs = uc->tuc_mcontext.gregs;
 
5182
    
 
5183
    err = __get_user(temp, &uc->tuc_mcontext.version);
 
5184
    if (temp != TARGET_MCONTEXT_VERSION)
 
5185
        goto badframe;
 
5186
 
 
5187
    /* restore passed registers */
 
5188
    err |= __get_user(env->dregs[0], &gregs[0]);
 
5189
    err |= __get_user(env->dregs[1], &gregs[1]);
 
5190
    err |= __get_user(env->dregs[2], &gregs[2]);
 
5191
    err |= __get_user(env->dregs[3], &gregs[3]);
 
5192
    err |= __get_user(env->dregs[4], &gregs[4]);
 
5193
    err |= __get_user(env->dregs[5], &gregs[5]);
 
5194
    err |= __get_user(env->dregs[6], &gregs[6]);
 
5195
    err |= __get_user(env->dregs[7], &gregs[7]);
 
5196
    err |= __get_user(env->aregs[0], &gregs[8]);
 
5197
    err |= __get_user(env->aregs[1], &gregs[9]);
 
5198
    err |= __get_user(env->aregs[2], &gregs[10]);
 
5199
    err |= __get_user(env->aregs[3], &gregs[11]);
 
5200
    err |= __get_user(env->aregs[4], &gregs[12]);
 
5201
    err |= __get_user(env->aregs[5], &gregs[13]);
 
5202
    err |= __get_user(env->aregs[6], &gregs[14]);
 
5203
    err |= __get_user(env->aregs[7], &gregs[15]);
 
5204
    err |= __get_user(env->pc, &gregs[16]);
 
5205
    err |= __get_user(temp, &gregs[17]);
 
5206
    env->sr = (env->sr & 0xff00) | (temp & 0xff);
 
5207
 
 
5208
    *pd0 = env->dregs[0];
 
5209
    return err;
 
5210
 
 
5211
badframe:
 
5212
    return 1;
 
5213
}
 
5214
 
 
5215
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
5216
                           target_siginfo_t *info,
 
5217
                           target_sigset_t *set, CPUM68KState *env)
 
5218
{
 
5219
    struct target_rt_sigframe *frame;
 
5220
    abi_ulong frame_addr;
 
5221
    abi_ulong retcode_addr;
 
5222
    abi_ulong info_addr;
 
5223
    abi_ulong uc_addr;
 
5224
    int err = 0;
 
5225
    int i;
 
5226
 
 
5227
    frame_addr = get_sigframe(ka, env, sizeof *frame);
 
5228
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
 
5229
        goto give_sigsegv;
 
5230
 
 
5231
    err |= __put_user(sig, &frame->sig);
 
5232
 
 
5233
    info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
 
5234
    err |= __put_user(info_addr, &frame->pinfo);
 
5235
 
 
5236
    uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
 
5237
    err |= __put_user(uc_addr, &frame->puc);
 
5238
 
 
5239
    err |= copy_siginfo_to_user(&frame->info, info);
 
5240
 
 
5241
    /* Create the ucontext */
 
5242
 
 
5243
    err |= __put_user(0, &frame->uc.tuc_flags);
 
5244
    err |= __put_user(0, &frame->uc.tuc_link);
 
5245
    err |= __put_user(target_sigaltstack_used.ss_sp,
 
5246
                      &frame->uc.tuc_stack.ss_sp);
 
5247
    err |= __put_user(sas_ss_flags(env->aregs[7]),
 
5248
                      &frame->uc.tuc_stack.ss_flags);
 
5249
    err |= __put_user(target_sigaltstack_used.ss_size,
 
5250
                      &frame->uc.tuc_stack.ss_size);
 
5251
    err |= target_rt_setup_ucontext(&frame->uc, env);
 
5252
 
 
5253
    if (err)
 
5254
            goto give_sigsegv;
 
5255
 
 
5256
    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
 
5257
        if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
 
5258
            goto give_sigsegv;
 
5259
    }
 
5260
 
 
5261
    /* Set up to return from userspace.  */
 
5262
 
 
5263
    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
 
5264
    err |= __put_user(retcode_addr, &frame->pretcode);
 
5265
 
 
5266
    /* moveq #,d0; notb d0; trap #0 */
 
5267
 
 
5268
    err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
 
5269
                      (long *)(frame->retcode + 0));
 
5270
    err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
 
5271
 
 
5272
    if (err)
 
5273
        goto give_sigsegv;
 
5274
 
 
5275
    /* Set up to return from userspace */
 
5276
 
 
5277
    env->aregs[7] = frame_addr;
 
5278
    env->pc = ka->_sa_handler;
 
5279
 
 
5280
    unlock_user_struct(frame, frame_addr, 1);
 
5281
    return;
 
5282
 
 
5283
give_sigsegv:
 
5284
    unlock_user_struct(frame, frame_addr, 1);
 
5285
    force_sig(TARGET_SIGSEGV);
 
5286
}
 
5287
 
 
5288
long do_sigreturn(CPUM68KState *env)
 
5289
{
 
5290
    struct target_sigframe *frame;
 
5291
    abi_ulong frame_addr = env->aregs[7] - 4;
 
5292
    target_sigset_t target_set;
 
5293
    sigset_t set;
 
5294
    int d0, i;
 
5295
 
 
5296
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
5297
        goto badframe;
 
5298
 
 
5299
    /* set blocked signals */
 
5300
 
 
5301
    if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
 
5302
        goto badframe;
 
5303
 
 
5304
    for(i = 1; i < TARGET_NSIG_WORDS; i++) {
 
5305
        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
 
5306
            goto badframe;
 
5307
    }
 
5308
 
 
5309
    target_to_host_sigset_internal(&set, &target_set);
 
5310
    sigprocmask(SIG_SETMASK, &set, NULL);
 
5311
 
 
5312
    /* restore registers */
 
5313
 
 
5314
    if (restore_sigcontext(env, &frame->sc, &d0))
 
5315
        goto badframe;
 
5316
 
 
5317
    unlock_user_struct(frame, frame_addr, 0);
 
5318
    return d0;
 
5319
 
 
5320
badframe:
 
5321
    unlock_user_struct(frame, frame_addr, 0);
 
5322
    force_sig(TARGET_SIGSEGV);
 
5323
    return 0;
 
5324
}
 
5325
 
 
5326
long do_rt_sigreturn(CPUM68KState *env)
 
5327
{
 
5328
    struct target_rt_sigframe *frame;
 
5329
    abi_ulong frame_addr = env->aregs[7] - 4;
 
5330
    target_sigset_t target_set;
 
5331
    sigset_t set;
 
5332
    int d0;
 
5333
 
 
5334
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
 
5335
        goto badframe;
 
5336
 
 
5337
    target_to_host_sigset_internal(&set, &target_set);
 
5338
    sigprocmask(SIG_SETMASK, &set, NULL);
 
5339
 
 
5340
    /* restore registers */
 
5341
 
 
5342
    if (target_rt_restore_ucontext(env, &frame->uc, &d0))
 
5343
        goto badframe;
 
5344
 
 
5345
    if (do_sigaltstack(frame_addr +
 
5346
                       offsetof(struct target_rt_sigframe, uc.tuc_stack),
 
5347
                       0, get_sp_from_cpustate(env)) == -EFAULT)
 
5348
        goto badframe;
 
5349
 
 
5350
    unlock_user_struct(frame, frame_addr, 0);
 
5351
    return d0;
 
5352
 
 
5353
badframe:
 
5354
    unlock_user_struct(frame, frame_addr, 0);
 
5355
    force_sig(TARGET_SIGSEGV);
 
5356
    return 0;
 
5357
}
 
5358
 
 
5359
#elif defined(TARGET_ALPHA)
 
5360
 
 
5361
struct target_sigcontext {
 
5362
    abi_long sc_onstack;
 
5363
    abi_long sc_mask;
 
5364
    abi_long sc_pc;
 
5365
    abi_long sc_ps;
 
5366
    abi_long sc_regs[32];
 
5367
    abi_long sc_ownedfp;
 
5368
    abi_long sc_fpregs[32];
 
5369
    abi_ulong sc_fpcr;
 
5370
    abi_ulong sc_fp_control;
 
5371
    abi_ulong sc_reserved1;
 
5372
    abi_ulong sc_reserved2;
 
5373
    abi_ulong sc_ssize;
 
5374
    abi_ulong sc_sbase;
 
5375
    abi_ulong sc_traparg_a0;
 
5376
    abi_ulong sc_traparg_a1;
 
5377
    abi_ulong sc_traparg_a2;
 
5378
    abi_ulong sc_fp_trap_pc;
 
5379
    abi_ulong sc_fp_trigger_sum;
 
5380
    abi_ulong sc_fp_trigger_inst;
 
5381
};
 
5382
 
 
5383
struct target_ucontext {
 
5384
    abi_ulong tuc_flags;
 
5385
    abi_ulong tuc_link;
 
5386
    abi_ulong tuc_osf_sigmask;
 
5387
    target_stack_t tuc_stack;
 
5388
    struct target_sigcontext tuc_mcontext;
 
5389
    target_sigset_t tuc_sigmask;
 
5390
};
 
5391
 
 
5392
struct target_sigframe {
 
5393
    struct target_sigcontext sc;
 
5394
    unsigned int retcode[3];
 
5395
};
 
5396
 
 
5397
struct target_rt_sigframe {
 
5398
    target_siginfo_t info;
 
5399
    struct target_ucontext uc;
 
5400
    unsigned int retcode[3];
 
5401
};
 
5402
 
 
5403
#define INSN_MOV_R30_R16        0x47fe0410
 
5404
#define INSN_LDI_R0             0x201f0000
 
5405
#define INSN_CALLSYS            0x00000083
 
5406
 
 
5407
static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
 
5408
                            abi_ulong frame_addr, target_sigset_t *set)
 
5409
{
 
5410
    int i, err = 0;
 
5411
 
 
5412
    err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
 
5413
    err |= __put_user(set->sig[0], &sc->sc_mask);
 
5414
    err |= __put_user(env->pc, &sc->sc_pc);
 
5415
    err |= __put_user(8, &sc->sc_ps);
 
5416
 
 
5417
    for (i = 0; i < 31; ++i) {
 
5418
        err |= __put_user(env->ir[i], &sc->sc_regs[i]);
 
5419
    }
 
5420
    err |= __put_user(0, &sc->sc_regs[31]);
 
5421
 
 
5422
    for (i = 0; i < 31; ++i) {
 
5423
        err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
 
5424
    }
 
5425
    err |= __put_user(0, &sc->sc_fpregs[31]);
 
5426
    err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
 
5427
 
 
5428
    err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
 
5429
    err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
 
5430
    err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
 
5431
 
 
5432
    return err;
 
5433
}
 
5434
 
 
5435
static int restore_sigcontext(CPUAlphaState *env,
 
5436
                              struct target_sigcontext *sc)
 
5437
{
 
5438
    uint64_t fpcr;
 
5439
    int i, err = 0;
 
5440
 
 
5441
    err |= __get_user(env->pc, &sc->sc_pc);
 
5442
 
 
5443
    for (i = 0; i < 31; ++i) {
 
5444
        err |= __get_user(env->ir[i], &sc->sc_regs[i]);
 
5445
    }
 
5446
    for (i = 0; i < 31; ++i) {
 
5447
        err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
 
5448
    }
 
5449
 
 
5450
    err |= __get_user(fpcr, &sc->sc_fpcr);
 
5451
    cpu_alpha_store_fpcr(env, fpcr);
 
5452
 
 
5453
    return err;
 
5454
}
 
5455
 
 
5456
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
 
5457
                                     CPUAlphaState *env,
 
5458
                                     unsigned long framesize)
 
5459
{
 
5460
    abi_ulong sp = env->ir[IR_SP];
 
5461
 
 
5462
    /* This is the X/Open sanctioned signal stack switching.  */
 
5463
    if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
 
5464
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
 
5465
    }
 
5466
    return (sp - framesize) & -32;
 
5467
}
 
5468
 
 
5469
static void setup_frame(int sig, struct target_sigaction *ka,
 
5470
                        target_sigset_t *set, CPUAlphaState *env)
 
5471
{
 
5472
    abi_ulong frame_addr, r26;
 
5473
    struct target_sigframe *frame;
 
5474
    int err = 0;
 
5475
 
 
5476
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
5477
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
 
5478
        goto give_sigsegv;
 
5479
    }
 
5480
 
 
5481
    err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
 
5482
 
 
5483
    if (ka->sa_restorer) {
 
5484
        r26 = ka->sa_restorer;
 
5485
    } else {
 
5486
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
 
5487
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
 
5488
                          &frame->retcode[1]);
 
5489
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
 
5490
        /* imb() */
 
5491
        r26 = frame_addr;
 
5492
    }
 
5493
 
 
5494
    unlock_user_struct(frame, frame_addr, 1);
 
5495
 
 
5496
    if (err) {
 
5497
    give_sigsegv:
 
5498
        if (sig == TARGET_SIGSEGV) {
 
5499
            ka->_sa_handler = TARGET_SIG_DFL;
 
5500
        }
 
5501
        force_sig(TARGET_SIGSEGV);
 
5502
    }
 
5503
 
 
5504
    env->ir[IR_RA] = r26;
 
5505
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
 
5506
    env->ir[IR_A0] = sig;
 
5507
    env->ir[IR_A1] = 0;
 
5508
    env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
 
5509
    env->ir[IR_SP] = frame_addr;
 
5510
}
 
5511
 
 
5512
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
5513
                           target_siginfo_t *info,
 
5514
                           target_sigset_t *set, CPUAlphaState *env)
 
5515
{
 
5516
    abi_ulong frame_addr, r26;
 
5517
    struct target_rt_sigframe *frame;
 
5518
    int i, err = 0;
 
5519
 
 
5520
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
 
5521
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
 
5522
        goto give_sigsegv;
 
5523
    }
 
5524
 
 
5525
    err |= copy_siginfo_to_user(&frame->info, info);
 
5526
 
 
5527
    err |= __put_user(0, &frame->uc.tuc_flags);
 
5528
    err |= __put_user(0, &frame->uc.tuc_link);
 
5529
    err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
 
5530
    err |= __put_user(target_sigaltstack_used.ss_sp,
 
5531
                      &frame->uc.tuc_stack.ss_sp);
 
5532
    err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
 
5533
                      &frame->uc.tuc_stack.ss_flags);
 
5534
    err |= __put_user(target_sigaltstack_used.ss_size,
 
5535
                      &frame->uc.tuc_stack.ss_size);
 
5536
    err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
 
5537
    for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
 
5538
        err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
 
5539
    }
 
5540
 
 
5541
    if (ka->sa_restorer) {
 
5542
        r26 = ka->sa_restorer;
 
5543
    } else {
 
5544
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
 
5545
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
 
5546
                          &frame->retcode[1]);
 
5547
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
 
5548
        /* imb(); */
 
5549
        r26 = frame_addr;
 
5550
    }
 
5551
 
 
5552
    if (err) {
 
5553
    give_sigsegv:
 
5554
       if (sig == TARGET_SIGSEGV) {
 
5555
            ka->_sa_handler = TARGET_SIG_DFL;
 
5556
        }
 
5557
        force_sig(TARGET_SIGSEGV);
 
5558
    }
 
5559
 
 
5560
    env->ir[IR_RA] = r26;
 
5561
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
 
5562
    env->ir[IR_A0] = sig;
 
5563
    env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
 
5564
    env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
 
5565
    env->ir[IR_SP] = frame_addr;
 
5566
}
 
5567
 
 
5568
long do_sigreturn(CPUAlphaState *env)
 
5569
{
 
5570
    struct target_sigcontext *sc;
 
5571
    abi_ulong sc_addr = env->ir[IR_A0];
 
5572
    target_sigset_t target_set;
 
5573
    sigset_t set;
 
5574
 
 
5575
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
 
5576
        goto badframe;
 
5577
    }
 
5578
 
 
5579
    target_sigemptyset(&target_set);
 
5580
    if (__get_user(target_set.sig[0], &sc->sc_mask)) {
 
5581
        goto badframe;
 
5582
    }
 
5583
 
 
5584
    target_to_host_sigset_internal(&set, &target_set);
 
5585
    sigprocmask(SIG_SETMASK, &set, NULL);
 
5586
 
 
5587
    if (restore_sigcontext(env, sc)) {
 
5588
        goto badframe;
 
5589
    }
 
5590
    unlock_user_struct(sc, sc_addr, 0);
 
5591
    return env->ir[IR_V0];
 
5592
 
 
5593
 badframe:
 
5594
    unlock_user_struct(sc, sc_addr, 0);
 
5595
    force_sig(TARGET_SIGSEGV);
 
5596
}
 
5597
 
 
5598
long do_rt_sigreturn(CPUAlphaState *env)
 
5599
{
 
5600
    abi_ulong frame_addr = env->ir[IR_A0];
 
5601
    struct target_rt_sigframe *frame;
 
5602
    sigset_t set;
 
5603
 
 
5604
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
 
5605
        goto badframe;
 
5606
    }
 
5607
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
 
5608
    sigprocmask(SIG_SETMASK, &set, NULL);
 
5609
 
 
5610
    if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
 
5611
        goto badframe;
 
5612
    }
 
5613
    if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
 
5614
                                             uc.tuc_stack),
 
5615
                       0, env->ir[IR_SP]) == -EFAULT) {
 
5616
        goto badframe;
 
5617
    }
 
5618
 
 
5619
    unlock_user_struct(frame, frame_addr, 0);
 
5620
    return env->ir[IR_V0];
 
5621
 
 
5622
 
 
5623
 badframe:
 
5624
    unlock_user_struct(frame, frame_addr, 0);
 
5625
    force_sig(TARGET_SIGSEGV);
 
5626
}
 
5627
 
 
5628
#else
 
5629
 
 
5630
static void setup_frame(int sig, struct target_sigaction *ka,
 
5631
                        target_sigset_t *set, CPUArchState *env)
 
5632
{
 
5633
    fprintf(stderr, "setup_frame: not implemented\n");
 
5634
}
 
5635
 
 
5636
static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
5637
                           target_siginfo_t *info,
 
5638
                           target_sigset_t *set, CPUArchState *env)
 
5639
{
 
5640
    fprintf(stderr, "setup_rt_frame: not implemented\n");
 
5641
}
 
5642
 
 
5643
long do_sigreturn(CPUArchState *env)
 
5644
{
 
5645
    fprintf(stderr, "do_sigreturn: not implemented\n");
 
5646
    return -TARGET_ENOSYS;
 
5647
}
 
5648
 
 
5649
long do_rt_sigreturn(CPUArchState *env)
 
5650
{
 
5651
    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
 
5652
    return -TARGET_ENOSYS;
 
5653
}
 
5654
 
 
5655
#endif
 
5656
 
 
5657
/* Wrapper for sigprocmask function
 
5658
 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
 
5659
 * are host signal set, not guest ones. This wraps the sigprocmask host calls
 
5660
 * that should be protected (calls originated from guest)
 
5661
 */
 
5662
int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 
5663
{
 
5664
#ifdef TARGET_AARCH64
 
5665
    int ret;
 
5666
    sigset_t val;
 
5667
    sigset_t *temp;
 
5668
    if (set) {
 
5669
        val = *set;
 
5670
        temp = &val;
 
5671
        sigdelset(temp, SIGSEGV);
 
5672
    } else {
 
5673
        temp = NULL;
 
5674
    }
 
5675
    ret = sigprocmask(how, temp, oldset);
 
5676
 
 
5677
    /* Force set state of SIGSEGV, may be best for some apps, maybe not so good
 
5678
     * This is not required for qemu to work */
 
5679
    if (oldset) {
 
5680
        sigaddset(oldset, SIGSEGV);
 
5681
    }
 
5682
    return ret;
 
5683
#else
 
5684
    return sigprocmask(how, set, oldset);
 
5685
#endif
 
5686
}
 
5687
 
 
5688
void process_pending_signals(CPUArchState *cpu_env)
 
5689
{
 
5690
    CPUState *cpu = ENV_GET_CPU(cpu_env);
 
5691
    int sig;
 
5692
    abi_ulong handler;
 
5693
    sigset_t set, old_set;
 
5694
    target_sigset_t target_old_set;
 
5695
    struct emulated_sigtable *k;
 
5696
    struct target_sigaction *sa;
 
5697
    struct sigqueue *q;
 
5698
    TaskState *ts = cpu_env->opaque;
 
5699
 
 
5700
    if (!ts->signal_pending)
 
5701
        return;
 
5702
 
 
5703
    /* FIXME: This is not threadsafe.  */
 
5704
    k = ts->sigtab;
 
5705
    for(sig = 1; sig <= TARGET_NSIG; sig++) {
 
5706
        if (k->pending)
 
5707
            goto handle_signal;
 
5708
        k++;
 
5709
    }
 
5710
    /* if no signal is pending, just return */
 
5711
    ts->signal_pending = 0;
 
5712
    return;
 
5713
 
 
5714
 handle_signal:
 
5715
#ifdef DEBUG_SIGNAL
 
5716
    fprintf(stderr, "qemu: process signal %d\n", sig);
 
5717
#endif
 
5718
    /* dequeue signal */
 
5719
    q = k->first;
 
5720
    k->first = q->next;
 
5721
    if (!k->first)
 
5722
        k->pending = 0;
 
5723
 
 
5724
    sig = gdb_handlesig(cpu, sig);
 
5725
    if (!sig) {
 
5726
        sa = NULL;
 
5727
        handler = TARGET_SIG_IGN;
 
5728
    } else {
 
5729
        sa = &sigact_table[sig - 1];
 
5730
        handler = sa->_sa_handler;
 
5731
    }
 
5732
 
 
5733
    if (handler == TARGET_SIG_DFL) {
 
5734
        /* default handler : ignore some signal. The other are job control or fatal */
 
5735
        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
 
5736
            kill(getpid(),SIGSTOP);
 
5737
        } else if (sig != TARGET_SIGCHLD &&
 
5738
                   sig != TARGET_SIGURG &&
 
5739
                   sig != TARGET_SIGWINCH &&
 
5740
                   sig != TARGET_SIGCONT) {
 
5741
            force_sig(sig);
 
5742
        }
 
5743
    } else if (handler == TARGET_SIG_IGN) {
 
5744
        /* ignore sig */
 
5745
    } else if (handler == TARGET_SIG_ERR) {
 
5746
        force_sig(sig);
 
5747
    } else {
 
5748
        /* compute the blocked signals during the handler execution */
 
5749
        target_to_host_sigset(&set, &sa->sa_mask);
 
5750
        /* SA_NODEFER indicates that the current signal should not be
 
5751
           blocked during the handler */
 
5752
        if (!(sa->sa_flags & TARGET_SA_NODEFER))
 
5753
            sigaddset(&set, target_to_host_signal(sig));
 
5754
 
 
5755
        /* block signals in the handler using Linux */
 
5756
        sigprocmask(SIG_BLOCK, &set, &old_set);
 
5757
        /* save the previous blocked signal state to restore it at the
 
5758
           end of the signal execution (see do_sigreturn) */
 
5759
        host_to_target_sigset_internal(&target_old_set, &old_set);
 
5760
 
 
5761
        /* if the CPU is in VM86 mode, we restore the 32 bit values */
 
5762
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
 
5763
        {
 
5764
            CPUX86State *env = cpu_env;
 
5765
            if (env->eflags & VM_MASK)
 
5766
                save_v86_state(env);
 
5767
        }
 
5768
#endif
 
5769
        /* prepare the stack frame of the virtual CPU */
 
5770
#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
 
5771
        /* These targets do not have traditional signals.  */
 
5772
        setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
 
5773
#else
 
5774
        if (sa->sa_flags & TARGET_SA_SIGINFO)
 
5775
            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
 
5776
        else
 
5777
            setup_frame(sig, sa, &target_old_set, cpu_env);
 
5778
#endif
 
5779
        if (sa->sa_flags & TARGET_SA_RESETHAND)
 
5780
            sa->_sa_handler = TARGET_SIG_DFL;
 
5781
    }
 
5782
    if (q != &k->info)
 
5783
        free_sigqueue(cpu_env, q);
 
5784
}