~ubuntu-branches/ubuntu/utopic/qemu/utopic

« back to all changes in this revision

Viewing changes to .pc/arm64/0018-target-arm-Clean-up-handling-of-AArch64-PSTATE.patch/linux-user/signal.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn, Serge Hallyn, dann frazier
  • Date: 2014-01-10 12:19:08 UTC
  • Revision ID: package-import@ubuntu.com-20140110121908-6lsn06rypqbokbaf
Tags: 1.7.0+dfsg-2ubuntu6
[ Serge Hallyn ]
* add arm64 patchset from upstream.  The three arm virt patches previously
  pushed are in that set, so drop them.

[ dann frazier ]
* Add packaging for qemu-system-aarch64. This package is currently only
  available for arm64, as full software emulation is not yet supported.

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