2
* Emulation of Linux signals
4
* Copyright (c) 2003 Fabrice Bellard
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.
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.
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/>.
26
#include <sys/ucontext.h>
27
#include <sys/resource.h>
30
#include "qemu-common.h"
31
#include "target_signal.h"
33
//#define DEBUG_SIGNAL
35
static struct target_sigaltstack target_sigaltstack_used = {
38
.ss_flags = TARGET_SS_DISABLE,
41
static struct target_sigaction sigact_table[TARGET_NSIG];
43
static void host_signal_handler(int host_signum, siginfo_t *info,
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,
64
[SIGSTKFLT] = TARGET_SIGSTKFLT,
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,
89
static uint8_t target_to_host_signal_table[_NSIG];
91
static inline int on_sig_stack(unsigned long sp)
93
return (sp - target_sigaltstack_used.ss_sp
94
< target_sigaltstack_used.ss_size);
97
static inline int sas_ss_flags(unsigned long sp)
99
return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
100
: on_sig_stack(sp) ? SS_ONSTACK : 0);
103
int host_to_target_signal(int sig)
105
if (sig < 0 || sig >= _NSIG)
107
return host_to_target_signal_table[sig];
110
int target_to_host_signal(int sig)
112
if (sig < 0 || sig >= _NSIG)
114
return target_to_host_signal_table[sig];
117
static inline void target_sigemptyset(target_sigset_t *set)
119
memset(set, 0, sizeof(*set));
122
static inline void target_sigaddset(target_sigset_t *set, int signum)
125
abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
126
set->sig[signum / TARGET_NSIG_BPW] |= mask;
129
static inline int target_sigismember(const target_sigset_t *set, int signum)
132
abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
133
return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
136
static void host_to_target_sigset_internal(target_sigset_t *d,
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));
148
void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
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]);
158
static void target_to_host_sigset_internal(sigset_t *d,
159
const target_sigset_t *s)
163
for (i = 1; i <= TARGET_NSIG; i++) {
164
if (target_sigismember(s, i)) {
165
sigaddset(d, target_to_host_signal(i));
170
void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
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);
180
void host_to_target_old_sigset(abi_ulong *old_sigset,
181
const sigset_t *sigset)
184
host_to_target_sigset(&d, sigset);
185
*old_sigset = d.sig[0];
188
void target_to_host_old_sigset(sigset_t *sigset,
189
const abi_ulong *old_sigset)
194
d.sig[0] = *old_sigset;
195
for(i = 1;i < TARGET_NSIG_WORDS; i++)
197
target_to_host_sigset(sigset, &d);
200
/* siginfo conversion */
202
static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
203
const siginfo_t *info)
205
int sig = host_to_target_signal(info->si_signo);
206
tinfo->si_signo = sig;
208
tinfo->si_code = info->si_code;
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;
234
static void tswap_siginfo(target_siginfo_t *tinfo,
235
const target_siginfo_t *info)
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);
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);
270
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
272
host_to_target_siginfo_noswap(tinfo, info);
273
tswap_siginfo(tinfo, tinfo);
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)
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);
289
static int fatal_signal (int sig)
294
case TARGET_SIGWINCH:
295
/* Ignored by default. */
302
/* Job control signals. */
309
/* returns 1 if given signal should dump core if not handled */
310
static int core_dump_signal(int sig)
326
void signal_init(void)
328
struct sigaction act;
329
struct sigaction oact;
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;
338
for(i = 1; i < _NSIG; i++) {
339
j = host_to_target_signal_table[i];
340
target_to_host_signal_table[j] = i;
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));
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;
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);
369
/* signal queue handling */
371
static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
373
TaskState *ts = env->opaque;
374
struct sigqueue *q = ts->first_free;
377
ts->first_free = q->next;
381
static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
383
TaskState *ts = env->opaque;
384
q->next = ts->first_free;
388
/* abort execution with signal */
389
static void QEMU_NORETURN force_sig(int target_sig)
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);
398
/* dump core if supported by target binary format */
399
if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
402
((*ts->bprm->core_dump)(target_sig, env) == 0);
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);
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" );
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
421
sigfillset(&act.sa_mask);
422
act.sa_handler = SIG_DFL;
423
sigaction(host_sig, &act, NULL);
425
/* For some reason raise(host_sig) doesn't send the signal when
426
* statically linked on x86-64. */
427
kill(getpid(), host_sig);
429
/* Make sure the signal isn't masked (just reuse the mask inside
431
sigdelset(&act.sa_mask, host_sig);
432
sigsuspend(&act.sa_mask);
438
/* queue a signal so that it will be send to the virtual CPU as soon
440
int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
442
TaskState *ts = env->opaque;
443
struct emulated_sigtable *k;
444
struct sigqueue *q, **pq;
448
#if defined(DEBUG_SIGNAL)
449
fprintf(stderr, "queue_signal: sig=%d\n",
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);
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) {
467
return 0; /* indicate ignored */
469
} else if (!queue && handler == TARGET_SIG_IGN) {
472
} else if (!queue && handler == TARGET_SIG_ERR) {
476
if (sig < TARGET_SIGRTMIN) {
477
/* if non real time signal, we queue exactly one signal */
487
q = alloc_sigqueue(env);
498
/* signal that a new signal is pending */
499
ts->signal_pending = 1;
500
return 1; /* indicates that the signal was queued */
504
static void host_signal_handler(int host_signum, siginfo_t *info,
507
CPUArchState *env = thread_cpu->env_ptr;
509
target_siginfo_t tinfo;
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))
519
/* get target signal number */
520
sig = host_to_target_signal(host_signum);
521
if (sig < 1 || sig > TARGET_NSIG)
523
#if defined(DEBUG_SIGNAL)
524
fprintf(stderr, "qemu: got signal %d\n", sig);
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);
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)
538
struct target_sigaltstack oss;
540
/* XXX: test errors */
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);
550
struct target_sigaltstack *uss;
551
struct target_sigaltstack ss;
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))
559
unlock_user_struct(uss, uss_addr, 0);
562
if (on_sig_stack(sp))
565
ret = -TARGET_EINVAL;
566
if (ss.ss_flags != TARGET_SS_DISABLE
567
&& ss.ss_flags != TARGET_SS_ONSTACK
571
if (ss.ss_flags == TARGET_SS_DISABLE) {
575
ret = -TARGET_ENOMEM;
576
if (ss.ss_size < MINSIGSTKSZ)
580
target_sigaltstack_used.ss_sp = ss.ss_sp;
581
target_sigaltstack_used.ss_size = ss.ss_size;
585
ret = -TARGET_EFAULT;
586
if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
595
/* do_sigaction() return host values and errnos */
596
int do_sigaction(int sig, const struct target_sigaction *act,
597
struct target_sigaction *oact)
599
struct target_sigaction *k;
600
struct sigaction act1;
604
if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
606
k = &sigact_table[sig - 1];
607
#if defined(DEBUG_SIGNAL)
608
fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
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);
618
oact->sa_mask = k->sa_mask;
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);
627
/* To be swapped in target_to_host_sigset. */
628
k->sa_mask = act->sa_mask;
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
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;
646
act1.sa_sigaction = (void *)SIG_DFL;
648
act1.sa_sigaction = host_signal_handler;
650
ret = sigaction(host_sig, &act1, NULL);
656
static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
657
const target_siginfo_t *info)
659
tswap_siginfo(tinfo, info);
663
static inline int current_exec_domain_sig(int sig)
665
return /* current->exec_domain && current->exec_domain->signal_invmap
666
&& sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
669
#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
671
/* from the Linux kernel */
673
struct target_fpreg {
674
uint16_t significand[4];
678
struct target_fpxreg {
679
uint16_t significand[4];
684
struct target_xmmreg {
685
abi_ulong element[4];
688
struct target_fpstate {
689
/* Regular FPU environment */
697
struct target_fpreg _st[8];
699
uint16_t magic; /* 0xffff = regular FPU data only */
701
/* FXSR FPU environment */
702
abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
705
struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
706
struct target_xmmreg _xmm[8];
707
abi_ulong padding[56];
710
#define X86_FXSR_MAGIC 0x0000
712
struct target_sigcontext {
730
abi_ulong esp_at_signal;
732
abi_ulong fpstate; /* pointer */
737
struct target_ucontext {
740
target_stack_t tuc_stack;
741
struct target_sigcontext tuc_mcontext;
742
target_sigset_t tuc_sigmask; /* mask last for extensibility */
749
struct target_sigcontext sc;
750
struct target_fpstate fpstate;
751
abi_ulong extramask[TARGET_NSIG_WORDS-1];
761
struct target_siginfo info;
762
struct target_ucontext uc;
763
struct target_fpstate fpstate;
768
* Set up a signal frame.
771
/* XXX: save x87 state */
773
setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
774
CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
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);
800
cpu_x86_fsave(env, fpstate_addr, 1);
801
fpstate->status = fpstate->sw;
803
err |= __put_user(magic, &fpstate->magic);
804
err |= __put_user(fpstate_addr, &sc->fpstate);
806
/* non-iBCS2 extensions.. */
807
err |= __put_user(mask, &sc->oldmask);
808
err |= __put_user(env->cr[2], &sc->cr2);
813
* Determine which stack to use..
816
static inline abi_ulong
817
get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
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;
829
/* This is the legacy signal stack switching. */
831
if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
832
!(ka->sa_flags & TARGET_SA_RESTORER) &&
834
esp = (unsigned long) ka->sa_restorer;
836
return (esp - frame_size) & -8ul;
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)
843
abi_ulong frame_addr;
844
struct sigframe *frame;
847
frame_addr = get_sigframe(ka, env, sizeof(*frame));
849
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
852
err |= __put_user(current_exec_domain_sig(sig),
857
setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
858
frame_addr + offsetof(struct sigframe, fpstate));
862
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
863
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
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);
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 */
878
err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
879
err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
881
err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
887
/* Set up registers for signal handler */
888
env->regs[R_ESP] = frame_addr;
889
env->eip = ka->_sa_handler;
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;
897
unlock_user_struct(frame, frame_addr, 1);
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 */);
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)
913
abi_ulong frame_addr, addr;
914
struct rt_sigframe *frame;
917
frame_addr = get_sigframe(ka, env, sizeof(*frame));
919
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
922
err |= __put_user(current_exec_domain_sig(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);
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,
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]))
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);
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));
961
err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
967
/* Set up registers for signal handler */
968
env->regs[R_ESP] = frame_addr;
969
env->eip = ka->_sa_handler;
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;
977
unlock_user_struct(frame, frame_addr, 1);
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 */);
989
restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
991
unsigned int err = 0;
992
abi_ulong fpstate_addr;
993
unsigned int tmpflags;
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));
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);
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);
1012
tmpflags = tswapl(sc->eflags);
1013
env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1014
// regs->orig_eax = -1; /* disable syscall checks */
1016
fpstate_addr = tswapl(sc->fpstate);
1017
if (fpstate_addr != 0) {
1018
if (!access_ok(VERIFY_READ, fpstate_addr,
1019
sizeof(struct target_fpstate)))
1021
cpu_x86_frstor(env, fpstate_addr, 1);
1024
*peax = tswapl(sc->eax);
1030
long do_sigreturn(CPUX86State *env)
1032
struct sigframe *frame;
1033
abi_ulong frame_addr = env->regs[R_ESP] - 8;
1034
target_sigset_t target_set;
1038
#if defined(DEBUG_SIGNAL)
1039
fprintf(stderr, "do_sigreturn\n");
1041
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1043
/* set blocked signals */
1044
if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1046
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1047
if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1051
target_to_host_sigset_internal(&set, &target_set);
1052
sigprocmask(SIG_SETMASK, &set, NULL);
1054
/* restore registers */
1055
if (restore_sigcontext(env, &frame->sc, &eax))
1057
unlock_user_struct(frame, frame_addr, 0);
1061
unlock_user_struct(frame, frame_addr, 0);
1062
force_sig(TARGET_SIGSEGV);
1066
long do_rt_sigreturn(CPUX86State *env)
1068
abi_ulong frame_addr;
1069
struct rt_sigframe *frame;
1073
frame_addr = env->regs[R_ESP] - 4;
1074
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1076
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1077
sigprocmask(SIG_SETMASK, &set, NULL);
1079
if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1082
if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1083
get_sp_from_cpustate(env)) == -EFAULT)
1086
unlock_user_struct(frame, frame_addr, 0);
1090
unlock_user_struct(frame, frame_addr, 0);
1091
force_sig(TARGET_SIGSEGV);
1095
#elif defined(TARGET_AARCH64)
1097
struct target_sigcontext {
1098
uint64_t fault_address;
1099
/* AArch64 registers */
1104
/* 4K reserved for FP/SIMD state and future expansion */
1105
char __reserved[4096] __attribute__((__aligned__(16)));
1108
struct target_ucontext {
1109
abi_ulong tuc_flags;
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;
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.
1125
struct target_aarch64_ctx {
1130
#define TARGET_FPSIMD_MAGIC 0x46508001
1132
struct target_fpsimd_context {
1133
struct target_aarch64_ctx head;
1136
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
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.
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;
1150
struct target_rt_sigframe {
1151
struct target_siginfo info;
1152
struct target_ucontext uc;
1158
static int target_setup_sigframe(struct target_rt_sigframe *sf,
1159
CPUARMState *env, target_sigset_t *set)
1162
struct target_aux_context *aux =
1163
(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1165
/* set up the stack frame for unwinding */
1166
__put_user(env->xregs[29], &sf->fp);
1167
__put_user(env->xregs[30], &sf->lr);
1169
for (i = 0; i < 31; i++) {
1170
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
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);
1176
__put_user(/*current->thread.fault_address*/ 0,
1177
&sf->uc.tuc_mcontext.fault_address);
1179
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
1180
__put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
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]);
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]);
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);
1198
/* set the "end" magic */
1199
__put_user(0, &aux->end.magic);
1200
__put_user(0, &aux->end.size);
1205
static int target_restore_sigframe(CPUARMState *env,
1206
struct target_rt_sigframe *sf)
1210
struct target_aux_context *aux =
1211
(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1212
uint32_t magic, size;
1214
target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1215
sigprocmask(SIG_SETMASK, &set, NULL);
1217
for (i = 0; i < 31; i++) {
1218
__get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
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);
1225
__get_user(magic, &aux->fpsimd.head.magic);
1226
__get_user(size, &aux->fpsimd.head.size);
1228
if (magic != TARGET_FPSIMD_MAGIC
1229
|| size != sizeof(struct target_fpsimd_context)) {
1233
for (i = 0; i < 32 * 2; i++) {
1234
__get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]);
1240
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1244
sp = env->xregs[31];
1247
* This is the X/Open sanctioned signal stack switching.
1249
if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
1250
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1253
sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1258
static void target_setup_frame(int usig, struct target_sigaction *ka,
1259
target_siginfo_t *info, target_sigset_t *set,
1262
struct target_rt_sigframe *frame;
1263
abi_ulong frame_addr;
1265
frame_addr = get_sigframe(ka, env);
1266
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1270
__put_user(0, &frame->uc.tuc_flags);
1271
__put_user(0, &frame->uc.tuc_link);
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);
1290
if (copy_siginfo_to_user(&frame->info, info)) {
1293
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1294
env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1297
unlock_user_struct(frame, frame_addr, 1);
1301
unlock_user_struct(frame, frame_addr, 1);
1302
force_sig(TARGET_SIGSEGV);
1305
static void setup_rt_frame(int sig, struct target_sigaction *ka,
1306
target_siginfo_t *info, target_sigset_t *set,
1309
target_setup_frame(sig, ka, info, set, env);
1312
static void setup_frame(int sig, struct target_sigaction *ka,
1313
target_sigset_t *set, CPUARMState *env)
1315
target_setup_frame(sig, ka, 0, set, env);
1318
long do_rt_sigreturn(CPUARMState *env)
1320
struct target_rt_sigframe *frame;
1321
abi_ulong frame_addr = env->xregs[31];
1323
if (frame_addr & 15) {
1327
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1331
if (target_restore_sigframe(env, frame)) {
1335
if (do_sigaltstack(frame_addr +
1336
offsetof(struct target_rt_sigframe, uc.tuc_stack),
1337
0, get_sp_from_cpustate(env)) == -EFAULT) {
1341
unlock_user_struct(frame, frame_addr, 0);
1342
return env->xregs[0];
1345
unlock_user_struct(frame, frame_addr, 0);
1346
force_sig(TARGET_SIGSEGV);
1350
long do_sigreturn(CPUARMState *env)
1352
return do_rt_sigreturn(env);
1355
#elif defined(TARGET_ARM)
1357
struct target_sigcontext {
1359
abi_ulong error_code;
1378
abi_ulong fault_address;
1381
struct target_ucontext_v1 {
1382
abi_ulong tuc_flags;
1384
target_stack_t tuc_stack;
1385
struct target_sigcontext tuc_mcontext;
1386
target_sigset_t tuc_sigmask; /* mask last for extensibility */
1389
struct target_ucontext_v2 {
1390
abi_ulong tuc_flags;
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)));
1399
struct target_user_vfp {
1400
uint64_t fpregs[32];
1404
struct target_user_vfp_exc {
1410
struct target_vfp_sigframe {
1413
struct target_user_vfp ufp;
1414
struct target_user_vfp_exc ufp_exc;
1415
} __attribute__((__aligned__(8)));
1417
struct target_iwmmxt_sigframe {
1421
/* Note that not all the coprocessor control registers are stored here */
1428
} __attribute__((__aligned__(8)));
1430
#define TARGET_VFP_MAGIC 0x56465001
1431
#define TARGET_IWMMXT_MAGIC 0x12ef842a
1435
struct target_sigcontext sc;
1436
abi_ulong extramask[TARGET_NSIG_WORDS-1];
1442
struct target_ucontext_v2 uc;
1446
struct rt_sigframe_v1
1450
struct target_siginfo info;
1451
struct target_ucontext_v1 uc;
1455
struct rt_sigframe_v2
1457
struct target_siginfo info;
1458
struct target_ucontext_v2 uc;
1462
#define TARGET_CONFIG_CPU_32 1
1465
* For ARM syscalls, we encode the syscall number into the instruction.
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))
1471
* For Thumb syscalls, we pass the syscall number via r7. We therefore
1472
* need two 16-bit instructions.
1474
#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1475
#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1477
static const abi_ulong retcodes[4] = {
1478
SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1479
SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1483
#define __get_user_error(x,p,e) __get_user(x, p)
1485
static inline int valid_user_regs(CPUARMState *regs)
1491
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1492
CPUARMState *env, abi_ulong mask)
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);
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);
1520
static inline abi_ulong
1521
get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1523
unsigned long sp = regs->regs[13];
1526
* This is the X/Open sanctioned signal stack switching.
1528
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1529
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1531
* ATPCS B01 mandates 8-byte alignment
1533
return (sp - framesize) & ~7;
1537
setup_return(CPUARMState *env, struct target_sigaction *ka,
1538
abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1540
abi_ulong handler = ka->_sa_handler;
1542
int thumb = handler & 1;
1543
uint32_t cpsr = cpsr_read(env);
1552
if (ka->sa_flags & TARGET_SA_RESTORER) {
1553
retcode = ka->sa_restorer;
1555
unsigned int idx = thumb;
1557
if (ka->sa_flags & TARGET_SA_SIGINFO)
1560
if (__put_user(retcodes[idx], rc))
1563
retcode = rc_addr + thumb;
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);
1575
static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
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]);
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);
1592
static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
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]);
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);
1612
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1613
target_sigset_t *set, CPUARMState *env)
1615
struct target_sigaltstack stack;
1617
abi_ulong *regspace;
1619
/* Clear all the bits of the ucontext we don't use. */
1620
memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
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));
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);
1634
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1635
regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1638
/* Write terminating magic word */
1639
__put_user(0, regspace);
1641
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1642
__put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
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)
1650
struct sigframe_v1 *frame;
1651
abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1654
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1657
setup_sigcontext(&frame->sc, regs, set->sig[0]);
1659
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1660
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1664
setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1665
frame_addr + offsetof(struct sigframe_v1, retcode));
1668
unlock_user_struct(frame, frame_addr, 1);
1671
static void setup_frame_v2(int usig, struct target_sigaction *ka,
1672
target_sigset_t *set, CPUARMState *regs)
1674
struct sigframe_v2 *frame;
1675
abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1677
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1680
setup_sigframe_v2(&frame->uc, set, regs);
1682
setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1683
frame_addr + offsetof(struct sigframe_v2, retcode));
1685
unlock_user_struct(frame, frame_addr, 1);
1688
static void setup_frame(int usig, struct target_sigaction *ka,
1689
target_sigset_t *set, CPUARMState *regs)
1691
if (get_osversion() >= 0x020612) {
1692
setup_frame_v2(usig, ka, set, regs);
1694
setup_frame_v1(usig, ka, set, regs);
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)
1703
struct rt_sigframe_v1 *frame;
1704
abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1705
struct target_sigaltstack stack;
1707
abi_ulong info_addr, uc_addr;
1709
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
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);
1718
/* Clear all the bits of the ucontext we don't use. */
1719
memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
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));
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]))
1733
setup_return(env, ka, &frame->retcode, frame_addr, usig,
1734
frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1736
env->regs[1] = info_addr;
1737
env->regs[2] = uc_addr;
1740
unlock_user_struct(frame, frame_addr, 1);
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)
1747
struct rt_sigframe_v2 *frame;
1748
abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1749
abi_ulong info_addr, uc_addr;
1751
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
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);
1758
setup_sigframe_v2(&frame->uc, set, env);
1760
setup_return(env, ka, &frame->retcode, frame_addr, usig,
1761
frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1763
env->regs[1] = info_addr;
1764
env->regs[2] = uc_addr;
1766
unlock_user_struct(frame, frame_addr, 1);
1769
static void setup_rt_frame(int usig, struct target_sigaction *ka,
1770
target_siginfo_t *info,
1771
target_sigset_t *set, CPUARMState *env)
1773
if (get_osversion() >= 0x020612) {
1774
setup_rt_frame_v2(usig, ka, info, set, env);
1776
setup_rt_frame_v1(usig, ka, info, set, env);
1781
restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
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);
1807
err |= !valid_user_regs(env);
1812
static long do_sigreturn_v1(CPUARMState *env)
1814
abi_ulong frame_addr;
1815
struct sigframe_v1 *frame = NULL;
1816
target_sigset_t set;
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.
1825
frame_addr = env->regs[13];
1826
if (frame_addr & 7) {
1830
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1833
if (__get_user(set.sig[0], &frame->sc.oldmask))
1835
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1836
if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1840
target_to_host_sigset_internal(&host_set, &set);
1841
sigprocmask(SIG_SETMASK, &host_set, NULL);
1843
if (restore_sigcontext(env, &frame->sc))
1847
/* Send SIGTRAP if we're single-stepping */
1848
if (ptrace_cancel_bpt(current))
1849
send_sig(SIGTRAP, current, 1);
1851
unlock_user_struct(frame, frame_addr, 0);
1852
return env->regs[0];
1855
unlock_user_struct(frame, frame_addr, 0);
1856
force_sig(TARGET_SIGSEGV /* , current */);
1860
static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1863
abi_ulong magic, sz;
1864
uint32_t fpscr, fpexc;
1865
struct target_vfp_sigframe *vfpframe;
1866
vfpframe = (struct target_vfp_sigframe *)regspace;
1868
__get_user(magic, &vfpframe->magic);
1869
__get_user(sz, &vfpframe->size);
1870
if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1873
for (i = 0; i < 32; i++) {
1874
__get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
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
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);
1890
static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1891
abi_ulong *regspace)
1894
abi_ulong magic, sz;
1895
struct target_iwmmxt_sigframe *iwmmxtframe;
1896
iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1898
__get_user(magic, &iwmmxtframe->magic);
1899
__get_user(sz, &iwmmxtframe->size);
1900
if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1903
for (i = 0; i < 16; i++) {
1904
__get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
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);
1915
static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1916
struct target_ucontext_v2 *uc)
1919
abi_ulong *regspace;
1921
target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1922
sigprocmask(SIG_SETMASK, &host_set, NULL);
1924
if (restore_sigcontext(env, &uc->tuc_mcontext))
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);
1935
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1936
regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1942
if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1946
/* Send SIGTRAP if we're single-stepping */
1947
if (ptrace_cancel_bpt(current))
1948
send_sig(SIGTRAP, current, 1);
1954
static long do_sigreturn_v2(CPUARMState *env)
1956
abi_ulong frame_addr;
1957
struct sigframe_v2 *frame = NULL;
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.
1964
frame_addr = env->regs[13];
1965
if (frame_addr & 7) {
1969
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1972
if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1975
unlock_user_struct(frame, frame_addr, 0);
1976
return env->regs[0];
1979
unlock_user_struct(frame, frame_addr, 0);
1980
force_sig(TARGET_SIGSEGV /* , current */);
1984
long do_sigreturn(CPUARMState *env)
1986
if (get_osversion() >= 0x020612) {
1987
return do_sigreturn_v2(env);
1989
return do_sigreturn_v1(env);
1993
static long do_rt_sigreturn_v1(CPUARMState *env)
1995
abi_ulong frame_addr;
1996
struct rt_sigframe_v1 *frame = NULL;
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.
2004
frame_addr = env->regs[13];
2005
if (frame_addr & 7) {
2009
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2012
target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2013
sigprocmask(SIG_SETMASK, &host_set, NULL);
2015
if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2018
if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2022
/* Send SIGTRAP if we're single-stepping */
2023
if (ptrace_cancel_bpt(current))
2024
send_sig(SIGTRAP, current, 1);
2026
unlock_user_struct(frame, frame_addr, 0);
2027
return env->regs[0];
2030
unlock_user_struct(frame, frame_addr, 0);
2031
force_sig(TARGET_SIGSEGV /* , current */);
2035
static long do_rt_sigreturn_v2(CPUARMState *env)
2037
abi_ulong frame_addr;
2038
struct rt_sigframe_v2 *frame = NULL;
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.
2045
frame_addr = env->regs[13];
2046
if (frame_addr & 7) {
2050
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2053
if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2056
unlock_user_struct(frame, frame_addr, 0);
2057
return env->regs[0];
2060
unlock_user_struct(frame, frame_addr, 0);
2061
force_sig(TARGET_SIGSEGV /* , current */);
2065
long do_rt_sigreturn(CPUARMState *env)
2067
if (get_osversion() >= 0x020612) {
2068
return do_rt_sigreturn_v2(env);
2070
return do_rt_sigreturn_v1(env);
2074
#elif defined(TARGET_SPARC)
2076
#define __SUNOS_MAXWIN 31
2078
/* This is what SunOS does, so shall I. */
2079
struct target_sigcontext {
2080
abi_ulong sigc_onstack; /* state to restore */
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. */
2090
/* Now comes information regarding the users window set
2091
* at the time of the signal.
2093
abi_ulong sigc_oswins; /* outstanding windows */
2095
/* stack ptrs for each regwin buf */
2096
char *sigc_spbuf[__SUNOS_MAXWIN];
2098
/* Windows to restore after signal */
2100
abi_ulong locals[8];
2102
} sigc_wbuf[__SUNOS_MAXWIN];
2104
/* A Sparc stack frame */
2105
struct sparc_stackf {
2106
abi_ulong locals[8];
2108
/* It's simpler to treat fp and callers_pc as elements of ins[]
2109
* since we never need to access them ourselves.
2113
abi_ulong xxargs[1];
2122
abi_ulong u_regs[16]; /* globals and ins */
2128
abi_ulong si_float_regs[32];
2129
unsigned long si_fsr;
2130
unsigned long si_fpqdepth;
2132
unsigned long *insn_addr;
2135
} qemu_siginfo_fpu_t;
2138
struct target_signal_frame {
2139
struct sparc_stackf ss;
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;
2147
struct target_rt_signal_frame {
2148
struct sparc_stackf ss;
2153
unsigned int insns[2];
2155
unsigned int extra_size; /* Should be 0 */
2156
qemu_siginfo_fpu_t fpu_state;
2170
#define UREG_FP UREG_I6
2171
#define UREG_SP UREG_O6
2173
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2175
unsigned long framesize)
2179
sp = env->regwptr[UREG_FP];
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;
2187
return sp - framesize;
2191
setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
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]);
2202
for (i=0; i < 8; i++) {
2203
err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2205
err |= __put_user(mask, &si->si_mask);
2211
setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2212
CPUSPARCState *env, unsigned long mask)
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);
2227
#define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2229
static void setup_frame(int sig, struct target_sigaction *ka,
2230
target_sigset_t *set, CPUSPARCState *env)
2233
struct target_signal_frame *sf;
2234
int sigframe_size, err, i;
2236
/* 1. Make sure everything is clean */
2237
//synchronize_user_stack();
2239
sigframe_size = NF_ALIGNEDSZ;
2240
sf_addr = get_sigframe(ka, env, sigframe_size);
2242
sf = lock_user(VERIFY_WRITE, sf_addr,
2243
sizeof(struct target_signal_frame), 0);
2247
//fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2249
if (invalid_frame_pointer(sf, sigframe_size))
2250
goto sigill_and_return;
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);
2256
//err |= save_fpu_state(regs, &sf->fpu_state);
2257
//err |= __put_user(&sf->fpu_state, &sf->fpu_save);
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]);
2264
for (i = 0; i < 8; i++) {
2265
err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2267
for (i = 0; i < 8; i++) {
2268
err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
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);
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;
2290
env->regwptr[UREG_I7] = sf_addr +
2291
offsetof(struct target_signal_frame, insns) - 2 * 4;
2293
/* mov __NR_sigreturn, %g1 */
2295
err |= __put_user(val32, &sf->insns[0]);
2299
err |= __put_user(val32, &sf->insns[1]);
2303
/* Flush instruction space. */
2304
//flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2307
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2311
force_sig(TARGET_SIGILL);
2314
//fprintf(stderr, "force_sig\n");
2315
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2316
force_sig(TARGET_SIGSEGV);
2319
restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2324
if (current->flags & PF_USEDFPU)
2325
regs->psr &= ~PSR_EF;
2327
if (current == last_task_used_math) {
2328
last_task_used_math = 0;
2329
regs->psr &= ~PSR_EF;
2332
current->used_math = 1;
2333
current->flags &= ~PF_USEDFPU;
2336
if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
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);
2345
err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2346
if (current->thread.fpqdepth != 0)
2347
err |= __copy_from_user(¤t->thread.fpqueue[0],
2348
&fpu->si_fpqueue[0],
2349
((sizeof(unsigned long) +
2350
(sizeof(unsigned long *)))*16));
2356
static void setup_rt_frame(int sig, struct target_sigaction *ka,
2357
target_siginfo_t *info,
2358
target_sigset_t *set, CPUSPARCState *env)
2360
fprintf(stderr, "setup_rt_frame: not implemented\n");
2363
long do_sigreturn(CPUSPARCState *env)
2366
struct target_signal_frame *sf;
2367
uint32_t up_psr, pc, npc;
2368
target_sigset_t set;
2372
sf_addr = env->regwptr[UREG_FP];
2373
if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
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]);
2379
//cpu_dump_state(env, stderr, fprintf, 0);
2381
/* 1. Make sure we are not getting garbage from the user */
2386
err = __get_user(pc, &sf->info.si_regs.pc);
2387
err |= __get_user(npc, &sf->info.si_regs.npc);
2392
/* 2. Restore the state */
2393
err |= __get_user(up_psr, &sf->info.si_regs.psr);
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 */));
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]);
2405
for (i=0; i < 8; i++) {
2406
err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2409
/* FIXME: implement FPU save/restore:
2410
* __get_user(fpu_save, &sf->fpu_save);
2412
* err |= restore_fpu_state(env, fpu_save);
2415
/* This is pretty much atomic, no amount locking would prevent
2416
* the races which exist anyways.
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]));
2423
target_to_host_sigset_internal(&host_set, &set);
2424
sigprocmask(SIG_SETMASK, &host_set, NULL);
2428
unlock_user_struct(sf, sf_addr, 0);
2429
return env->regwptr[0];
2432
unlock_user_struct(sf, sf_addr, 0);
2433
force_sig(TARGET_SIGSEGV);
2436
long do_rt_sigreturn(CPUSPARCState *env)
2438
fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2439
return -TARGET_ENOSYS;
2442
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2464
typedef abi_ulong target_mc_greg_t;
2465
typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2467
struct target_mc_fq {
2468
abi_ulong *mcfq_addr;
2472
struct target_mc_fpu {
2476
//uint128_t qregs[16];
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;
2486
typedef struct target_mc_fpu target_mc_fpu_t;
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;
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;
2502
/* A V9 register window */
2503
struct target_reg_window {
2504
abi_ulong locals[8];
2508
#define TARGET_STACK_BIAS 2047
2510
/* {set, get}context() needed for 64-bit SparcLinux userland. */
2511
void sparc64_set_context(CPUSPARCState *env)
2514
struct target_ucontext *ucp;
2515
target_mc_gregset_t *grp;
2516
abi_ulong pc, npc, tstate;
2517
abi_ulong fp, i7, w_addr;
2521
ucp_addr = env->regwptr[UREG_I0];
2522
if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
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))
2529
if (env->regwptr[UREG_I1]) {
2530
target_sigset_t target_set;
2533
if (TARGET_NSIG_WORDS == 1) {
2534
if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
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);
2542
err |= __get_user(*dst, src);
2546
target_to_host_sigset_internal(&set, &target_set);
2547
sigprocmask(SIG_SETMASK, &set, NULL);
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]));
2572
err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2573
err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2575
w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2576
if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2579
if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
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));
2587
err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2589
uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2590
for (i = 0; i < 64; i++, src++) {
2592
err |= __get_user(env->fpr[i/2].l.lower, src);
2594
err |= __get_user(env->fpr[i/2].l.upper, src);
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));
2604
unlock_user_struct(ucp, ucp_addr, 0);
2607
unlock_user_struct(ucp, ucp_addr, 0);
2608
force_sig(TARGET_SIGSEGV);
2611
void sparc64_get_context(CPUSPARCState *env)
2614
struct target_ucontext *ucp;
2615
target_mc_gregset_t *grp;
2616
target_mcontext_t *mcp;
2617
abi_ulong fp, i7, w_addr;
2620
target_sigset_t target_set;
2623
ucp_addr = env->regwptr[UREG_I0];
2624
if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2627
mcp = &ucp->tuc_mcontext;
2628
grp = &mcp->mc_gregs;
2630
/* Skip over the trap instruction, first. */
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);
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);
2647
err |= __put_user(*src, dst);
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]));
2673
w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2675
if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2678
if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2681
err |= __put_user(fp, &(mcp->mc_fp));
2682
err |= __put_user(i7, &(mcp->mc_i7));
2685
uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2686
for (i = 0; i < 64; i++, dst++) {
2688
err |= __put_user(env->fpr[i/2].l.lower, dst);
2690
err |= __put_user(env->fpr[i/2].l.upper, dst);
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));
2700
unlock_user_struct(ucp, ucp_addr, 1);
2703
unlock_user_struct(ucp, ucp_addr, 1);
2704
force_sig(TARGET_SIGSEGV);
2707
#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2709
# if defined(TARGET_ABI_MIPSO32)
2710
struct target_sigcontext {
2711
uint32_t sc_regmask; /* Unused */
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 */
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;
2731
# else /* N32 || N64 */
2732
struct target_sigcontext {
2733
uint64_t sc_regs[32];
2734
uint64_t sc_fpregs[32];
2744
uint32_t sc_fpc_csr;
2745
uint32_t sc_used_math;
2747
uint32_t sc_reserved;
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;
2758
struct target_ucontext {
2759
target_ulong tuc_flags;
2760
target_ulong tuc_link;
2761
target_stack_t tuc_stack;
2763
struct target_sigcontext tuc_mcontext;
2764
target_sigset_t tuc_sigmask;
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;
2774
/* Install trampoline to jump back from signal handler */
2775
static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2780
* Set up the return code ...
2782
* li v0, __NR__foo_sigreturn
2786
err |= __put_user(0x24020000 + syscall, tramp + 0);
2787
err |= __put_user(0x0000000c , tramp + 1);
2792
setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2797
err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
2798
regs->hflags &= ~MIPS_HFLAG_BMASK;
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]);
2805
err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2806
err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
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);
2817
uint32_t dsp = cpu_rddsp(0x3ff, regs);
2818
err |= __put_user(dsp, &sc->sc_dsp);
2821
err |= __put_user(1, &sc->sc_used_math);
2823
for (i = 0; i < 32; ++i) {
2824
err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2831
restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2836
err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2838
err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2839
err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2841
for (i = 1; i < 32; ++i) {
2842
err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
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);
2853
err |= __get_user(dsp, &sc->sc_dsp);
2854
cpu_wrdsp(dsp, 0x3ff, regs);
2857
for (i = 0; i < 32; ++i) {
2858
err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2865
* Determine which stack to use..
2867
static inline abi_ulong
2868
get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2872
/* Default to using normal stack */
2873
sp = regs->active_tc.gpr[29];
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.
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;
2887
return (sp - frame_size) & ~7;
2890
static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
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;
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)
2904
struct sigframe *frame;
2905
abi_ulong frame_addr;
2908
frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2909
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2912
install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2914
if(setup_sigcontext(regs, &frame->sf_sc))
2917
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2918
if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2923
* Arguments to signal handler:
2925
* a0 = signal number
2926
* a1 = 0 (should be cause)
2927
* a2 = pointer to struct sigcontext
2929
* $25 and PC point to the signal handler, $29 points to the
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);
2946
unlock_user_struct(frame, frame_addr, 1);
2947
force_sig(TARGET_SIGSEGV/*, current*/);
2950
long do_sigreturn(CPUMIPSState *regs)
2952
struct sigframe *frame;
2953
abi_ulong frame_addr;
2955
target_sigset_t target_set;
2958
#if defined(DEBUG_SIGNAL)
2959
fprintf(stderr, "do_sigreturn\n");
2961
frame_addr = regs->active_tc.gpr[29];
2962
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2965
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2966
if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2970
target_to_host_sigset_internal(&blocked, &target_set);
2971
sigprocmask(SIG_SETMASK, &blocked, NULL);
2973
if (restore_sigcontext(regs, &frame->sf_sc))
2978
* Don't let your children do this ...
2980
__asm__ __volatile__(
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 ? */
2993
return -TARGET_QEMU_ESIGRETURN;
2996
force_sig(TARGET_SIGSEGV/*, current*/);
3001
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3002
target_siginfo_t *info,
3003
target_sigset_t *set, CPUMIPSState *env)
3005
struct target_rt_sigframe *frame;
3006
abi_ulong frame_addr;
3009
frame_addr = get_sigframe(ka, env, sizeof(*frame));
3010
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3013
install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3015
copy_siginfo_to_user(&frame->rs_info, info);
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);
3024
setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3026
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3027
__put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3031
* Arguments to signal handler:
3033
* a0 = signal number
3034
* a1 = pointer to siginfo_t
3035
* a2 = pointer to struct ucontext
3037
* $25 and PC point to the signal handler, $29 points to the
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);
3057
unlock_user_struct(frame, frame_addr, 1);
3058
force_sig(TARGET_SIGSEGV/*, current*/);
3061
long do_rt_sigreturn(CPUMIPSState *env)
3063
struct target_rt_sigframe *frame;
3064
abi_ulong frame_addr;
3067
#if defined(DEBUG_SIGNAL)
3068
fprintf(stderr, "do_rt_sigreturn\n");
3070
frame_addr = env->active_tc.gpr[29];
3071
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3074
target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3075
sigprocmask(SIG_SETMASK, &blocked, NULL);
3077
if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
3080
if (do_sigaltstack(frame_addr +
3081
offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3082
0, get_sp_from_cpustate(env)) == -EFAULT)
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 ? */
3090
return -TARGET_QEMU_ESIGRETURN;
3093
force_sig(TARGET_SIGSEGV/*, current*/);
3097
#elif defined(TARGET_SH4)
3100
* code and data structures from linux kernel:
3101
* include/asm-sh/sigcontext.h
3102
* arch/sh/kernel/signal.c
3105
struct target_sigcontext {
3106
target_ulong oldmask;
3109
target_ulong sc_gregs[16];
3113
target_ulong sc_gbr;
3114
target_ulong sc_mach;
3115
target_ulong sc_macl;
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;
3125
struct target_sigframe
3127
struct target_sigcontext sc;
3128
target_ulong extramask[TARGET_NSIG_WORDS-1];
3129
uint16_t retcode[3];
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 */
3141
struct target_rt_sigframe
3143
struct target_siginfo info;
3144
struct target_ucontext uc;
3145
uint16_t retcode[3];
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 */
3152
static abi_ulong get_sigframe(struct target_sigaction *ka,
3153
unsigned long sp, size_t frame_size)
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;
3159
return (sp - frame_size) & -8ul;
3162
static int setup_sigcontext(struct target_sigcontext *sc,
3163
CPUSH4State *regs, unsigned long mask)
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);
3182
for (i=0; i<16; i++) {
3183
err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3185
err |= __put_user(regs->fpscr, &sc->sc_fpscr);
3186
err |= __put_user(regs->fpul, &sc->sc_fpul);
3188
/* non-iBCS2 extensions.. */
3189
err |= __put_user(mask, &sc->oldmask);
3194
static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3197
unsigned int err = 0;
3200
#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
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);
3214
for (i=0; i<16; i++) {
3215
err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3217
err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3218
err |= __get_user(regs->fpul, &sc->sc_fpul);
3220
regs->tra = -1; /* disable syscall checks */
3221
err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3225
static void setup_frame(int sig, struct target_sigaction *ka,
3226
target_sigset_t *set, CPUSH4State *regs)
3228
struct target_sigframe *frame;
3229
abi_ulong frame_addr;
3234
frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3235
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3238
signal = current_exec_domain_sig(sig);
3240
err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3242
for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3243
err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
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;
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;
3261
/* Set up registers for signal handler */
3262
regs->gregs[15] = frame_addr;
3263
regs->gregs[4] = signal; /* Arg for signal handler */
3265
regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3266
regs->pc = (unsigned long) ka->_sa_handler;
3268
unlock_user_struct(frame, frame_addr, 1);
3272
unlock_user_struct(frame, frame_addr, 1);
3273
force_sig(TARGET_SIGSEGV);
3276
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3277
target_siginfo_t *info,
3278
target_sigset_t *set, CPUSH4State *regs)
3280
struct target_rt_sigframe *frame;
3281
abi_ulong frame_addr;
3286
frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3287
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3290
signal = current_exec_domain_sig(sig);
3292
err |= copy_siginfo_to_user(&frame->info, info);
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,
3305
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3306
err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
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;
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;
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;
3331
unlock_user_struct(frame, frame_addr, 1);
3335
unlock_user_struct(frame, frame_addr, 1);
3336
force_sig(TARGET_SIGSEGV);
3339
long do_sigreturn(CPUSH4State *regs)
3341
struct target_sigframe *frame;
3342
abi_ulong frame_addr;
3344
target_sigset_t target_set;
3349
#if defined(DEBUG_SIGNAL)
3350
fprintf(stderr, "do_sigreturn\n");
3352
frame_addr = regs->gregs[15];
3353
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
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]));
3364
target_to_host_sigset_internal(&blocked, &target_set);
3365
sigprocmask(SIG_SETMASK, &blocked, NULL);
3367
if (restore_sigcontext(regs, &frame->sc, &r0))
3370
unlock_user_struct(frame, frame_addr, 0);
3374
unlock_user_struct(frame, frame_addr, 0);
3375
force_sig(TARGET_SIGSEGV);
3379
long do_rt_sigreturn(CPUSH4State *regs)
3381
struct target_rt_sigframe *frame;
3382
abi_ulong frame_addr;
3386
#if defined(DEBUG_SIGNAL)
3387
fprintf(stderr, "do_rt_sigreturn\n");
3389
frame_addr = regs->gregs[15];
3390
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3393
target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3394
sigprocmask(SIG_SETMASK, &blocked, NULL);
3396
if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3399
if (do_sigaltstack(frame_addr +
3400
offsetof(struct target_rt_sigframe, uc.tuc_stack),
3401
0, get_sp_from_cpustate(regs)) == -EFAULT)
3404
unlock_user_struct(frame, frame_addr, 0);
3408
unlock_user_struct(frame, frame_addr, 0);
3409
force_sig(TARGET_SIGSEGV);
3412
#elif defined(TARGET_MICROBLAZE)
3414
struct target_sigcontext {
3415
struct target_pt_regs regs; /* needs to be first */
3419
struct target_stack_t {
3422
unsigned int ss_size;
3425
struct target_ucontext {
3426
abi_ulong tuc_flags;
3428
struct target_stack_t tuc_stack;
3429
struct target_sigcontext tuc_mcontext;
3430
uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3433
/* Signal frames. */
3434
struct target_signal_frame {
3435
struct target_ucontext uc;
3436
uint32_t extramask[TARGET_NSIG_WORDS - 1];
3440
struct rt_signal_frame {
3446
static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
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);
3483
static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
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);
3520
static abi_ulong get_sigframe(struct target_sigaction *ka,
3521
CPUMBState *env, int frame_size)
3523
abi_ulong sp = env->regs[1];
3525
if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3526
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3528
return ((sp - frame_size) & -8UL);
3531
static void setup_frame(int sig, struct target_sigaction *ka,
3532
target_sigset_t *set, CPUMBState *env)
3534
struct target_signal_frame *frame;
3535
abi_ulong frame_addr;
3539
frame_addr = get_sigframe(ka, env, sizeof *frame);
3540
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3543
/* Save the mask. */
3544
err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3548
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3549
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3553
setup_sigcontext(&frame->uc.tuc_mcontext, env);
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;
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);
3568
err |= __put_user(t, frame->tramp + 1);
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;
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 */
3583
/* arg 1: sigcontext */
3584
env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3586
/* Offset of 4 to handle microblaze rtid r14, 0 */
3587
env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3589
unlock_user_struct(frame, frame_addr, 1);
3592
unlock_user_struct(frame, frame_addr, 1);
3593
force_sig(TARGET_SIGSEGV);
3596
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3597
target_siginfo_t *info,
3598
target_sigset_t *set, CPUMBState *env)
3600
fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3603
long do_sigreturn(CPUMBState *env)
3605
struct target_signal_frame *frame;
3606
abi_ulong frame_addr;
3607
target_sigset_t target_set;
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))
3616
/* Restore blocked signals */
3617
if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3619
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3620
if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3623
target_to_host_sigset_internal(&set, &target_set);
3624
sigprocmask(SIG_SETMASK, &set, NULL);
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];
3631
unlock_user_struct(frame, frame_addr, 0);
3632
return env->regs[10];
3634
unlock_user_struct(frame, frame_addr, 0);
3635
force_sig(TARGET_SIGSEGV);
3638
long do_rt_sigreturn(CPUMBState *env)
3640
fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3641
return -TARGET_ENOSYS;
3644
#elif defined(TARGET_CRIS)
3646
struct target_sigcontext {
3647
struct target_pt_regs regs; /* needs to be first */
3649
uint32_t usp; /* usp before stacking this gunk on it */
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. */
3659
struct rt_signal_frame {
3664
uint8_t retcode[8]; /* Trampoline code. */
3667
static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
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);
3690
static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
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);
3713
static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3716
/* Align the stack downwards to 4. */
3717
sp = (env->regs[R_SP] & ~3);
3718
return sp - framesize;
3721
static void setup_frame(int sig, struct target_sigaction *ka,
3722
target_sigset_t *set, CPUCRISState *env)
3724
struct target_signal_frame *frame;
3725
abi_ulong frame_addr;
3729
frame_addr = get_sigframe(env, sizeof *frame);
3730
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
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.
3738
* This is movu.w __NR_sigreturn, r9; break 13;
3740
err |= __put_user(0x9c5f, frame->retcode+0);
3741
err |= __put_user(TARGET_NR_sigreturn,
3743
err |= __put_user(0xe93d, frame->retcode+4);
3745
/* Save the mask. */
3746
err |= __put_user(set->sig[0], &frame->sc.oldmask);
3750
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3751
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3755
setup_sigcontext(&frame->sc, env);
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);
3764
unlock_user_struct(frame, frame_addr, 1);
3767
unlock_user_struct(frame, frame_addr, 1);
3768
force_sig(TARGET_SIGSEGV);
3771
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3772
target_siginfo_t *info,
3773
target_sigset_t *set, CPUCRISState *env)
3775
fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3778
long do_sigreturn(CPUCRISState *env)
3780
struct target_signal_frame *frame;
3781
abi_ulong frame_addr;
3782
target_sigset_t target_set;
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))
3791
/* Restore blocked signals */
3792
if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3794
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3795
if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3798
target_to_host_sigset_internal(&set, &target_set);
3799
sigprocmask(SIG_SETMASK, &set, NULL);
3801
restore_sigcontext(&frame->sc, env);
3802
unlock_user_struct(frame, frame_addr, 0);
3803
return env->regs[10];
3805
unlock_user_struct(frame, frame_addr, 0);
3806
force_sig(TARGET_SIGSEGV);
3809
long do_rt_sigreturn(CPUCRISState *env)
3811
fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3812
return -TARGET_ENOSYS;
3815
#elif defined(TARGET_OPENRISC)
3817
struct target_sigcontext {
3818
struct target_pt_regs regs;
3823
struct target_ucontext {
3824
abi_ulong tuc_flags;
3826
target_stack_t tuc_stack;
3827
struct target_sigcontext tuc_mcontext;
3828
target_sigset_t tuc_sigmask; /* mask last for extensibility */
3831
struct target_rt_sigframe {
3834
struct target_siginfo info;
3835
struct target_sigcontext sc;
3836
struct target_ucontext uc;
3837
unsigned char retcode[16]; /* trampoline code */
3840
/* This is the asm-generic/ucontext.h version */
3842
static int restore_sigcontext(CPUOpenRISCState *regs,
3843
struct target_sigcontext *sc)
3845
unsigned int err = 0;
3846
unsigned long old_usp;
3848
/* Alwys make any pending restarted system call return -EINTR */
3849
current_thread_info()->restart_block.fn = do_no_restart_syscall;
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)
3856
if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3860
/* make sure the U-flag is set so user-mode cannot fool us */
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)
3869
err |= __get_user(old_usp, &sc->usp);
3870
phx_signal("old_usp 0x%lx", old_usp);
3872
__PHX__ REALLY /* ??? */
3874
regs->gpr[1] = old_usp;
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
3888
/* Set up a signal frame. */
3890
static int setup_sigcontext(struct target_sigcontext *sc,
3891
CPUOpenRISCState *regs,
3895
unsigned long usp = regs->gpr[1];
3897
/* copy the regs. they are first in sc so we can use sc directly */
3899
/*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
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;*/
3906
/* then some other stuff */
3907
err |= __put_user(mask, &sc->oldmask);
3908
err |= __put_user(usp, &sc->usp); return err;
3911
static inline unsigned long align_sigframe(unsigned long sp)
3918
static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3919
CPUOpenRISCState *regs,
3922
unsigned long sp = regs->gpr[1];
3923
int onsigstack = on_sig_stack(sp);
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;
3931
sp = align_sigframe(sp - frame_size);
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.
3938
if (onsigstack && !likely(on_sig_stack(sp))) {
3945
static void setup_frame(int sig, struct target_sigaction *ka,
3946
target_sigset_t *set, CPUOpenRISCState *env)
3948
qemu_log("Not implement.\n");
3951
static void setup_rt_frame(int sig, struct target_sigaction *ka,
3952
target_siginfo_t *info,
3953
target_sigset_t *set, CPUOpenRISCState *env)
3956
abi_ulong frame_addr;
3957
unsigned long return_ip;
3958
struct target_rt_sigframe *frame;
3959
abi_ulong info_addr, uc_addr;
3961
frame_addr = get_sigframe(ka, env, sizeof *frame);
3963
frame_addr = get_sigframe(ka, env, sizeof(*frame));
3964
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
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);
3973
if (ka->sa_flags & SA_SIGINFO) {
3974
err |= copy_siginfo_to_user(&frame->info, info);
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]);
3990
/*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
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));
4008
/* TODO what is the current->exec_domain stuff and invmap ? */
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 */
4017
/* actually move the usp to reflect the stacked frame */
4018
env->gpr[1] = (unsigned long)frame;
4023
unlock_user_struct(frame, frame_addr, 1);
4024
if (sig == TARGET_SIGSEGV) {
4025
ka->_sa_handler = TARGET_SIG_DFL;
4027
force_sig(TARGET_SIGSEGV);
4030
long do_sigreturn(CPUOpenRISCState *env)
4033
qemu_log("do_sigreturn: not implemented\n");
4034
return -TARGET_ENOSYS;
4037
long do_rt_sigreturn(CPUOpenRISCState *env)
4039
qemu_log("do_rt_sigreturn: not implemented\n");
4040
return -TARGET_ENOSYS;
4042
/* TARGET_OPENRISC */
4044
#elif defined(TARGET_S390X)
4046
#define __NUM_GPRS 16
4047
#define __NUM_FPRS 16
4048
#define __NUM_ACRS 16
4050
#define S390_SYSCALL_SIZE 2
4051
#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
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)
4062
target_ulong gprs[__NUM_GPRS];
4063
unsigned int acrs[__NUM_ACRS];
4064
} target_s390_regs_common;
4068
double fprs[__NUM_FPRS];
4069
} target_s390_fp_regs;
4072
target_s390_regs_common regs;
4073
target_s390_fp_regs fpregs;
4076
struct target_sigcontext {
4077
target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4078
target_sigregs *sregs;
4082
uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4083
struct target_sigcontext sc;
4084
target_sigregs sregs;
4086
uint8_t retcode[S390_SYSCALL_SIZE];
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 */
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;
4104
static inline abi_ulong
4105
get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4109
/* Default to using normal stack */
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;
4120
/* This is the legacy signal stack switching. */
4121
else if (/* FIXME !user_mode(regs) */ 0 &&
4122
!(ka->sa_flags & TARGET_SA_RESTORER) &&
4124
sp = (abi_ulong) ka->sa_restorer;
4127
return (sp - frame_size) & -8ul;
4130
static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4133
//save_access_regs(current->thread.acrs); FIXME
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]);
4142
for (i = 0; i < 16; i++) {
4143
__put_user(env->aregs[i], &sregs->regs.acrs[i]);
4146
* We have to store the fp registers to current->thread.fp_regs
4147
* to merge them with the emulated registers.
4149
//save_fp_regs(¤t->thread.fp_regs); FIXME
4150
for (i = 0; i < 16; i++) {
4151
__put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4155
static void setup_frame(int sig, struct target_sigaction *ka,
4156
target_sigset_t *set, CPUS390XState *env)
4159
abi_ulong frame_addr;
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)) {
4168
qemu_log("%s: 1\n", __FUNCTION__);
4169
if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
4173
save_sigregs(env, &frame->sregs);
4175
__put_user((abi_ulong)(unsigned long)&frame->sregs,
4176
(abi_ulong *)&frame->sc.sregs);
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;
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)))
4191
/* Set up backchain. */
4192
if (__put_user(env->regs[15], (abi_ulong *) frame)) {
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;
4200
env->regs[2] = sig; //map_signal(sig);
4201
env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
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;
4208
/* Place signal number on stack to allow backtrace from handler. */
4209
if (__put_user(env->regs[2], (int *) &frame->signo)) {
4212
unlock_user_struct(frame, frame_addr, 1);
4216
qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4217
unlock_user_struct(frame, frame_addr, 1);
4218
force_sig(TARGET_SIGSEGV);
4221
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4222
target_siginfo_t *info,
4223
target_sigset_t *set, CPUS390XState *env)
4227
abi_ulong frame_addr;
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)) {
4236
qemu_log("%s: 1\n", __FUNCTION__);
4237
if (copy_siginfo_to_user(&frame->info, info)) {
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]);
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;
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))) {
4266
/* Set up backchain. */
4267
if (__put_user(env->regs[15], (abi_ulong *) frame)) {
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;
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);
4281
qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4282
unlock_user_struct(frame, frame_addr, 1);
4283
force_sig(TARGET_SIGSEGV);
4287
restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4292
for (i = 0; i < 16; i++) {
4293
err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
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 */
4303
for (i = 0; i < 16; i++) {
4304
err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
4306
for (i = 0; i < 16; i++) {
4307
err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4313
long do_sigreturn(CPUS390XState *env)
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;
4322
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4325
if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
4329
target_to_host_sigset_internal(&set, &target_set);
4330
sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4332
if (restore_sigregs(env, &frame->sregs)) {
4336
unlock_user_struct(frame, frame_addr, 0);
4337
return env->regs[2];
4340
unlock_user_struct(frame, frame_addr, 0);
4341
force_sig(TARGET_SIGSEGV);
4345
long do_rt_sigreturn(CPUS390XState *env)
4348
abi_ulong frame_addr = env->regs[15];
4349
qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4350
(unsigned long long)frame_addr);
4353
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4356
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4358
sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4360
if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4364
if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4365
get_sp_from_cpustate(env)) == -EFAULT) {
4368
unlock_user_struct(frame, frame_addr, 0);
4369
return env->regs[2];
4372
unlock_user_struct(frame, frame_addr, 0);
4373
force_sig(TARGET_SIGSEGV);
4377
#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
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.
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. */
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
4392
#define SIGNAL_FRAMESIZE 64
4395
/* See arch/powerpc/include/asm/sigcontext.h. */
4396
struct target_sigcontext {
4397
target_ulong _unused[4];
4399
#if defined(TARGET_PPC64)
4402
target_ulong handler;
4403
target_ulong oldmask;
4404
target_ulong regs; /* struct pt_regs __user * */
4405
/* TODO: PPC64 includes extra bits here. */
4408
/* Indices for target_mcontext.mc_gregs, below.
4409
See arch/powerpc/include/asm/ptrace.h for details. */
4445
TARGET_PT_ORIG_R3 = 34,
4450
/* Yes, there are two registers with #39. One is 64-bit only. */
4452
TARGET_PT_SOFTE = 39,
4453
TARGET_PT_TRAP = 40,
4455
TARGET_PT_DSISR = 42,
4456
TARGET_PT_RESULT = 43,
4457
TARGET_PT_REGS_COUNT = 44
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. */
4472
/* SPE vector registers. One extra for SPEFSCR. */
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
4480
#define QEMU_NVRREG 33
4482
ppc_avr_t altivec[QEMU_NVRREG];
4484
} mc_vregs __attribute__((__aligned__(16)));
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)
4493
target_ulong tuc_regs; /* struct mcontext __user *
4494
points to uc_mcontext field */
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;
4501
int32_t tuc_maskext[30];
4502
int32_t tuc_pad2[3];
4503
struct target_mcontext tuc_mcontext;
4507
/* See arch/powerpc/kernel/signal_32.c. */
4508
struct target_sigframe {
4509
struct target_sigcontext sctx;
4510
struct target_mcontext mctx;
4514
struct target_rt_sigframe {
4515
struct target_siginfo info;
4516
struct target_ucontext uc;
4520
/* We use the mc_pad field for the signal return trampoline. */
4521
#define tramp mc_pad
4523
/* See arch/powerpc/kernel/signal.c. */
4524
static target_ulong get_sigframe(struct target_sigaction *ka,
4528
target_ulong oldsp, newsp;
4530
oldsp = env->gpr[1];
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);
4538
newsp = (oldsp - frame_size) & ~0xFUL;
4543
static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4546
target_ulong msr = env->msr;
4548
target_ulong ccr = 0;
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. */
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])) {
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]))
4566
for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4567
ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4569
if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
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];
4578
if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4579
__put_user(avr->u64[1], &vreg->u64[1])) {
4583
/* Set MSR_VR in the saved MSR value to indicate that
4584
frame->mc_vregs contains valid data. */
4586
if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4587
&frame->mc_vregs.altivec[32].u32[3]))
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])) {
4598
if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
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])) {
4611
for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4612
if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4617
/* Set MSR_SPE in the saved MSR value to indicate that
4618
frame->mc_vregs contains valid data. */
4620
if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4625
if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4628
/* Set up the sigreturn trampoline: li r0,sigret; sc. */
4630
if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4631
__put_user(0x44000002UL, &frame->tramp[1])) {
4639
static int restore_user_regs(CPUPPCState *env,
4640
struct target_mcontext *frame, int sig)
4642
target_ulong save_r2 = 0;
4649
save_r2 = env->gpr[2];
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])) {
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]))
4663
if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4666
for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4667
env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4671
env->gpr[2] = save_r2;
4674
if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4677
/* If doing signal return, restore the previous little-endian mode. */
4679
env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
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];
4687
if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4688
__get_user(avr->u64[1], &vreg->u64[1])) {
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])))
4699
/* Restore floating point registers. */
4700
if (env->insns_flags & PPC_FLOAT) {
4702
for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4703
if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4707
if (__get_user(fpscr, &frame->mc_fregs[32]))
4709
env->fpscr = (uint32_t) fpscr;
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++) {
4718
if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4721
env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4724
for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4725
if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4730
if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4737
static void setup_frame(int sig, struct target_sigaction *ka,
4738
target_sigset_t *set, CPUPPCState *env)
4740
struct target_sigframe *frame;
4741
struct target_sigcontext *sc;
4742
target_ulong frame_addr, newsp;
4746
frame_addr = get_sigframe(ka, env, sizeof(*frame));
4747
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4751
signal = current_exec_domain_sig(sig);
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]);
4758
err |= __put_user(set->sig[1], &sc->_unused[3]);
4760
err |= __put_user(h2g(&frame->mctx), &sc->regs);
4761
err |= __put_user(sig, &sc->signal);
4763
/* Save user regs. */
4764
err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
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);
4770
/* Turn off all fp exceptions. */
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);
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;
4788
unlock_user_struct(frame, frame_addr, 1);
4792
unlock_user_struct(frame, frame_addr, 1);
4793
qemu_log("segfaulting from setup_frame\n");
4794
force_sig(TARGET_SIGSEGV);
4797
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4798
target_siginfo_t *info,
4799
target_sigset_t *set, CPUPPCState *env)
4801
struct target_rt_sigframe *rt_sf;
4802
struct target_mcontext *frame;
4803
target_ulong rt_sf_addr, newsp = 0;
4807
rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4808
if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4811
signal = current_exec_domain_sig(sig);
4813
err |= copy_siginfo_to_user(&rt_sf->info, info);
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]);
4829
frame = &rt_sf->uc.tuc_mcontext;
4830
err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
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);
4836
/* Turn off all fp exceptions. */
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);
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;
4856
unlock_user_struct(rt_sf, rt_sf_addr, 1);
4860
unlock_user_struct(rt_sf, rt_sf_addr, 1);
4861
qemu_log("segfaulting from setup_rt_frame\n");
4862
force_sig(TARGET_SIGSEGV);
4866
long do_sigreturn(CPUPPCState *env)
4868
struct target_sigcontext *sc = NULL;
4869
struct target_mcontext *sr = NULL;
4870
target_ulong sr_addr = 0, sc_addr;
4872
target_sigset_t set;
4874
sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4875
if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4878
#if defined(TARGET_PPC64)
4879
set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4881
if(__get_user(set.sig[0], &sc->oldmask) ||
4882
__get_user(set.sig[1], &sc->_unused[3]))
4885
target_to_host_sigset_internal(&blocked, &set);
4886
sigprocmask(SIG_SETMASK, &blocked, NULL);
4888
if (__get_user(sr_addr, &sc->regs))
4890
if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4892
if (restore_user_regs(env, sr, 1))
4895
unlock_user_struct(sr, sr_addr, 1);
4896
unlock_user_struct(sc, sc_addr, 1);
4897
return -TARGET_QEMU_ESIGRETURN;
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);
4907
/* See arch/powerpc/kernel/signal_32.c. */
4908
static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4910
struct target_mcontext *mcp;
4911
target_ulong mcp_addr;
4913
target_sigset_t set;
4915
if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4919
#if defined(TARGET_PPC64)
4920
fprintf (stderr, "do_setcontext: not implemented\n");
4923
if (__get_user(mcp_addr, &ucp->tuc_regs))
4926
if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4929
target_to_host_sigset_internal(&blocked, &set);
4930
sigprocmask(SIG_SETMASK, &blocked, NULL);
4931
if (restore_user_regs(env, mcp, sig))
4934
unlock_user_struct(mcp, mcp_addr, 1);
4938
unlock_user_struct(mcp, mcp_addr, 1);
4943
long do_rt_sigreturn(CPUPPCState *env)
4945
struct target_rt_sigframe *rt_sf = NULL;
4946
target_ulong rt_sf_addr;
4948
rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4949
if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4952
if (do_setcontext(&rt_sf->uc, env, 1))
4955
do_sigaltstack(rt_sf_addr
4956
+ offsetof(struct target_rt_sigframe, uc.tuc_stack),
4959
unlock_user_struct(rt_sf, rt_sf_addr, 1);
4960
return -TARGET_QEMU_ESIGRETURN;
4963
unlock_user_struct(rt_sf, rt_sf_addr, 1);
4964
qemu_log("segfaulting from do_rt_sigreturn\n");
4965
force_sig(TARGET_SIGSEGV);
4969
#elif defined(TARGET_M68K)
4971
struct target_sigcontext {
4978
unsigned short sc_sr;
4982
struct target_sigframe
4989
abi_ulong extramask[TARGET_NSIG_WORDS-1];
4990
struct target_sigcontext sc;
4993
typedef int target_greg_t;
4994
#define TARGET_NGREG 18
4995
typedef target_greg_t target_gregset_t[TARGET_NGREG];
4997
typedef struct target_fpregset {
5000
} target_fpregset_t;
5002
struct target_mcontext {
5004
target_gregset_t gregs;
5005
target_fpregset_t fpregs;
5008
#define TARGET_MCONTEXT_VERSION 2
5010
struct target_ucontext {
5011
abi_ulong tuc_flags;
5013
target_stack_t tuc_stack;
5014
struct target_mcontext tuc_mcontext;
5015
abi_long tuc_filler[80];
5016
target_sigset_t tuc_sigmask;
5019
struct target_rt_sigframe
5026
struct target_siginfo info;
5027
struct target_ucontext uc;
5031
setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
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);
5049
restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
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);
5062
*pd0 = tswapl(sc->sc_d0);
5068
* Determine which stack to use..
5070
static inline abi_ulong
5071
get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5076
sp = regs->aregs[7];
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;
5083
return ((sp - frame_size) & -8UL);
5086
static void setup_frame(int sig, struct target_sigaction *ka,
5087
target_sigset_t *set, CPUM68KState *env)
5089
struct target_sigframe *frame;
5090
abi_ulong frame_addr;
5091
abi_ulong retcode_addr;
5096
frame_addr = get_sigframe(ka, env, sizeof *frame);
5097
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5100
err |= __put_user(sig, &frame->sig);
5102
sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
5103
err |= __put_user(sc_addr, &frame->psc);
5105
err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
5109
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5110
if (__put_user(set->sig[i], &frame->extramask[i - 1]))
5114
/* Set up to return from userspace. */
5116
retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5117
err |= __put_user(retcode_addr, &frame->pretcode);
5119
/* moveq #,d0; trap #0 */
5121
err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5122
(long *)(frame->retcode));
5127
/* Set up to return from userspace */
5129
env->aregs[7] = frame_addr;
5130
env->pc = ka->_sa_handler;
5132
unlock_user_struct(frame, frame_addr, 1);
5136
unlock_user_struct(frame, frame_addr, 1);
5137
force_sig(TARGET_SIGSEGV);
5140
static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5143
target_greg_t *gregs = uc->tuc_mcontext.gregs;
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]);
5169
static inline int target_rt_restore_ucontext(CPUM68KState *env,
5170
struct target_ucontext *uc,
5175
target_greg_t *gregs = uc->tuc_mcontext.gregs;
5177
err = __get_user(temp, &uc->tuc_mcontext.version);
5178
if (temp != TARGET_MCONTEXT_VERSION)
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);
5202
*pd0 = env->dregs[0];
5209
static void setup_rt_frame(int sig, struct target_sigaction *ka,
5210
target_siginfo_t *info,
5211
target_sigset_t *set, CPUM68KState *env)
5213
struct target_rt_sigframe *frame;
5214
abi_ulong frame_addr;
5215
abi_ulong retcode_addr;
5216
abi_ulong info_addr;
5221
frame_addr = get_sigframe(ka, env, sizeof *frame);
5222
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5225
err |= __put_user(sig, &frame->sig);
5227
info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5228
err |= __put_user(info_addr, &frame->pinfo);
5230
uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5231
err |= __put_user(uc_addr, &frame->puc);
5233
err |= copy_siginfo_to_user(&frame->info, info);
5235
/* Create the ucontext */
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);
5250
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5251
if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
5255
/* Set up to return from userspace. */
5257
retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5258
err |= __put_user(retcode_addr, &frame->pretcode);
5260
/* moveq #,d0; notb d0; trap #0 */
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));
5269
/* Set up to return from userspace */
5271
env->aregs[7] = frame_addr;
5272
env->pc = ka->_sa_handler;
5274
unlock_user_struct(frame, frame_addr, 1);
5278
unlock_user_struct(frame, frame_addr, 1);
5279
force_sig(TARGET_SIGSEGV);
5282
long do_sigreturn(CPUM68KState *env)
5284
struct target_sigframe *frame;
5285
abi_ulong frame_addr = env->aregs[7] - 4;
5286
target_sigset_t target_set;
5290
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5293
/* set blocked signals */
5295
if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
5298
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5299
if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
5303
target_to_host_sigset_internal(&set, &target_set);
5304
sigprocmask(SIG_SETMASK, &set, NULL);
5306
/* restore registers */
5308
if (restore_sigcontext(env, &frame->sc, &d0))
5311
unlock_user_struct(frame, frame_addr, 0);
5315
unlock_user_struct(frame, frame_addr, 0);
5316
force_sig(TARGET_SIGSEGV);
5320
long do_rt_sigreturn(CPUM68KState *env)
5322
struct target_rt_sigframe *frame;
5323
abi_ulong frame_addr = env->aregs[7] - 4;
5324
target_sigset_t target_set;
5328
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5331
target_to_host_sigset_internal(&set, &target_set);
5332
sigprocmask(SIG_SETMASK, &set, NULL);
5334
/* restore registers */
5336
if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5339
if (do_sigaltstack(frame_addr +
5340
offsetof(struct target_rt_sigframe, uc.tuc_stack),
5341
0, get_sp_from_cpustate(env)) == -EFAULT)
5344
unlock_user_struct(frame, frame_addr, 0);
5348
unlock_user_struct(frame, frame_addr, 0);
5349
force_sig(TARGET_SIGSEGV);
5353
#elif defined(TARGET_ALPHA)
5355
struct target_sigcontext {
5356
abi_long sc_onstack;
5360
abi_long sc_regs[32];
5361
abi_long sc_ownedfp;
5362
abi_long sc_fpregs[32];
5364
abi_ulong sc_fp_control;
5365
abi_ulong sc_reserved1;
5366
abi_ulong sc_reserved2;
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;
5377
struct target_ucontext {
5378
abi_ulong tuc_flags;
5380
abi_ulong tuc_osf_sigmask;
5381
target_stack_t tuc_stack;
5382
struct target_sigcontext tuc_mcontext;
5383
target_sigset_t tuc_sigmask;
5386
struct target_sigframe {
5387
struct target_sigcontext sc;
5388
unsigned int retcode[3];
5391
struct target_rt_sigframe {
5392
target_siginfo_t info;
5393
struct target_ucontext uc;
5394
unsigned int retcode[3];
5397
#define INSN_MOV_R30_R16 0x47fe0410
5398
#define INSN_LDI_R0 0x201f0000
5399
#define INSN_CALLSYS 0x00000083
5401
static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5402
abi_ulong frame_addr, target_sigset_t *set)
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);
5411
for (i = 0; i < 31; ++i) {
5412
err |= __put_user(env->ir[i], &sc->sc_regs[i]);
5414
err |= __put_user(0, &sc->sc_regs[31]);
5416
for (i = 0; i < 31; ++i) {
5417
err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
5419
err |= __put_user(0, &sc->sc_fpregs[31]);
5420
err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
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 */
5429
static int restore_sigcontext(CPUAlphaState *env,
5430
struct target_sigcontext *sc)
5435
err |= __get_user(env->pc, &sc->sc_pc);
5437
for (i = 0; i < 31; ++i) {
5438
err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5440
for (i = 0; i < 31; ++i) {
5441
err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5444
err |= __get_user(fpcr, &sc->sc_fpcr);
5445
cpu_alpha_store_fpcr(env, fpcr);
5450
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5452
unsigned long framesize)
5454
abi_ulong sp = env->ir[IR_SP];
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;
5460
return (sp - framesize) & -32;
5463
static void setup_frame(int sig, struct target_sigaction *ka,
5464
target_sigset_t *set, CPUAlphaState *env)
5466
abi_ulong frame_addr, r26;
5467
struct target_sigframe *frame;
5470
frame_addr = get_sigframe(ka, env, sizeof(*frame));
5471
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5475
err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5477
if (ka->sa_restorer) {
5478
r26 = ka->sa_restorer;
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]);
5488
unlock_user_struct(frame, frame_addr, 1);
5492
if (sig == TARGET_SIGSEGV) {
5493
ka->_sa_handler = TARGET_SIG_DFL;
5495
force_sig(TARGET_SIGSEGV);
5498
env->ir[IR_RA] = r26;
5499
env->ir[IR_PV] = env->pc = ka->_sa_handler;
5500
env->ir[IR_A0] = sig;
5502
env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5503
env->ir[IR_SP] = frame_addr;
5506
static void setup_rt_frame(int sig, struct target_sigaction *ka,
5507
target_siginfo_t *info,
5508
target_sigset_t *set, CPUAlphaState *env)
5510
abi_ulong frame_addr, r26;
5511
struct target_rt_sigframe *frame;
5514
frame_addr = get_sigframe(ka, env, sizeof(*frame));
5515
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5519
err |= copy_siginfo_to_user(&frame->info, info);
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]);
5535
if (ka->sa_restorer) {
5536
r26 = ka->sa_restorer;
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]);
5548
if (sig == TARGET_SIGSEGV) {
5549
ka->_sa_handler = TARGET_SIG_DFL;
5551
force_sig(TARGET_SIGSEGV);
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;
5562
long do_sigreturn(CPUAlphaState *env)
5564
struct target_sigcontext *sc;
5565
abi_ulong sc_addr = env->ir[IR_A0];
5566
target_sigset_t target_set;
5569
if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5573
target_sigemptyset(&target_set);
5574
if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5578
target_to_host_sigset_internal(&set, &target_set);
5579
sigprocmask(SIG_SETMASK, &set, NULL);
5581
if (restore_sigcontext(env, sc)) {
5584
unlock_user_struct(sc, sc_addr, 0);
5585
return env->ir[IR_V0];
5588
unlock_user_struct(sc, sc_addr, 0);
5589
force_sig(TARGET_SIGSEGV);
5592
long do_rt_sigreturn(CPUAlphaState *env)
5594
abi_ulong frame_addr = env->ir[IR_A0];
5595
struct target_rt_sigframe *frame;
5598
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5601
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5602
sigprocmask(SIG_SETMASK, &set, NULL);
5604
if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5607
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5609
0, env->ir[IR_SP]) == -EFAULT) {
5613
unlock_user_struct(frame, frame_addr, 0);
5614
return env->ir[IR_V0];
5618
unlock_user_struct(frame, frame_addr, 0);
5619
force_sig(TARGET_SIGSEGV);
5624
static void setup_frame(int sig, struct target_sigaction *ka,
5625
target_sigset_t *set, CPUArchState *env)
5627
fprintf(stderr, "setup_frame: not implemented\n");
5630
static void setup_rt_frame(int sig, struct target_sigaction *ka,
5631
target_siginfo_t *info,
5632
target_sigset_t *set, CPUArchState *env)
5634
fprintf(stderr, "setup_rt_frame: not implemented\n");
5637
long do_sigreturn(CPUArchState *env)
5639
fprintf(stderr, "do_sigreturn: not implemented\n");
5640
return -TARGET_ENOSYS;
5643
long do_rt_sigreturn(CPUArchState *env)
5645
fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5646
return -TARGET_ENOSYS;
5651
void process_pending_signals(CPUArchState *cpu_env)
5653
CPUState *cpu = ENV_GET_CPU(cpu_env);
5656
sigset_t set, old_set;
5657
target_sigset_t target_old_set;
5658
struct emulated_sigtable *k;
5659
struct target_sigaction *sa;
5661
TaskState *ts = cpu_env->opaque;
5663
if (!ts->signal_pending)
5666
/* FIXME: This is not threadsafe. */
5668
for(sig = 1; sig <= TARGET_NSIG; sig++) {
5673
/* if no signal is pending, just return */
5674
ts->signal_pending = 0;
5679
fprintf(stderr, "qemu: process signal %d\n", sig);
5681
/* dequeue signal */
5687
sig = gdb_handlesig(cpu, sig);
5690
handler = TARGET_SIG_IGN;
5692
sa = &sigact_table[sig - 1];
5693
handler = sa->_sa_handler;
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) {
5706
} else if (handler == TARGET_SIG_IGN) {
5708
} else if (handler == TARGET_SIG_ERR) {
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));
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);
5724
/* if the CPU is in VM86 mode, we restore the 32 bit values */
5725
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
5727
CPUX86State *env = cpu_env;
5728
if (env->eflags & VM_MASK)
5729
save_v86_state(env);
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);
5737
if (sa->sa_flags & TARGET_SA_SIGINFO)
5738
setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5740
setup_frame(sig, sa, &target_old_set, cpu_env);
5742
if (sa->sa_flags & TARGET_SA_RESETHAND)
5743
sa->_sa_handler = TARGET_SIG_DFL;
5746
free_sigqueue(cpu_env, q);