ARM: linux-user: Restore VFP state from ucontext on sigreturn
[qemu.git] / linux-user / signal.c
blob63d893b876f5dee8e5ba0cba139424f41affa218
1 /*
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/>.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/ucontext.h>
28 #include <sys/resource.h>
30 #include "qemu.h"
31 #include "qemu-common.h"
32 #include "target_signal.h"
34 //#define DEBUG_SIGNAL
36 static struct target_sigaltstack target_sigaltstack_used = {
37 .ss_sp = 0,
38 .ss_size = 0,
39 .ss_flags = TARGET_SS_DISABLE,
42 static struct target_sigaction sigact_table[TARGET_NSIG];
44 static void host_signal_handler(int host_signum, siginfo_t *info,
45 void *puc);
47 static uint8_t host_to_target_signal_table[_NSIG] = {
48 [SIGHUP] = TARGET_SIGHUP,
49 [SIGINT] = TARGET_SIGINT,
50 [SIGQUIT] = TARGET_SIGQUIT,
51 [SIGILL] = TARGET_SIGILL,
52 [SIGTRAP] = TARGET_SIGTRAP,
53 [SIGABRT] = TARGET_SIGABRT,
54 /* [SIGIOT] = TARGET_SIGIOT,*/
55 [SIGBUS] = TARGET_SIGBUS,
56 [SIGFPE] = TARGET_SIGFPE,
57 [SIGKILL] = TARGET_SIGKILL,
58 [SIGUSR1] = TARGET_SIGUSR1,
59 [SIGSEGV] = TARGET_SIGSEGV,
60 [SIGUSR2] = TARGET_SIGUSR2,
61 [SIGPIPE] = TARGET_SIGPIPE,
62 [SIGALRM] = TARGET_SIGALRM,
63 [SIGTERM] = TARGET_SIGTERM,
64 #ifdef SIGSTKFLT
65 [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 #endif
67 [SIGCHLD] = TARGET_SIGCHLD,
68 [SIGCONT] = TARGET_SIGCONT,
69 [SIGSTOP] = TARGET_SIGSTOP,
70 [SIGTSTP] = TARGET_SIGTSTP,
71 [SIGTTIN] = TARGET_SIGTTIN,
72 [SIGTTOU] = TARGET_SIGTTOU,
73 [SIGURG] = TARGET_SIGURG,
74 [SIGXCPU] = TARGET_SIGXCPU,
75 [SIGXFSZ] = TARGET_SIGXFSZ,
76 [SIGVTALRM] = TARGET_SIGVTALRM,
77 [SIGPROF] = TARGET_SIGPROF,
78 [SIGWINCH] = TARGET_SIGWINCH,
79 [SIGIO] = TARGET_SIGIO,
80 [SIGPWR] = TARGET_SIGPWR,
81 [SIGSYS] = TARGET_SIGSYS,
82 /* next signals stay the same */
83 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
85 To fix this properly we need to do manual signal delivery multiplexed
86 over a single host signal. */
87 [__SIGRTMIN] = __SIGRTMAX,
88 [__SIGRTMAX] = __SIGRTMIN,
90 static uint8_t target_to_host_signal_table[_NSIG];
92 static inline int on_sig_stack(unsigned long sp)
94 return (sp - target_sigaltstack_used.ss_sp
95 < target_sigaltstack_used.ss_size);
98 static inline int sas_ss_flags(unsigned long sp)
100 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
101 : on_sig_stack(sp) ? SS_ONSTACK : 0);
104 int host_to_target_signal(int sig)
106 if (sig >= _NSIG)
107 return sig;
108 return host_to_target_signal_table[sig];
111 int target_to_host_signal(int sig)
113 if (sig >= _NSIG)
114 return sig;
115 return target_to_host_signal_table[sig];
118 static inline void target_sigemptyset(target_sigset_t *set)
120 memset(set, 0, sizeof(*set));
123 static inline void target_sigaddset(target_sigset_t *set, int signum)
125 signum--;
126 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
127 set->sig[signum / TARGET_NSIG_BPW] |= mask;
130 static inline int target_sigismember(const target_sigset_t *set, int signum)
132 signum--;
133 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
134 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
137 static void host_to_target_sigset_internal(target_sigset_t *d,
138 const sigset_t *s)
140 int i;
141 target_sigemptyset(d);
142 for (i = 1; i <= TARGET_NSIG; i++) {
143 if (sigismember(s, i)) {
144 target_sigaddset(d, host_to_target_signal(i));
149 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
151 target_sigset_t d1;
152 int i;
154 host_to_target_sigset_internal(&d1, s);
155 for(i = 0;i < TARGET_NSIG_WORDS; i++)
156 d->sig[i] = tswapl(d1.sig[i]);
159 static void target_to_host_sigset_internal(sigset_t *d,
160 const target_sigset_t *s)
162 int i;
163 sigemptyset(d);
164 for (i = 1; i <= TARGET_NSIG; i++) {
165 if (target_sigismember(s, i)) {
166 sigaddset(d, target_to_host_signal(i));
171 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
173 target_sigset_t s1;
174 int i;
176 for(i = 0;i < TARGET_NSIG_WORDS; i++)
177 s1.sig[i] = tswapl(s->sig[i]);
178 target_to_host_sigset_internal(d, &s1);
181 void host_to_target_old_sigset(abi_ulong *old_sigset,
182 const sigset_t *sigset)
184 target_sigset_t d;
185 host_to_target_sigset(&d, sigset);
186 *old_sigset = d.sig[0];
189 void target_to_host_old_sigset(sigset_t *sigset,
190 const abi_ulong *old_sigset)
192 target_sigset_t d;
193 int i;
195 d.sig[0] = *old_sigset;
196 for(i = 1;i < TARGET_NSIG_WORDS; i++)
197 d.sig[i] = 0;
198 target_to_host_sigset(sigset, &d);
201 /* siginfo conversion */
203 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
204 const siginfo_t *info)
206 int sig;
207 sig = host_to_target_signal(info->si_signo);
208 tinfo->si_signo = sig;
209 tinfo->si_errno = 0;
210 tinfo->si_code = info->si_code;
211 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
212 sig == SIGBUS || sig == SIGTRAP) {
213 /* should never come here, but who knows. The information for
214 the target is irrelevant */
215 tinfo->_sifields._sigfault._addr = 0;
216 } else if (sig == SIGIO) {
217 tinfo->_sifields._sigpoll._fd = info->si_fd;
218 } else if (sig >= TARGET_SIGRTMIN) {
219 tinfo->_sifields._rt._pid = info->si_pid;
220 tinfo->_sifields._rt._uid = info->si_uid;
221 /* XXX: potential problem if 64 bit */
222 tinfo->_sifields._rt._sigval.sival_ptr =
223 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
227 static void tswap_siginfo(target_siginfo_t *tinfo,
228 const target_siginfo_t *info)
230 int sig;
231 sig = info->si_signo;
232 tinfo->si_signo = tswap32(sig);
233 tinfo->si_errno = tswap32(info->si_errno);
234 tinfo->si_code = tswap32(info->si_code);
235 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
236 sig == SIGBUS || sig == SIGTRAP) {
237 tinfo->_sifields._sigfault._addr =
238 tswapl(info->_sifields._sigfault._addr);
239 } else if (sig == SIGIO) {
240 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
241 } else if (sig >= TARGET_SIGRTMIN) {
242 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
243 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
244 tinfo->_sifields._rt._sigval.sival_ptr =
245 tswapl(info->_sifields._rt._sigval.sival_ptr);
250 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
252 host_to_target_siginfo_noswap(tinfo, info);
253 tswap_siginfo(tinfo, tinfo);
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
258 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
260 info->si_signo = tswap32(tinfo->si_signo);
261 info->si_errno = tswap32(tinfo->si_errno);
262 info->si_code = tswap32(tinfo->si_code);
263 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
264 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
265 info->si_value.sival_ptr =
266 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
269 static int fatal_signal (int sig)
271 switch (sig) {
272 case TARGET_SIGCHLD:
273 case TARGET_SIGURG:
274 case TARGET_SIGWINCH:
275 /* Ignored by default. */
276 return 0;
277 case TARGET_SIGCONT:
278 case TARGET_SIGSTOP:
279 case TARGET_SIGTSTP:
280 case TARGET_SIGTTIN:
281 case TARGET_SIGTTOU:
282 /* Job control signals. */
283 return 0;
284 default:
285 return 1;
289 /* returns 1 if given signal should dump core if not handled */
290 static int core_dump_signal(int sig)
292 switch (sig) {
293 case TARGET_SIGABRT:
294 case TARGET_SIGFPE:
295 case TARGET_SIGILL:
296 case TARGET_SIGQUIT:
297 case TARGET_SIGSEGV:
298 case TARGET_SIGTRAP:
299 case TARGET_SIGBUS:
300 return (1);
301 default:
302 return (0);
306 void signal_init(void)
308 struct sigaction act;
309 struct sigaction oact;
310 int i, j;
311 int host_sig;
313 /* generate signal conversion tables */
314 for(i = 1; i < _NSIG; i++) {
315 if (host_to_target_signal_table[i] == 0)
316 host_to_target_signal_table[i] = i;
318 for(i = 1; i < _NSIG; i++) {
319 j = host_to_target_signal_table[i];
320 target_to_host_signal_table[j] = i;
323 /* set all host signal handlers. ALL signals are blocked during
324 the handlers to serialize them. */
325 memset(sigact_table, 0, sizeof(sigact_table));
327 sigfillset(&act.sa_mask);
328 act.sa_flags = SA_SIGINFO;
329 act.sa_sigaction = host_signal_handler;
330 for(i = 1; i <= TARGET_NSIG; i++) {
331 host_sig = target_to_host_signal(i);
332 sigaction(host_sig, NULL, &oact);
333 if (oact.sa_sigaction == (void *)SIG_IGN) {
334 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
335 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
336 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
338 /* If there's already a handler installed then something has
339 gone horribly wrong, so don't even try to handle that case. */
340 /* Install some handlers for our own use. We need at least
341 SIGSEGV and SIGBUS, to detect exceptions. We can not just
342 trap all signals because it affects syscall interrupt
343 behavior. But do trap all default-fatal signals. */
344 if (fatal_signal (i))
345 sigaction(host_sig, &act, NULL);
349 /* signal queue handling */
351 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
353 TaskState *ts = env->opaque;
354 struct sigqueue *q = ts->first_free;
355 if (!q)
356 return NULL;
357 ts->first_free = q->next;
358 return q;
361 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
363 TaskState *ts = env->opaque;
364 q->next = ts->first_free;
365 ts->first_free = q;
368 /* abort execution with signal */
369 static void QEMU_NORETURN force_sig(int target_sig)
371 TaskState *ts = (TaskState *)thread_env->opaque;
372 int host_sig, core_dumped = 0;
373 struct sigaction act;
374 host_sig = target_to_host_signal(target_sig);
375 gdb_signalled(thread_env, target_sig);
377 /* dump core if supported by target binary format */
378 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
379 stop_all_tasks();
380 core_dumped =
381 ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
383 if (core_dumped) {
384 /* we already dumped the core of target process, we don't want
385 * a coredump of qemu itself */
386 struct rlimit nodump;
387 getrlimit(RLIMIT_CORE, &nodump);
388 nodump.rlim_cur=0;
389 setrlimit(RLIMIT_CORE, &nodump);
390 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
391 target_sig, strsignal(host_sig), "core dumped" );
394 /* The proper exit code for dieing from an uncaught signal is
395 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
396 * a negative value. To get the proper exit code we need to
397 * actually die from an uncaught signal. Here the default signal
398 * handler is installed, we send ourself a signal and we wait for
399 * it to arrive. */
400 sigfillset(&act.sa_mask);
401 act.sa_handler = SIG_DFL;
402 sigaction(host_sig, &act, NULL);
404 /* For some reason raise(host_sig) doesn't send the signal when
405 * statically linked on x86-64. */
406 kill(getpid(), host_sig);
408 /* Make sure the signal isn't masked (just reuse the mask inside
409 of act) */
410 sigdelset(&act.sa_mask, host_sig);
411 sigsuspend(&act.sa_mask);
413 /* unreachable */
414 abort();
417 /* queue a signal so that it will be send to the virtual CPU as soon
418 as possible */
419 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
421 TaskState *ts = env->opaque;
422 struct emulated_sigtable *k;
423 struct sigqueue *q, **pq;
424 abi_ulong handler;
425 int queue;
427 #if defined(DEBUG_SIGNAL)
428 fprintf(stderr, "queue_signal: sig=%d\n",
429 sig);
430 #endif
431 k = &ts->sigtab[sig - 1];
432 queue = gdb_queuesig ();
433 handler = sigact_table[sig - 1]._sa_handler;
434 if (!queue && handler == TARGET_SIG_DFL) {
435 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
436 kill(getpid(),SIGSTOP);
437 return 0;
438 } else
439 /* default handler : ignore some signal. The other are fatal */
440 if (sig != TARGET_SIGCHLD &&
441 sig != TARGET_SIGURG &&
442 sig != TARGET_SIGWINCH &&
443 sig != TARGET_SIGCONT) {
444 force_sig(sig);
445 } else {
446 return 0; /* indicate ignored */
448 } else if (!queue && handler == TARGET_SIG_IGN) {
449 /* ignore signal */
450 return 0;
451 } else if (!queue && handler == TARGET_SIG_ERR) {
452 force_sig(sig);
453 } else {
454 pq = &k->first;
455 if (sig < TARGET_SIGRTMIN) {
456 /* if non real time signal, we queue exactly one signal */
457 if (!k->pending)
458 q = &k->info;
459 else
460 return 0;
461 } else {
462 if (!k->pending) {
463 /* first signal */
464 q = &k->info;
465 } else {
466 q = alloc_sigqueue(env);
467 if (!q)
468 return -EAGAIN;
469 while (*pq != NULL)
470 pq = &(*pq)->next;
473 *pq = q;
474 q->info = *info;
475 q->next = NULL;
476 k->pending = 1;
477 /* signal that a new signal is pending */
478 ts->signal_pending = 1;
479 return 1; /* indicates that the signal was queued */
483 static void host_signal_handler(int host_signum, siginfo_t *info,
484 void *puc)
486 int sig;
487 target_siginfo_t tinfo;
489 /* the CPU emulator uses some host signals to detect exceptions,
490 we forward to it some signals */
491 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
492 && info->si_code > 0) {
493 if (cpu_signal_handler(host_signum, info, puc))
494 return;
497 /* get target signal number */
498 sig = host_to_target_signal(host_signum);
499 if (sig < 1 || sig > TARGET_NSIG)
500 return;
501 #if defined(DEBUG_SIGNAL)
502 fprintf(stderr, "qemu: got signal %d\n", sig);
503 #endif
504 host_to_target_siginfo_noswap(&tinfo, info);
505 if (queue_signal(thread_env, sig, &tinfo) == 1) {
506 /* interrupt the virtual CPU as soon as possible */
507 cpu_exit(thread_env);
511 /* do_sigaltstack() returns target values and errnos. */
512 /* compare linux/kernel/signal.c:do_sigaltstack() */
513 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
515 int ret;
516 struct target_sigaltstack oss;
518 /* XXX: test errors */
519 if(uoss_addr)
521 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
522 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
523 __put_user(sas_ss_flags(sp), &oss.ss_flags);
526 if(uss_addr)
528 struct target_sigaltstack *uss;
529 struct target_sigaltstack ss;
531 ret = -TARGET_EFAULT;
532 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
533 || __get_user(ss.ss_sp, &uss->ss_sp)
534 || __get_user(ss.ss_size, &uss->ss_size)
535 || __get_user(ss.ss_flags, &uss->ss_flags))
536 goto out;
537 unlock_user_struct(uss, uss_addr, 0);
539 ret = -TARGET_EPERM;
540 if (on_sig_stack(sp))
541 goto out;
543 ret = -TARGET_EINVAL;
544 if (ss.ss_flags != TARGET_SS_DISABLE
545 && ss.ss_flags != TARGET_SS_ONSTACK
546 && ss.ss_flags != 0)
547 goto out;
549 if (ss.ss_flags == TARGET_SS_DISABLE) {
550 ss.ss_size = 0;
551 ss.ss_sp = 0;
552 } else {
553 ret = -TARGET_ENOMEM;
554 if (ss.ss_size < MINSIGSTKSZ)
555 goto out;
558 target_sigaltstack_used.ss_sp = ss.ss_sp;
559 target_sigaltstack_used.ss_size = ss.ss_size;
562 if (uoss_addr) {
563 ret = -TARGET_EFAULT;
564 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
565 goto out;
568 ret = 0;
569 out:
570 return ret;
573 /* do_sigaction() return host values and errnos */
574 int do_sigaction(int sig, const struct target_sigaction *act,
575 struct target_sigaction *oact)
577 struct target_sigaction *k;
578 struct sigaction act1;
579 int host_sig;
580 int ret = 0;
582 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
583 return -EINVAL;
584 k = &sigact_table[sig - 1];
585 #if defined(DEBUG_SIGNAL)
586 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
587 sig, act, oact);
588 #endif
589 if (oact) {
590 oact->_sa_handler = tswapl(k->_sa_handler);
591 oact->sa_flags = tswapl(k->sa_flags);
592 #if !defined(TARGET_MIPS)
593 oact->sa_restorer = tswapl(k->sa_restorer);
594 #endif
595 oact->sa_mask = k->sa_mask;
597 if (act) {
598 /* FIXME: This is not threadsafe. */
599 k->_sa_handler = tswapl(act->_sa_handler);
600 k->sa_flags = tswapl(act->sa_flags);
601 #if !defined(TARGET_MIPS)
602 k->sa_restorer = tswapl(act->sa_restorer);
603 #endif
604 k->sa_mask = act->sa_mask;
606 /* we update the host linux signal state */
607 host_sig = target_to_host_signal(sig);
608 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
609 sigfillset(&act1.sa_mask);
610 act1.sa_flags = SA_SIGINFO;
611 if (k->sa_flags & TARGET_SA_RESTART)
612 act1.sa_flags |= SA_RESTART;
613 /* NOTE: it is important to update the host kernel signal
614 ignore state to avoid getting unexpected interrupted
615 syscalls */
616 if (k->_sa_handler == TARGET_SIG_IGN) {
617 act1.sa_sigaction = (void *)SIG_IGN;
618 } else if (k->_sa_handler == TARGET_SIG_DFL) {
619 if (fatal_signal (sig))
620 act1.sa_sigaction = host_signal_handler;
621 else
622 act1.sa_sigaction = (void *)SIG_DFL;
623 } else {
624 act1.sa_sigaction = host_signal_handler;
626 ret = sigaction(host_sig, &act1, NULL);
629 return ret;
632 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
633 const target_siginfo_t *info)
635 tswap_siginfo(tinfo, info);
636 return 0;
639 static inline int current_exec_domain_sig(int sig)
641 return /* current->exec_domain && current->exec_domain->signal_invmap
642 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
645 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
647 /* from the Linux kernel */
649 struct target_fpreg {
650 uint16_t significand[4];
651 uint16_t exponent;
654 struct target_fpxreg {
655 uint16_t significand[4];
656 uint16_t exponent;
657 uint16_t padding[3];
660 struct target_xmmreg {
661 abi_ulong element[4];
664 struct target_fpstate {
665 /* Regular FPU environment */
666 abi_ulong cw;
667 abi_ulong sw;
668 abi_ulong tag;
669 abi_ulong ipoff;
670 abi_ulong cssel;
671 abi_ulong dataoff;
672 abi_ulong datasel;
673 struct target_fpreg _st[8];
674 uint16_t status;
675 uint16_t magic; /* 0xffff = regular FPU data only */
677 /* FXSR FPU environment */
678 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
679 abi_ulong mxcsr;
680 abi_ulong reserved;
681 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
682 struct target_xmmreg _xmm[8];
683 abi_ulong padding[56];
686 #define X86_FXSR_MAGIC 0x0000
688 struct target_sigcontext {
689 uint16_t gs, __gsh;
690 uint16_t fs, __fsh;
691 uint16_t es, __esh;
692 uint16_t ds, __dsh;
693 abi_ulong edi;
694 abi_ulong esi;
695 abi_ulong ebp;
696 abi_ulong esp;
697 abi_ulong ebx;
698 abi_ulong edx;
699 abi_ulong ecx;
700 abi_ulong eax;
701 abi_ulong trapno;
702 abi_ulong err;
703 abi_ulong eip;
704 uint16_t cs, __csh;
705 abi_ulong eflags;
706 abi_ulong esp_at_signal;
707 uint16_t ss, __ssh;
708 abi_ulong fpstate; /* pointer */
709 abi_ulong oldmask;
710 abi_ulong cr2;
713 struct target_ucontext {
714 abi_ulong tuc_flags;
715 abi_ulong tuc_link;
716 target_stack_t tuc_stack;
717 struct target_sigcontext tuc_mcontext;
718 target_sigset_t tuc_sigmask; /* mask last for extensibility */
721 struct sigframe
723 abi_ulong pretcode;
724 int sig;
725 struct target_sigcontext sc;
726 struct target_fpstate fpstate;
727 abi_ulong extramask[TARGET_NSIG_WORDS-1];
728 char retcode[8];
731 struct rt_sigframe
733 abi_ulong pretcode;
734 int sig;
735 abi_ulong pinfo;
736 abi_ulong puc;
737 struct target_siginfo info;
738 struct target_ucontext uc;
739 struct target_fpstate fpstate;
740 char retcode[8];
744 * Set up a signal frame.
747 /* XXX: save x87 state */
748 static int
749 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
750 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
752 int err = 0;
753 uint16_t magic;
755 /* already locked in setup_frame() */
756 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
757 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
758 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
759 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
760 err |= __put_user(env->regs[R_EDI], &sc->edi);
761 err |= __put_user(env->regs[R_ESI], &sc->esi);
762 err |= __put_user(env->regs[R_EBP], &sc->ebp);
763 err |= __put_user(env->regs[R_ESP], &sc->esp);
764 err |= __put_user(env->regs[R_EBX], &sc->ebx);
765 err |= __put_user(env->regs[R_EDX], &sc->edx);
766 err |= __put_user(env->regs[R_ECX], &sc->ecx);
767 err |= __put_user(env->regs[R_EAX], &sc->eax);
768 err |= __put_user(env->exception_index, &sc->trapno);
769 err |= __put_user(env->error_code, &sc->err);
770 err |= __put_user(env->eip, &sc->eip);
771 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
772 err |= __put_user(env->eflags, &sc->eflags);
773 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
774 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
776 cpu_x86_fsave(env, fpstate_addr, 1);
777 fpstate->status = fpstate->sw;
778 magic = 0xffff;
779 err |= __put_user(magic, &fpstate->magic);
780 err |= __put_user(fpstate_addr, &sc->fpstate);
782 /* non-iBCS2 extensions.. */
783 err |= __put_user(mask, &sc->oldmask);
784 err |= __put_user(env->cr[2], &sc->cr2);
785 return err;
789 * Determine which stack to use..
792 static inline abi_ulong
793 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
795 unsigned long esp;
797 /* Default to using normal stack */
798 esp = env->regs[R_ESP];
799 /* This is the X/Open sanctioned signal stack switching. */
800 if (ka->sa_flags & TARGET_SA_ONSTACK) {
801 if (sas_ss_flags(esp) == 0)
802 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
805 /* This is the legacy signal stack switching. */
806 else
807 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
808 !(ka->sa_flags & TARGET_SA_RESTORER) &&
809 ka->sa_restorer) {
810 esp = (unsigned long) ka->sa_restorer;
812 return (esp - frame_size) & -8ul;
815 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
816 static void setup_frame(int sig, struct target_sigaction *ka,
817 target_sigset_t *set, CPUX86State *env)
819 abi_ulong frame_addr;
820 struct sigframe *frame;
821 int i, err = 0;
823 frame_addr = get_sigframe(ka, env, sizeof(*frame));
825 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
826 goto give_sigsegv;
828 err |= __put_user(current_exec_domain_sig(sig),
829 &frame->sig);
830 if (err)
831 goto give_sigsegv;
833 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
834 frame_addr + offsetof(struct sigframe, fpstate));
835 if (err)
836 goto give_sigsegv;
838 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
839 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
840 goto give_sigsegv;
843 /* Set up to return from userspace. If provided, use a stub
844 already in userspace. */
845 if (ka->sa_flags & TARGET_SA_RESTORER) {
846 err |= __put_user(ka->sa_restorer, &frame->pretcode);
847 } else {
848 uint16_t val16;
849 abi_ulong retcode_addr;
850 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
851 err |= __put_user(retcode_addr, &frame->pretcode);
852 /* This is popl %eax ; movl $,%eax ; int $0x80 */
853 val16 = 0xb858;
854 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
855 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
856 val16 = 0x80cd;
857 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
860 if (err)
861 goto give_sigsegv;
863 /* Set up registers for signal handler */
864 env->regs[R_ESP] = frame_addr;
865 env->eip = ka->_sa_handler;
867 cpu_x86_load_seg(env, R_DS, __USER_DS);
868 cpu_x86_load_seg(env, R_ES, __USER_DS);
869 cpu_x86_load_seg(env, R_SS, __USER_DS);
870 cpu_x86_load_seg(env, R_CS, __USER_CS);
871 env->eflags &= ~TF_MASK;
873 unlock_user_struct(frame, frame_addr, 1);
875 return;
877 give_sigsegv:
878 unlock_user_struct(frame, frame_addr, 1);
879 if (sig == TARGET_SIGSEGV)
880 ka->_sa_handler = TARGET_SIG_DFL;
881 force_sig(TARGET_SIGSEGV /* , current */);
884 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
885 static void setup_rt_frame(int sig, struct target_sigaction *ka,
886 target_siginfo_t *info,
887 target_sigset_t *set, CPUX86State *env)
889 abi_ulong frame_addr, addr;
890 struct rt_sigframe *frame;
891 int i, err = 0;
893 frame_addr = get_sigframe(ka, env, sizeof(*frame));
895 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
896 goto give_sigsegv;
898 err |= __put_user(current_exec_domain_sig(sig),
899 &frame->sig);
900 addr = frame_addr + offsetof(struct rt_sigframe, info);
901 err |= __put_user(addr, &frame->pinfo);
902 addr = frame_addr + offsetof(struct rt_sigframe, uc);
903 err |= __put_user(addr, &frame->puc);
904 err |= copy_siginfo_to_user(&frame->info, info);
905 if (err)
906 goto give_sigsegv;
908 /* Create the ucontext. */
909 err |= __put_user(0, &frame->uc.tuc_flags);
910 err |= __put_user(0, &frame->uc.tuc_link);
911 err |= __put_user(target_sigaltstack_used.ss_sp,
912 &frame->uc.tuc_stack.ss_sp);
913 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
914 &frame->uc.tuc_stack.ss_flags);
915 err |= __put_user(target_sigaltstack_used.ss_size,
916 &frame->uc.tuc_stack.ss_size);
917 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
918 env, set->sig[0],
919 frame_addr + offsetof(struct rt_sigframe, fpstate));
920 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
921 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
922 goto give_sigsegv;
925 /* Set up to return from userspace. If provided, use a stub
926 already in userspace. */
927 if (ka->sa_flags & TARGET_SA_RESTORER) {
928 err |= __put_user(ka->sa_restorer, &frame->pretcode);
929 } else {
930 uint16_t val16;
931 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
932 err |= __put_user(addr, &frame->pretcode);
933 /* This is movl $,%eax ; int $0x80 */
934 err |= __put_user(0xb8, (char *)(frame->retcode+0));
935 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
936 val16 = 0x80cd;
937 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
940 if (err)
941 goto give_sigsegv;
943 /* Set up registers for signal handler */
944 env->regs[R_ESP] = frame_addr;
945 env->eip = ka->_sa_handler;
947 cpu_x86_load_seg(env, R_DS, __USER_DS);
948 cpu_x86_load_seg(env, R_ES, __USER_DS);
949 cpu_x86_load_seg(env, R_SS, __USER_DS);
950 cpu_x86_load_seg(env, R_CS, __USER_CS);
951 env->eflags &= ~TF_MASK;
953 unlock_user_struct(frame, frame_addr, 1);
955 return;
957 give_sigsegv:
958 unlock_user_struct(frame, frame_addr, 1);
959 if (sig == TARGET_SIGSEGV)
960 ka->_sa_handler = TARGET_SIG_DFL;
961 force_sig(TARGET_SIGSEGV /* , current */);
964 static int
965 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
967 unsigned int err = 0;
968 abi_ulong fpstate_addr;
969 unsigned int tmpflags;
971 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
972 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
973 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
974 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
976 env->regs[R_EDI] = tswapl(sc->edi);
977 env->regs[R_ESI] = tswapl(sc->esi);
978 env->regs[R_EBP] = tswapl(sc->ebp);
979 env->regs[R_ESP] = tswapl(sc->esp);
980 env->regs[R_EBX] = tswapl(sc->ebx);
981 env->regs[R_EDX] = tswapl(sc->edx);
982 env->regs[R_ECX] = tswapl(sc->ecx);
983 env->eip = tswapl(sc->eip);
985 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
986 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
988 tmpflags = tswapl(sc->eflags);
989 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
990 // regs->orig_eax = -1; /* disable syscall checks */
992 fpstate_addr = tswapl(sc->fpstate);
993 if (fpstate_addr != 0) {
994 if (!access_ok(VERIFY_READ, fpstate_addr,
995 sizeof(struct target_fpstate)))
996 goto badframe;
997 cpu_x86_frstor(env, fpstate_addr, 1);
1000 *peax = tswapl(sc->eax);
1001 return err;
1002 badframe:
1003 return 1;
1006 long do_sigreturn(CPUX86State *env)
1008 struct sigframe *frame;
1009 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1010 target_sigset_t target_set;
1011 sigset_t set;
1012 int eax, i;
1014 #if defined(DEBUG_SIGNAL)
1015 fprintf(stderr, "do_sigreturn\n");
1016 #endif
1017 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1018 goto badframe;
1019 /* set blocked signals */
1020 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1021 goto badframe;
1022 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1023 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1024 goto badframe;
1027 target_to_host_sigset_internal(&set, &target_set);
1028 sigprocmask(SIG_SETMASK, &set, NULL);
1030 /* restore registers */
1031 if (restore_sigcontext(env, &frame->sc, &eax))
1032 goto badframe;
1033 unlock_user_struct(frame, frame_addr, 0);
1034 return eax;
1036 badframe:
1037 unlock_user_struct(frame, frame_addr, 0);
1038 force_sig(TARGET_SIGSEGV);
1039 return 0;
1042 long do_rt_sigreturn(CPUX86State *env)
1044 abi_ulong frame_addr;
1045 struct rt_sigframe *frame;
1046 sigset_t set;
1047 int eax;
1049 frame_addr = env->regs[R_ESP] - 4;
1050 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1051 goto badframe;
1052 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1053 sigprocmask(SIG_SETMASK, &set, NULL);
1055 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1056 goto badframe;
1058 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1059 get_sp_from_cpustate(env)) == -EFAULT)
1060 goto badframe;
1062 unlock_user_struct(frame, frame_addr, 0);
1063 return eax;
1065 badframe:
1066 unlock_user_struct(frame, frame_addr, 0);
1067 force_sig(TARGET_SIGSEGV);
1068 return 0;
1071 #elif defined(TARGET_ARM)
1073 struct target_sigcontext {
1074 abi_ulong trap_no;
1075 abi_ulong error_code;
1076 abi_ulong oldmask;
1077 abi_ulong arm_r0;
1078 abi_ulong arm_r1;
1079 abi_ulong arm_r2;
1080 abi_ulong arm_r3;
1081 abi_ulong arm_r4;
1082 abi_ulong arm_r5;
1083 abi_ulong arm_r6;
1084 abi_ulong arm_r7;
1085 abi_ulong arm_r8;
1086 abi_ulong arm_r9;
1087 abi_ulong arm_r10;
1088 abi_ulong arm_fp;
1089 abi_ulong arm_ip;
1090 abi_ulong arm_sp;
1091 abi_ulong arm_lr;
1092 abi_ulong arm_pc;
1093 abi_ulong arm_cpsr;
1094 abi_ulong fault_address;
1097 struct target_ucontext_v1 {
1098 abi_ulong tuc_flags;
1099 abi_ulong tuc_link;
1100 target_stack_t tuc_stack;
1101 struct target_sigcontext tuc_mcontext;
1102 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1105 struct target_ucontext_v2 {
1106 abi_ulong tuc_flags;
1107 abi_ulong tuc_link;
1108 target_stack_t tuc_stack;
1109 struct target_sigcontext tuc_mcontext;
1110 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1111 char __unused[128 - sizeof(target_sigset_t)];
1112 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1115 struct target_user_vfp {
1116 uint64_t fpregs[32];
1117 abi_ulong fpscr;
1120 struct target_user_vfp_exc {
1121 abi_ulong fpexc;
1122 abi_ulong fpinst;
1123 abi_ulong fpinst2;
1126 struct target_vfp_sigframe {
1127 abi_ulong magic;
1128 abi_ulong size;
1129 struct target_user_vfp ufp;
1130 struct target_user_vfp_exc ufp_exc;
1131 } __attribute__((__aligned__(8)));
1133 #define TARGET_VFP_MAGIC 0x56465001
1135 struct sigframe_v1
1137 struct target_sigcontext sc;
1138 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1139 abi_ulong retcode;
1142 struct sigframe_v2
1144 struct target_ucontext_v2 uc;
1145 abi_ulong retcode;
1148 struct rt_sigframe_v1
1150 abi_ulong pinfo;
1151 abi_ulong puc;
1152 struct target_siginfo info;
1153 struct target_ucontext_v1 uc;
1154 abi_ulong retcode;
1157 struct rt_sigframe_v2
1159 struct target_siginfo info;
1160 struct target_ucontext_v2 uc;
1161 abi_ulong retcode;
1164 #define TARGET_CONFIG_CPU_32 1
1167 * For ARM syscalls, we encode the syscall number into the instruction.
1169 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1170 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1173 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1174 * need two 16-bit instructions.
1176 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1177 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1179 static const abi_ulong retcodes[4] = {
1180 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1181 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1185 #define __get_user_error(x,p,e) __get_user(x, p)
1187 static inline int valid_user_regs(CPUState *regs)
1189 return 1;
1192 static void
1193 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1194 CPUState *env, abi_ulong mask)
1196 __put_user(env->regs[0], &sc->arm_r0);
1197 __put_user(env->regs[1], &sc->arm_r1);
1198 __put_user(env->regs[2], &sc->arm_r2);
1199 __put_user(env->regs[3], &sc->arm_r3);
1200 __put_user(env->regs[4], &sc->arm_r4);
1201 __put_user(env->regs[5], &sc->arm_r5);
1202 __put_user(env->regs[6], &sc->arm_r6);
1203 __put_user(env->regs[7], &sc->arm_r7);
1204 __put_user(env->regs[8], &sc->arm_r8);
1205 __put_user(env->regs[9], &sc->arm_r9);
1206 __put_user(env->regs[10], &sc->arm_r10);
1207 __put_user(env->regs[11], &sc->arm_fp);
1208 __put_user(env->regs[12], &sc->arm_ip);
1209 __put_user(env->regs[13], &sc->arm_sp);
1210 __put_user(env->regs[14], &sc->arm_lr);
1211 __put_user(env->regs[15], &sc->arm_pc);
1212 #ifdef TARGET_CONFIG_CPU_32
1213 __put_user(cpsr_read(env), &sc->arm_cpsr);
1214 #endif
1216 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1217 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1218 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1219 __put_user(mask, &sc->oldmask);
1222 static inline abi_ulong
1223 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1225 unsigned long sp = regs->regs[13];
1228 * This is the X/Open sanctioned signal stack switching.
1230 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1231 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1233 * ATPCS B01 mandates 8-byte alignment
1235 return (sp - framesize) & ~7;
1238 static int
1239 setup_return(CPUState *env, struct target_sigaction *ka,
1240 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1242 abi_ulong handler = ka->_sa_handler;
1243 abi_ulong retcode;
1244 int thumb = handler & 1;
1246 if (ka->sa_flags & TARGET_SA_RESTORER) {
1247 retcode = ka->sa_restorer;
1248 } else {
1249 unsigned int idx = thumb;
1251 if (ka->sa_flags & TARGET_SA_SIGINFO)
1252 idx += 2;
1254 if (__put_user(retcodes[idx], rc))
1255 return 1;
1256 #if 0
1257 flush_icache_range((abi_ulong)rc,
1258 (abi_ulong)(rc + 1));
1259 #endif
1260 retcode = rc_addr + thumb;
1263 env->regs[0] = usig;
1264 env->regs[13] = frame_addr;
1265 env->regs[14] = retcode;
1266 env->regs[15] = handler & (thumb ? ~1 : ~3);
1267 env->thumb = thumb;
1269 #if 0
1270 #ifdef TARGET_CONFIG_CPU_32
1271 env->cpsr = cpsr;
1272 #endif
1273 #endif
1275 return 0;
1278 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env)
1280 int i;
1281 struct target_vfp_sigframe *vfpframe;
1282 vfpframe = (struct target_vfp_sigframe *)regspace;
1283 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1284 __put_user(sizeof(*vfpframe), &vfpframe->size);
1285 for (i = 0; i < 32; i++) {
1286 __put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1288 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1289 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1290 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1291 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1292 return (abi_ulong*)(vfpframe+1);
1295 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1296 target_sigset_t *set, CPUState *env)
1298 struct target_sigaltstack stack;
1299 int i;
1300 abi_ulong *regspace;
1302 /* Clear all the bits of the ucontext we don't use. */
1303 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1305 memset(&stack, 0, sizeof(stack));
1306 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1307 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1308 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1309 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1311 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1312 /* Save coprocessor signal frame. */
1313 regspace = uc->tuc_regspace;
1314 if (arm_feature(env, ARM_FEATURE_VFP)) {
1315 regspace = setup_sigframe_v2_vfp(regspace, env);
1317 /* Write terminating magic word */
1318 __put_user(0, regspace);
1320 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1321 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1325 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1326 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1327 target_sigset_t *set, CPUState *regs)
1329 struct sigframe_v1 *frame;
1330 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1331 int i;
1333 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1334 return;
1336 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1338 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1339 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1340 goto end;
1343 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1344 frame_addr + offsetof(struct sigframe_v1, retcode));
1346 end:
1347 unlock_user_struct(frame, frame_addr, 1);
1350 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1351 target_sigset_t *set, CPUState *regs)
1353 struct sigframe_v2 *frame;
1354 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1356 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1357 return;
1359 setup_sigframe_v2(&frame->uc, set, regs);
1361 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1362 frame_addr + offsetof(struct sigframe_v2, retcode));
1364 unlock_user_struct(frame, frame_addr, 1);
1367 static void setup_frame(int usig, struct target_sigaction *ka,
1368 target_sigset_t *set, CPUState *regs)
1370 if (get_osversion() >= 0x020612) {
1371 setup_frame_v2(usig, ka, set, regs);
1372 } else {
1373 setup_frame_v1(usig, ka, set, regs);
1377 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1378 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1379 target_siginfo_t *info,
1380 target_sigset_t *set, CPUState *env)
1382 struct rt_sigframe_v1 *frame;
1383 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1384 struct target_sigaltstack stack;
1385 int i;
1386 abi_ulong info_addr, uc_addr;
1388 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1389 return /* 1 */;
1391 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1392 __put_user(info_addr, &frame->pinfo);
1393 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1394 __put_user(uc_addr, &frame->puc);
1395 copy_siginfo_to_user(&frame->info, info);
1397 /* Clear all the bits of the ucontext we don't use. */
1398 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1400 memset(&stack, 0, sizeof(stack));
1401 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1402 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1403 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1404 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1406 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1407 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1408 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1409 goto end;
1412 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1413 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1415 env->regs[1] = info_addr;
1416 env->regs[2] = uc_addr;
1418 end:
1419 unlock_user_struct(frame, frame_addr, 1);
1422 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1423 target_siginfo_t *info,
1424 target_sigset_t *set, CPUState *env)
1426 struct rt_sigframe_v2 *frame;
1427 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1428 abi_ulong info_addr, uc_addr;
1430 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1431 return /* 1 */;
1433 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1434 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1435 copy_siginfo_to_user(&frame->info, info);
1437 setup_sigframe_v2(&frame->uc, set, env);
1439 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1440 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1442 env->regs[1] = info_addr;
1443 env->regs[2] = uc_addr;
1445 unlock_user_struct(frame, frame_addr, 1);
1448 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1449 target_siginfo_t *info,
1450 target_sigset_t *set, CPUState *env)
1452 if (get_osversion() >= 0x020612) {
1453 setup_rt_frame_v2(usig, ka, info, set, env);
1454 } else {
1455 setup_rt_frame_v1(usig, ka, info, set, env);
1459 static int
1460 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1462 int err = 0;
1463 uint32_t cpsr;
1465 __get_user_error(env->regs[0], &sc->arm_r0, err);
1466 __get_user_error(env->regs[1], &sc->arm_r1, err);
1467 __get_user_error(env->regs[2], &sc->arm_r2, err);
1468 __get_user_error(env->regs[3], &sc->arm_r3, err);
1469 __get_user_error(env->regs[4], &sc->arm_r4, err);
1470 __get_user_error(env->regs[5], &sc->arm_r5, err);
1471 __get_user_error(env->regs[6], &sc->arm_r6, err);
1472 __get_user_error(env->regs[7], &sc->arm_r7, err);
1473 __get_user_error(env->regs[8], &sc->arm_r8, err);
1474 __get_user_error(env->regs[9], &sc->arm_r9, err);
1475 __get_user_error(env->regs[10], &sc->arm_r10, err);
1476 __get_user_error(env->regs[11], &sc->arm_fp, err);
1477 __get_user_error(env->regs[12], &sc->arm_ip, err);
1478 __get_user_error(env->regs[13], &sc->arm_sp, err);
1479 __get_user_error(env->regs[14], &sc->arm_lr, err);
1480 __get_user_error(env->regs[15], &sc->arm_pc, err);
1481 #ifdef TARGET_CONFIG_CPU_32
1482 __get_user_error(cpsr, &sc->arm_cpsr, err);
1483 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1484 #endif
1486 err |= !valid_user_regs(env);
1488 return err;
1491 static long do_sigreturn_v1(CPUState *env)
1493 abi_ulong frame_addr;
1494 struct sigframe_v1 *frame;
1495 target_sigset_t set;
1496 sigset_t host_set;
1497 int i;
1500 * Since we stacked the signal on a 64-bit boundary,
1501 * then 'sp' should be word aligned here. If it's
1502 * not, then the user is trying to mess with us.
1504 if (env->regs[13] & 7)
1505 goto badframe;
1507 frame_addr = env->regs[13];
1508 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1509 goto badframe;
1511 if (__get_user(set.sig[0], &frame->sc.oldmask))
1512 goto badframe;
1513 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1514 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1515 goto badframe;
1518 target_to_host_sigset_internal(&host_set, &set);
1519 sigprocmask(SIG_SETMASK, &host_set, NULL);
1521 if (restore_sigcontext(env, &frame->sc))
1522 goto badframe;
1524 #if 0
1525 /* Send SIGTRAP if we're single-stepping */
1526 if (ptrace_cancel_bpt(current))
1527 send_sig(SIGTRAP, current, 1);
1528 #endif
1529 unlock_user_struct(frame, frame_addr, 0);
1530 return env->regs[0];
1532 badframe:
1533 unlock_user_struct(frame, frame_addr, 0);
1534 force_sig(TARGET_SIGSEGV /* , current */);
1535 return 0;
1538 static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace)
1540 int i;
1541 abi_ulong magic, sz;
1542 uint32_t fpscr, fpexc;
1543 struct target_vfp_sigframe *vfpframe;
1544 vfpframe = (struct target_vfp_sigframe *)regspace;
1546 __get_user(magic, &vfpframe->magic);
1547 __get_user(sz, &vfpframe->size);
1548 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1549 return 0;
1551 for (i = 0; i < 32; i++) {
1552 __get_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1554 __get_user(fpscr, &vfpframe->ufp.fpscr);
1555 vfp_set_fpscr(env, fpscr);
1556 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1557 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1558 * and the exception flag is cleared
1560 fpexc |= (1 << 30);
1561 fpexc &= ~((1 << 31) | (1 << 28));
1562 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1563 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1564 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1565 return (abi_ulong*)(vfpframe + 1);
1568 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1569 struct target_ucontext_v2 *uc)
1571 sigset_t host_set;
1572 abi_ulong *regspace;
1574 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1575 sigprocmask(SIG_SETMASK, &host_set, NULL);
1577 if (restore_sigcontext(env, &uc->tuc_mcontext))
1578 return 1;
1580 /* Restore coprocessor signal frame */
1581 regspace = uc->tuc_regspace;
1582 if (arm_feature(env, ARM_FEATURE_VFP)) {
1583 regspace = restore_sigframe_v2_vfp(env, regspace);
1584 if (!regspace) {
1585 return 1;
1589 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1590 return 1;
1592 #if 0
1593 /* Send SIGTRAP if we're single-stepping */
1594 if (ptrace_cancel_bpt(current))
1595 send_sig(SIGTRAP, current, 1);
1596 #endif
1598 return 0;
1601 static long do_sigreturn_v2(CPUState *env)
1603 abi_ulong frame_addr;
1604 struct sigframe_v2 *frame;
1607 * Since we stacked the signal on a 64-bit boundary,
1608 * then 'sp' should be word aligned here. If it's
1609 * not, then the user is trying to mess with us.
1611 if (env->regs[13] & 7)
1612 goto badframe;
1614 frame_addr = env->regs[13];
1615 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1616 goto badframe;
1618 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1619 goto badframe;
1621 unlock_user_struct(frame, frame_addr, 0);
1622 return env->regs[0];
1624 badframe:
1625 unlock_user_struct(frame, frame_addr, 0);
1626 force_sig(TARGET_SIGSEGV /* , current */);
1627 return 0;
1630 long do_sigreturn(CPUState *env)
1632 if (get_osversion() >= 0x020612) {
1633 return do_sigreturn_v2(env);
1634 } else {
1635 return do_sigreturn_v1(env);
1639 static long do_rt_sigreturn_v1(CPUState *env)
1641 abi_ulong frame_addr;
1642 struct rt_sigframe_v1 *frame;
1643 sigset_t host_set;
1646 * Since we stacked the signal on a 64-bit boundary,
1647 * then 'sp' should be word aligned here. If it's
1648 * not, then the user is trying to mess with us.
1650 if (env->regs[13] & 7)
1651 goto badframe;
1653 frame_addr = env->regs[13];
1654 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1655 goto badframe;
1657 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1658 sigprocmask(SIG_SETMASK, &host_set, NULL);
1660 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1661 goto badframe;
1663 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1664 goto badframe;
1666 #if 0
1667 /* Send SIGTRAP if we're single-stepping */
1668 if (ptrace_cancel_bpt(current))
1669 send_sig(SIGTRAP, current, 1);
1670 #endif
1671 unlock_user_struct(frame, frame_addr, 0);
1672 return env->regs[0];
1674 badframe:
1675 unlock_user_struct(frame, frame_addr, 0);
1676 force_sig(TARGET_SIGSEGV /* , current */);
1677 return 0;
1680 static long do_rt_sigreturn_v2(CPUState *env)
1682 abi_ulong frame_addr;
1683 struct rt_sigframe_v2 *frame;
1686 * Since we stacked the signal on a 64-bit boundary,
1687 * then 'sp' should be word aligned here. If it's
1688 * not, then the user is trying to mess with us.
1690 if (env->regs[13] & 7)
1691 goto badframe;
1693 frame_addr = env->regs[13];
1694 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1695 goto badframe;
1697 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1698 goto badframe;
1700 unlock_user_struct(frame, frame_addr, 0);
1701 return env->regs[0];
1703 badframe:
1704 unlock_user_struct(frame, frame_addr, 0);
1705 force_sig(TARGET_SIGSEGV /* , current */);
1706 return 0;
1709 long do_rt_sigreturn(CPUState *env)
1711 if (get_osversion() >= 0x020612) {
1712 return do_rt_sigreturn_v2(env);
1713 } else {
1714 return do_rt_sigreturn_v1(env);
1718 #elif defined(TARGET_SPARC)
1720 #define __SUNOS_MAXWIN 31
1722 /* This is what SunOS does, so shall I. */
1723 struct target_sigcontext {
1724 abi_ulong sigc_onstack; /* state to restore */
1726 abi_ulong sigc_mask; /* sigmask to restore */
1727 abi_ulong sigc_sp; /* stack pointer */
1728 abi_ulong sigc_pc; /* program counter */
1729 abi_ulong sigc_npc; /* next program counter */
1730 abi_ulong sigc_psr; /* for condition codes etc */
1731 abi_ulong sigc_g1; /* User uses these two registers */
1732 abi_ulong sigc_o0; /* within the trampoline code. */
1734 /* Now comes information regarding the users window set
1735 * at the time of the signal.
1737 abi_ulong sigc_oswins; /* outstanding windows */
1739 /* stack ptrs for each regwin buf */
1740 char *sigc_spbuf[__SUNOS_MAXWIN];
1742 /* Windows to restore after signal */
1743 struct {
1744 abi_ulong locals[8];
1745 abi_ulong ins[8];
1746 } sigc_wbuf[__SUNOS_MAXWIN];
1748 /* A Sparc stack frame */
1749 struct sparc_stackf {
1750 abi_ulong locals[8];
1751 abi_ulong ins[6];
1752 struct sparc_stackf *fp;
1753 abi_ulong callers_pc;
1754 char *structptr;
1755 abi_ulong xargs[6];
1756 abi_ulong xxargs[1];
1759 typedef struct {
1760 struct {
1761 abi_ulong psr;
1762 abi_ulong pc;
1763 abi_ulong npc;
1764 abi_ulong y;
1765 abi_ulong u_regs[16]; /* globals and ins */
1766 } si_regs;
1767 int si_mask;
1768 } __siginfo_t;
1770 typedef struct {
1771 unsigned long si_float_regs [32];
1772 unsigned long si_fsr;
1773 unsigned long si_fpqdepth;
1774 struct {
1775 unsigned long *insn_addr;
1776 unsigned long insn;
1777 } si_fpqueue [16];
1778 } qemu_siginfo_fpu_t;
1781 struct target_signal_frame {
1782 struct sparc_stackf ss;
1783 __siginfo_t info;
1784 abi_ulong fpu_save;
1785 abi_ulong insns[2] __attribute__ ((aligned (8)));
1786 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1787 abi_ulong extra_size; /* Should be 0 */
1788 qemu_siginfo_fpu_t fpu_state;
1790 struct target_rt_signal_frame {
1791 struct sparc_stackf ss;
1792 siginfo_t info;
1793 abi_ulong regs[20];
1794 sigset_t mask;
1795 abi_ulong fpu_save;
1796 unsigned int insns[2];
1797 stack_t stack;
1798 unsigned int extra_size; /* Should be 0 */
1799 qemu_siginfo_fpu_t fpu_state;
1802 #define UREG_O0 16
1803 #define UREG_O6 22
1804 #define UREG_I0 0
1805 #define UREG_I1 1
1806 #define UREG_I2 2
1807 #define UREG_I3 3
1808 #define UREG_I4 4
1809 #define UREG_I5 5
1810 #define UREG_I6 6
1811 #define UREG_I7 7
1812 #define UREG_L0 8
1813 #define UREG_FP UREG_I6
1814 #define UREG_SP UREG_O6
1816 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1817 CPUState *env, unsigned long framesize)
1819 abi_ulong sp;
1821 sp = env->regwptr[UREG_FP];
1823 /* This is the X/Open sanctioned signal stack switching. */
1824 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1825 if (!on_sig_stack(sp)
1826 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1827 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1829 return sp - framesize;
1832 static int
1833 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1835 int err = 0, i;
1837 err |= __put_user(env->psr, &si->si_regs.psr);
1838 err |= __put_user(env->pc, &si->si_regs.pc);
1839 err |= __put_user(env->npc, &si->si_regs.npc);
1840 err |= __put_user(env->y, &si->si_regs.y);
1841 for (i=0; i < 8; i++) {
1842 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1844 for (i=0; i < 8; i++) {
1845 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1847 err |= __put_user(mask, &si->si_mask);
1848 return err;
1851 #if 0
1852 static int
1853 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1854 CPUState *env, unsigned long mask)
1856 int err = 0;
1858 err |= __put_user(mask, &sc->sigc_mask);
1859 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1860 err |= __put_user(env->pc, &sc->sigc_pc);
1861 err |= __put_user(env->npc, &sc->sigc_npc);
1862 err |= __put_user(env->psr, &sc->sigc_psr);
1863 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1864 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1866 return err;
1868 #endif
1869 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1871 static void setup_frame(int sig, struct target_sigaction *ka,
1872 target_sigset_t *set, CPUState *env)
1874 abi_ulong sf_addr;
1875 struct target_signal_frame *sf;
1876 int sigframe_size, err, i;
1878 /* 1. Make sure everything is clean */
1879 //synchronize_user_stack();
1881 sigframe_size = NF_ALIGNEDSZ;
1882 sf_addr = get_sigframe(ka, env, sigframe_size);
1884 sf = lock_user(VERIFY_WRITE, sf_addr,
1885 sizeof(struct target_signal_frame), 0);
1886 if (!sf)
1887 goto sigsegv;
1889 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1890 #if 0
1891 if (invalid_frame_pointer(sf, sigframe_size))
1892 goto sigill_and_return;
1893 #endif
1894 /* 2. Save the current process state */
1895 err = setup___siginfo(&sf->info, env, set->sig[0]);
1896 err |= __put_user(0, &sf->extra_size);
1898 //err |= save_fpu_state(regs, &sf->fpu_state);
1899 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1901 err |= __put_user(set->sig[0], &sf->info.si_mask);
1902 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1903 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1906 for (i = 0; i < 8; i++) {
1907 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1909 for (i = 0; i < 8; i++) {
1910 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1912 if (err)
1913 goto sigsegv;
1915 /* 3. signal handler back-trampoline and parameters */
1916 env->regwptr[UREG_FP] = sf_addr;
1917 env->regwptr[UREG_I0] = sig;
1918 env->regwptr[UREG_I1] = sf_addr +
1919 offsetof(struct target_signal_frame, info);
1920 env->regwptr[UREG_I2] = sf_addr +
1921 offsetof(struct target_signal_frame, info);
1923 /* 4. signal handler */
1924 env->pc = ka->_sa_handler;
1925 env->npc = (env->pc + 4);
1926 /* 5. return to kernel instructions */
1927 if (ka->sa_restorer)
1928 env->regwptr[UREG_I7] = ka->sa_restorer;
1929 else {
1930 uint32_t val32;
1932 env->regwptr[UREG_I7] = sf_addr +
1933 offsetof(struct target_signal_frame, insns) - 2 * 4;
1935 /* mov __NR_sigreturn, %g1 */
1936 val32 = 0x821020d8;
1937 err |= __put_user(val32, &sf->insns[0]);
1939 /* t 0x10 */
1940 val32 = 0x91d02010;
1941 err |= __put_user(val32, &sf->insns[1]);
1942 if (err)
1943 goto sigsegv;
1945 /* Flush instruction space. */
1946 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1947 // tb_flush(env);
1949 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1950 return;
1951 #if 0
1952 sigill_and_return:
1953 force_sig(TARGET_SIGILL);
1954 #endif
1955 sigsegv:
1956 //fprintf(stderr, "force_sig\n");
1957 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1958 force_sig(TARGET_SIGSEGV);
1960 static inline int
1961 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1963 int err;
1964 #if 0
1965 #ifdef CONFIG_SMP
1966 if (current->flags & PF_USEDFPU)
1967 regs->psr &= ~PSR_EF;
1968 #else
1969 if (current == last_task_used_math) {
1970 last_task_used_math = 0;
1971 regs->psr &= ~PSR_EF;
1973 #endif
1974 current->used_math = 1;
1975 current->flags &= ~PF_USEDFPU;
1976 #endif
1977 #if 0
1978 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1979 return -EFAULT;
1980 #endif
1982 #if 0
1983 /* XXX: incorrect */
1984 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1985 (sizeof(unsigned long) * 32));
1986 #endif
1987 err |= __get_user(env->fsr, &fpu->si_fsr);
1988 #if 0
1989 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1990 if (current->thread.fpqdepth != 0)
1991 err |= __copy_from_user(&current->thread.fpqueue[0],
1992 &fpu->si_fpqueue[0],
1993 ((sizeof(unsigned long) +
1994 (sizeof(unsigned long *)))*16));
1995 #endif
1996 return err;
2000 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2001 target_siginfo_t *info,
2002 target_sigset_t *set, CPUState *env)
2004 fprintf(stderr, "setup_rt_frame: not implemented\n");
2007 long do_sigreturn(CPUState *env)
2009 abi_ulong sf_addr;
2010 struct target_signal_frame *sf;
2011 uint32_t up_psr, pc, npc;
2012 target_sigset_t set;
2013 sigset_t host_set;
2014 abi_ulong fpu_save_addr;
2015 int err, i;
2017 sf_addr = env->regwptr[UREG_FP];
2018 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2019 goto segv_and_exit;
2020 #if 0
2021 fprintf(stderr, "sigreturn\n");
2022 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2023 #endif
2024 //cpu_dump_state(env, stderr, fprintf, 0);
2026 /* 1. Make sure we are not getting garbage from the user */
2028 if (sf_addr & 3)
2029 goto segv_and_exit;
2031 err = __get_user(pc, &sf->info.si_regs.pc);
2032 err |= __get_user(npc, &sf->info.si_regs.npc);
2034 if ((pc | npc) & 3)
2035 goto segv_and_exit;
2037 /* 2. Restore the state */
2038 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2040 /* User can only change condition codes and FPU enabling in %psr. */
2041 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2042 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2044 env->pc = pc;
2045 env->npc = npc;
2046 err |= __get_user(env->y, &sf->info.si_regs.y);
2047 for (i=0; i < 8; i++) {
2048 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2050 for (i=0; i < 8; i++) {
2051 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2054 err |= __get_user(fpu_save_addr, &sf->fpu_save);
2056 //if (fpu_save)
2057 // err |= restore_fpu_state(env, fpu_save);
2059 /* This is pretty much atomic, no amount locking would prevent
2060 * the races which exist anyways.
2062 err |= __get_user(set.sig[0], &sf->info.si_mask);
2063 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2064 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2067 target_to_host_sigset_internal(&host_set, &set);
2068 sigprocmask(SIG_SETMASK, &host_set, NULL);
2070 if (err)
2071 goto segv_and_exit;
2072 unlock_user_struct(sf, sf_addr, 0);
2073 return env->regwptr[0];
2075 segv_and_exit:
2076 unlock_user_struct(sf, sf_addr, 0);
2077 force_sig(TARGET_SIGSEGV);
2080 long do_rt_sigreturn(CPUState *env)
2082 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2083 return -TARGET_ENOSYS;
2086 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2087 #define MC_TSTATE 0
2088 #define MC_PC 1
2089 #define MC_NPC 2
2090 #define MC_Y 3
2091 #define MC_G1 4
2092 #define MC_G2 5
2093 #define MC_G3 6
2094 #define MC_G4 7
2095 #define MC_G5 8
2096 #define MC_G6 9
2097 #define MC_G7 10
2098 #define MC_O0 11
2099 #define MC_O1 12
2100 #define MC_O2 13
2101 #define MC_O3 14
2102 #define MC_O4 15
2103 #define MC_O5 16
2104 #define MC_O6 17
2105 #define MC_O7 18
2106 #define MC_NGREG 19
2108 typedef abi_ulong target_mc_greg_t;
2109 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2111 struct target_mc_fq {
2112 abi_ulong *mcfq_addr;
2113 uint32_t mcfq_insn;
2116 struct target_mc_fpu {
2117 union {
2118 uint32_t sregs[32];
2119 uint64_t dregs[32];
2120 //uint128_t qregs[16];
2121 } mcfpu_fregs;
2122 abi_ulong mcfpu_fsr;
2123 abi_ulong mcfpu_fprs;
2124 abi_ulong mcfpu_gsr;
2125 struct target_mc_fq *mcfpu_fq;
2126 unsigned char mcfpu_qcnt;
2127 unsigned char mcfpu_qentsz;
2128 unsigned char mcfpu_enab;
2130 typedef struct target_mc_fpu target_mc_fpu_t;
2132 typedef struct {
2133 target_mc_gregset_t mc_gregs;
2134 target_mc_greg_t mc_fp;
2135 target_mc_greg_t mc_i7;
2136 target_mc_fpu_t mc_fpregs;
2137 } target_mcontext_t;
2139 struct target_ucontext {
2140 struct target_ucontext *tuc_link;
2141 abi_ulong tuc_flags;
2142 target_sigset_t tuc_sigmask;
2143 target_mcontext_t tuc_mcontext;
2146 /* A V9 register window */
2147 struct target_reg_window {
2148 abi_ulong locals[8];
2149 abi_ulong ins[8];
2152 #define TARGET_STACK_BIAS 2047
2154 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2155 void sparc64_set_context(CPUSPARCState *env)
2157 abi_ulong ucp_addr;
2158 struct target_ucontext *ucp;
2159 target_mc_gregset_t *grp;
2160 abi_ulong pc, npc, tstate;
2161 abi_ulong fp, i7, w_addr;
2162 unsigned char fenab;
2163 int err;
2164 unsigned int i;
2166 ucp_addr = env->regwptr[UREG_I0];
2167 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2168 goto do_sigsegv;
2169 grp = &ucp->tuc_mcontext.mc_gregs;
2170 err = __get_user(pc, &((*grp)[MC_PC]));
2171 err |= __get_user(npc, &((*grp)[MC_NPC]));
2172 if (err || ((pc | npc) & 3))
2173 goto do_sigsegv;
2174 if (env->regwptr[UREG_I1]) {
2175 target_sigset_t target_set;
2176 sigset_t set;
2178 if (TARGET_NSIG_WORDS == 1) {
2179 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2180 goto do_sigsegv;
2181 } else {
2182 abi_ulong *src, *dst;
2183 src = ucp->tuc_sigmask.sig;
2184 dst = target_set.sig;
2185 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2186 i++, dst++, src++)
2187 err |= __get_user(*dst, src);
2188 if (err)
2189 goto do_sigsegv;
2191 target_to_host_sigset_internal(&set, &target_set);
2192 sigprocmask(SIG_SETMASK, &set, NULL);
2194 env->pc = pc;
2195 env->npc = npc;
2196 err |= __get_user(env->y, &((*grp)[MC_Y]));
2197 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2198 env->asi = (tstate >> 24) & 0xff;
2199 cpu_put_ccr(env, tstate >> 32);
2200 cpu_put_cwp64(env, tstate & 0x1f);
2201 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2202 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2203 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2204 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2205 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2206 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2207 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2208 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2209 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2210 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2211 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2212 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2213 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2214 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2215 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2217 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2218 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2220 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2221 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2222 abi_ulong) != 0)
2223 goto do_sigsegv;
2224 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2225 abi_ulong) != 0)
2226 goto do_sigsegv;
2227 err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2228 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2230 uint32_t *src, *dst;
2231 src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2232 dst = env->fpr;
2233 /* XXX: check that the CPU storage is the same as user context */
2234 for (i = 0; i < 64; i++, dst++, src++)
2235 err |= __get_user(*dst, src);
2237 err |= __get_user(env->fsr,
2238 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2239 err |= __get_user(env->gsr,
2240 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2241 if (err)
2242 goto do_sigsegv;
2243 unlock_user_struct(ucp, ucp_addr, 0);
2244 return;
2245 do_sigsegv:
2246 unlock_user_struct(ucp, ucp_addr, 0);
2247 force_sig(TARGET_SIGSEGV);
2250 void sparc64_get_context(CPUSPARCState *env)
2252 abi_ulong ucp_addr;
2253 struct target_ucontext *ucp;
2254 target_mc_gregset_t *grp;
2255 target_mcontext_t *mcp;
2256 abi_ulong fp, i7, w_addr;
2257 int err;
2258 unsigned int i;
2259 target_sigset_t target_set;
2260 sigset_t set;
2262 ucp_addr = env->regwptr[UREG_I0];
2263 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2264 goto do_sigsegv;
2266 mcp = &ucp->tuc_mcontext;
2267 grp = &mcp->mc_gregs;
2269 /* Skip over the trap instruction, first. */
2270 env->pc = env->npc;
2271 env->npc += 4;
2273 err = 0;
2275 sigprocmask(0, NULL, &set);
2276 host_to_target_sigset_internal(&target_set, &set);
2277 if (TARGET_NSIG_WORDS == 1) {
2278 err |= __put_user(target_set.sig[0],
2279 (abi_ulong *)&ucp->tuc_sigmask);
2280 } else {
2281 abi_ulong *src, *dst;
2282 src = target_set.sig;
2283 dst = ucp->tuc_sigmask.sig;
2284 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2285 i++, dst++, src++)
2286 err |= __put_user(*src, dst);
2287 if (err)
2288 goto do_sigsegv;
2291 /* XXX: tstate must be saved properly */
2292 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2293 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2294 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2295 err |= __put_user(env->y, &((*grp)[MC_Y]));
2296 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2297 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2298 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2299 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2300 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2301 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2302 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2303 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2304 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2305 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2306 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2307 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2308 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2309 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2310 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2312 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2313 fp = i7 = 0;
2314 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2315 abi_ulong) != 0)
2316 goto do_sigsegv;
2317 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2318 abi_ulong) != 0)
2319 goto do_sigsegv;
2320 err |= __put_user(fp, &(mcp->mc_fp));
2321 err |= __put_user(i7, &(mcp->mc_i7));
2324 uint32_t *src, *dst;
2325 src = env->fpr;
2326 dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2327 /* XXX: check that the CPU storage is the same as user context */
2328 for (i = 0; i < 64; i++, dst++, src++)
2329 err |= __put_user(*src, dst);
2331 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2332 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2333 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2335 if (err)
2336 goto do_sigsegv;
2337 unlock_user_struct(ucp, ucp_addr, 1);
2338 return;
2339 do_sigsegv:
2340 unlock_user_struct(ucp, ucp_addr, 1);
2341 force_sig(TARGET_SIGSEGV);
2343 #endif
2344 #elif defined(TARGET_ABI_MIPSN64)
2346 # warning signal handling not implemented
2348 static void setup_frame(int sig, struct target_sigaction *ka,
2349 target_sigset_t *set, CPUState *env)
2351 fprintf(stderr, "setup_frame: not implemented\n");
2354 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2355 target_siginfo_t *info,
2356 target_sigset_t *set, CPUState *env)
2358 fprintf(stderr, "setup_rt_frame: not implemented\n");
2361 long do_sigreturn(CPUState *env)
2363 fprintf(stderr, "do_sigreturn: not implemented\n");
2364 return -TARGET_ENOSYS;
2367 long do_rt_sigreturn(CPUState *env)
2369 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2370 return -TARGET_ENOSYS;
2373 #elif defined(TARGET_ABI_MIPSN32)
2375 # warning signal handling not implemented
2377 static void setup_frame(int sig, struct target_sigaction *ka,
2378 target_sigset_t *set, CPUState *env)
2380 fprintf(stderr, "setup_frame: not implemented\n");
2383 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2384 target_siginfo_t *info,
2385 target_sigset_t *set, CPUState *env)
2387 fprintf(stderr, "setup_rt_frame: not implemented\n");
2390 long do_sigreturn(CPUState *env)
2392 fprintf(stderr, "do_sigreturn: not implemented\n");
2393 return -TARGET_ENOSYS;
2396 long do_rt_sigreturn(CPUState *env)
2398 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2399 return -TARGET_ENOSYS;
2402 #elif defined(TARGET_ABI_MIPSO32)
2404 struct target_sigcontext {
2405 uint32_t sc_regmask; /* Unused */
2406 uint32_t sc_status;
2407 uint64_t sc_pc;
2408 uint64_t sc_regs[32];
2409 uint64_t sc_fpregs[32];
2410 uint32_t sc_ownedfp; /* Unused */
2411 uint32_t sc_fpc_csr;
2412 uint32_t sc_fpc_eir; /* Unused */
2413 uint32_t sc_used_math;
2414 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2415 uint32_t pad0;
2416 uint64_t sc_mdhi;
2417 uint64_t sc_mdlo;
2418 target_ulong sc_hi1; /* Was sc_cause */
2419 target_ulong sc_lo1; /* Was sc_badvaddr */
2420 target_ulong sc_hi2; /* Was sc_sigset[4] */
2421 target_ulong sc_lo2;
2422 target_ulong sc_hi3;
2423 target_ulong sc_lo3;
2426 struct sigframe {
2427 uint32_t sf_ass[4]; /* argument save space for o32 */
2428 uint32_t sf_code[2]; /* signal trampoline */
2429 struct target_sigcontext sf_sc;
2430 target_sigset_t sf_mask;
2433 struct target_ucontext {
2434 target_ulong tuc_flags;
2435 target_ulong tuc_link;
2436 target_stack_t tuc_stack;
2437 target_ulong pad0;
2438 struct target_sigcontext tuc_mcontext;
2439 target_sigset_t tuc_sigmask;
2442 struct target_rt_sigframe {
2443 uint32_t rs_ass[4]; /* argument save space for o32 */
2444 uint32_t rs_code[2]; /* signal trampoline */
2445 struct target_siginfo rs_info;
2446 struct target_ucontext rs_uc;
2449 /* Install trampoline to jump back from signal handler */
2450 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2452 int err;
2455 * Set up the return code ...
2457 * li v0, __NR__foo_sigreturn
2458 * syscall
2461 err = __put_user(0x24020000 + syscall, tramp + 0);
2462 err |= __put_user(0x0000000c , tramp + 1);
2463 /* flush_cache_sigtramp((unsigned long) tramp); */
2464 return err;
2467 static inline int
2468 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2470 int err = 0;
2472 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2474 #define save_gp_reg(i) do { \
2475 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2476 } while(0)
2477 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2478 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2479 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2480 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2481 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2482 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2483 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2484 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2485 save_gp_reg(31);
2486 #undef save_gp_reg
2488 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2489 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2491 /* Not used yet, but might be useful if we ever have DSP suppport */
2492 #if 0
2493 if (cpu_has_dsp) {
2494 err |= __put_user(mfhi1(), &sc->sc_hi1);
2495 err |= __put_user(mflo1(), &sc->sc_lo1);
2496 err |= __put_user(mfhi2(), &sc->sc_hi2);
2497 err |= __put_user(mflo2(), &sc->sc_lo2);
2498 err |= __put_user(mfhi3(), &sc->sc_hi3);
2499 err |= __put_user(mflo3(), &sc->sc_lo3);
2500 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2502 /* same with 64 bit */
2503 #ifdef CONFIG_64BIT
2504 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2505 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2506 if (cpu_has_dsp) {
2507 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2508 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2509 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2510 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2511 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2512 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2513 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2515 #endif
2516 #endif
2518 #if 0
2519 err |= __put_user(!!used_math(), &sc->sc_used_math);
2521 if (!used_math())
2522 goto out;
2525 * Save FPU state to signal context. Signal handler will "inherit"
2526 * current FPU state.
2528 preempt_disable();
2530 if (!is_fpu_owner()) {
2531 own_fpu();
2532 restore_fp(current);
2534 err |= save_fp_context(sc);
2536 preempt_enable();
2537 out:
2538 #endif
2539 return err;
2542 static inline int
2543 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2545 int err = 0;
2547 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2549 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2550 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2552 #define restore_gp_reg(i) do { \
2553 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2554 } while(0)
2555 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2556 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2557 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2558 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2559 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2560 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2561 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2562 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2563 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2564 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2565 restore_gp_reg(31);
2566 #undef restore_gp_reg
2568 #if 0
2569 if (cpu_has_dsp) {
2570 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2571 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2572 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2573 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2574 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2575 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2576 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2578 #ifdef CONFIG_64BIT
2579 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2580 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2581 if (cpu_has_dsp) {
2582 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2583 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2584 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2585 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2586 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2587 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2588 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2590 #endif
2592 err |= __get_user(used_math, &sc->sc_used_math);
2593 conditional_used_math(used_math);
2595 preempt_disable();
2597 if (used_math()) {
2598 /* restore fpu context if we have used it before */
2599 own_fpu();
2600 err |= restore_fp_context(sc);
2601 } else {
2602 /* signal handler may have used FPU. Give it up. */
2603 lose_fpu();
2606 preempt_enable();
2607 #endif
2608 return err;
2611 * Determine which stack to use..
2613 static inline abi_ulong
2614 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2616 unsigned long sp;
2618 /* Default to using normal stack */
2619 sp = regs->active_tc.gpr[29];
2622 * FPU emulator may have it's own trampoline active just
2623 * above the user stack, 16-bytes before the next lowest
2624 * 16 byte boundary. Try to avoid trashing it.
2626 sp -= 32;
2628 /* This is the X/Open sanctioned signal stack switching. */
2629 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2630 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2633 return (sp - frame_size) & ~7;
2636 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2637 static void setup_frame(int sig, struct target_sigaction * ka,
2638 target_sigset_t *set, CPUState *regs)
2640 struct sigframe *frame;
2641 abi_ulong frame_addr;
2642 int i;
2644 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2645 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2646 goto give_sigsegv;
2648 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2650 if(setup_sigcontext(regs, &frame->sf_sc))
2651 goto give_sigsegv;
2653 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2654 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2655 goto give_sigsegv;
2659 * Arguments to signal handler:
2661 * a0 = signal number
2662 * a1 = 0 (should be cause)
2663 * a2 = pointer to struct sigcontext
2665 * $25 and PC point to the signal handler, $29 points to the
2666 * struct sigframe.
2668 regs->active_tc.gpr[ 4] = sig;
2669 regs->active_tc.gpr[ 5] = 0;
2670 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2671 regs->active_tc.gpr[29] = frame_addr;
2672 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2673 /* The original kernel code sets CP0_EPC to the handler
2674 * since it returns to userland using eret
2675 * we cannot do this here, and we must set PC directly */
2676 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2677 unlock_user_struct(frame, frame_addr, 1);
2678 return;
2680 give_sigsegv:
2681 unlock_user_struct(frame, frame_addr, 1);
2682 force_sig(TARGET_SIGSEGV/*, current*/);
2683 return;
2686 long do_sigreturn(CPUState *regs)
2688 struct sigframe *frame;
2689 abi_ulong frame_addr;
2690 sigset_t blocked;
2691 target_sigset_t target_set;
2692 int i;
2694 #if defined(DEBUG_SIGNAL)
2695 fprintf(stderr, "do_sigreturn\n");
2696 #endif
2697 frame_addr = regs->active_tc.gpr[29];
2698 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2699 goto badframe;
2701 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2702 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2703 goto badframe;
2706 target_to_host_sigset_internal(&blocked, &target_set);
2707 sigprocmask(SIG_SETMASK, &blocked, NULL);
2709 if (restore_sigcontext(regs, &frame->sf_sc))
2710 goto badframe;
2712 #if 0
2714 * Don't let your children do this ...
2716 __asm__ __volatile__(
2717 "move\t$29, %0\n\t"
2718 "j\tsyscall_exit"
2719 :/* no outputs */
2720 :"r" (&regs));
2721 /* Unreached */
2722 #endif
2724 regs->active_tc.PC = regs->CP0_EPC;
2725 /* I am not sure this is right, but it seems to work
2726 * maybe a problem with nested signals ? */
2727 regs->CP0_EPC = 0;
2728 return -TARGET_QEMU_ESIGRETURN;
2730 badframe:
2731 force_sig(TARGET_SIGSEGV/*, current*/);
2732 return 0;
2735 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2736 target_siginfo_t *info,
2737 target_sigset_t *set, CPUState *env)
2739 struct target_rt_sigframe *frame;
2740 abi_ulong frame_addr;
2741 int i;
2743 frame_addr = get_sigframe(ka, env, sizeof(*frame));
2744 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2745 goto give_sigsegv;
2747 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
2749 copy_siginfo_to_user(&frame->rs_info, info);
2751 __put_user(0, &frame->rs_uc.tuc_flags);
2752 __put_user(0, &frame->rs_uc.tuc_link);
2753 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
2754 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
2755 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
2756 &frame->rs_uc.tuc_stack.ss_flags);
2758 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
2760 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2761 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
2765 * Arguments to signal handler:
2767 * a0 = signal number
2768 * a1 = pointer to struct siginfo
2769 * a2 = pointer to struct ucontext
2771 * $25 and PC point to the signal handler, $29 points to the
2772 * struct sigframe.
2774 env->active_tc.gpr[ 4] = sig;
2775 env->active_tc.gpr[ 5] = frame_addr
2776 + offsetof(struct target_rt_sigframe, rs_info);
2777 env->active_tc.gpr[ 6] = frame_addr
2778 + offsetof(struct target_rt_sigframe, rs_uc);
2779 env->active_tc.gpr[29] = frame_addr;
2780 env->active_tc.gpr[31] = frame_addr
2781 + offsetof(struct target_rt_sigframe, rs_code);
2782 /* The original kernel code sets CP0_EPC to the handler
2783 * since it returns to userland using eret
2784 * we cannot do this here, and we must set PC directly */
2785 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
2786 unlock_user_struct(frame, frame_addr, 1);
2787 return;
2789 give_sigsegv:
2790 unlock_user_struct(frame, frame_addr, 1);
2791 force_sig(TARGET_SIGSEGV/*, current*/);
2792 return;
2795 long do_rt_sigreturn(CPUState *env)
2797 struct target_rt_sigframe *frame;
2798 abi_ulong frame_addr;
2799 sigset_t blocked;
2801 #if defined(DEBUG_SIGNAL)
2802 fprintf(stderr, "do_rt_sigreturn\n");
2803 #endif
2804 frame_addr = env->active_tc.gpr[29];
2805 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2806 goto badframe;
2808 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
2809 sigprocmask(SIG_SETMASK, &blocked, NULL);
2811 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
2812 goto badframe;
2814 if (do_sigaltstack(frame_addr +
2815 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
2816 0, get_sp_from_cpustate(env)) == -EFAULT)
2817 goto badframe;
2819 env->active_tc.PC = env->CP0_EPC;
2820 /* I am not sure this is right, but it seems to work
2821 * maybe a problem with nested signals ? */
2822 env->CP0_EPC = 0;
2823 return -TARGET_QEMU_ESIGRETURN;
2825 badframe:
2826 force_sig(TARGET_SIGSEGV/*, current*/);
2827 return 0;
2830 #elif defined(TARGET_SH4)
2833 * code and data structures from linux kernel:
2834 * include/asm-sh/sigcontext.h
2835 * arch/sh/kernel/signal.c
2838 struct target_sigcontext {
2839 target_ulong oldmask;
2841 /* CPU registers */
2842 target_ulong sc_gregs[16];
2843 target_ulong sc_pc;
2844 target_ulong sc_pr;
2845 target_ulong sc_sr;
2846 target_ulong sc_gbr;
2847 target_ulong sc_mach;
2848 target_ulong sc_macl;
2850 /* FPU registers */
2851 target_ulong sc_fpregs[16];
2852 target_ulong sc_xfpregs[16];
2853 unsigned int sc_fpscr;
2854 unsigned int sc_fpul;
2855 unsigned int sc_ownedfp;
2858 struct target_sigframe
2860 struct target_sigcontext sc;
2861 target_ulong extramask[TARGET_NSIG_WORDS-1];
2862 uint16_t retcode[3];
2866 struct target_ucontext {
2867 target_ulong tuc_flags;
2868 struct target_ucontext *tuc_link;
2869 target_stack_t tuc_stack;
2870 struct target_sigcontext tuc_mcontext;
2871 target_sigset_t tuc_sigmask; /* mask last for extensibility */
2874 struct target_rt_sigframe
2876 struct target_siginfo info;
2877 struct target_ucontext uc;
2878 uint16_t retcode[3];
2882 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2883 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2885 static abi_ulong get_sigframe(struct target_sigaction *ka,
2886 unsigned long sp, size_t frame_size)
2888 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2889 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2892 return (sp - frame_size) & -8ul;
2895 static int setup_sigcontext(struct target_sigcontext *sc,
2896 CPUState *regs, unsigned long mask)
2898 int err = 0;
2899 int i;
2901 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2902 COPY(gregs[0]); COPY(gregs[1]);
2903 COPY(gregs[2]); COPY(gregs[3]);
2904 COPY(gregs[4]); COPY(gregs[5]);
2905 COPY(gregs[6]); COPY(gregs[7]);
2906 COPY(gregs[8]); COPY(gregs[9]);
2907 COPY(gregs[10]); COPY(gregs[11]);
2908 COPY(gregs[12]); COPY(gregs[13]);
2909 COPY(gregs[14]); COPY(gregs[15]);
2910 COPY(gbr); COPY(mach);
2911 COPY(macl); COPY(pr);
2912 COPY(sr); COPY(pc);
2913 #undef COPY
2915 for (i=0; i<16; i++) {
2916 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
2918 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
2919 err |= __put_user(regs->fpul, &sc->sc_fpul);
2921 /* non-iBCS2 extensions.. */
2922 err |= __put_user(mask, &sc->oldmask);
2924 return err;
2927 static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
2928 target_ulong *r0_p)
2930 unsigned int err = 0;
2931 int i;
2933 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2934 COPY(gregs[1]);
2935 COPY(gregs[2]); COPY(gregs[3]);
2936 COPY(gregs[4]); COPY(gregs[5]);
2937 COPY(gregs[6]); COPY(gregs[7]);
2938 COPY(gregs[8]); COPY(gregs[9]);
2939 COPY(gregs[10]); COPY(gregs[11]);
2940 COPY(gregs[12]); COPY(gregs[13]);
2941 COPY(gregs[14]); COPY(gregs[15]);
2942 COPY(gbr); COPY(mach);
2943 COPY(macl); COPY(pr);
2944 COPY(sr); COPY(pc);
2945 #undef COPY
2947 for (i=0; i<16; i++) {
2948 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
2950 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
2951 err |= __get_user(regs->fpul, &sc->sc_fpul);
2953 regs->tra = -1; /* disable syscall checks */
2954 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
2955 return err;
2958 static void setup_frame(int sig, struct target_sigaction *ka,
2959 target_sigset_t *set, CPUState *regs)
2961 struct target_sigframe *frame;
2962 abi_ulong frame_addr;
2963 int i;
2964 int err = 0;
2965 int signal;
2967 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2968 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2969 goto give_sigsegv;
2971 signal = current_exec_domain_sig(sig);
2973 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2975 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2976 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2979 /* Set up to return from userspace. If provided, use a stub
2980 already in userspace. */
2981 if (ka->sa_flags & TARGET_SA_RESTORER) {
2982 regs->pr = (unsigned long) ka->sa_restorer;
2983 } else {
2984 /* Generate return code (system call to sigreturn) */
2985 err |= __put_user(MOVW(2), &frame->retcode[0]);
2986 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2987 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2988 regs->pr = (unsigned long) frame->retcode;
2991 if (err)
2992 goto give_sigsegv;
2994 /* Set up registers for signal handler */
2995 regs->gregs[15] = (unsigned long) frame;
2996 regs->gregs[4] = signal; /* Arg for signal handler */
2997 regs->gregs[5] = 0;
2998 regs->gregs[6] = (unsigned long) &frame->sc;
2999 regs->pc = (unsigned long) ka->_sa_handler;
3001 unlock_user_struct(frame, frame_addr, 1);
3002 return;
3004 give_sigsegv:
3005 unlock_user_struct(frame, frame_addr, 1);
3006 force_sig(TARGET_SIGSEGV);
3009 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3010 target_siginfo_t *info,
3011 target_sigset_t *set, CPUState *regs)
3013 struct target_rt_sigframe *frame;
3014 abi_ulong frame_addr;
3015 int i;
3016 int err = 0;
3017 int signal;
3019 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3020 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3021 goto give_sigsegv;
3023 signal = current_exec_domain_sig(sig);
3025 err |= copy_siginfo_to_user(&frame->info, info);
3027 /* Create the ucontext. */
3028 err |= __put_user(0, &frame->uc.tuc_flags);
3029 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3030 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3031 &frame->uc.tuc_stack.ss_sp);
3032 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3033 &frame->uc.tuc_stack.ss_flags);
3034 err |= __put_user(target_sigaltstack_used.ss_size,
3035 &frame->uc.tuc_stack.ss_size);
3036 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3037 regs, set->sig[0]);
3038 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3039 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3042 /* Set up to return from userspace. If provided, use a stub
3043 already in userspace. */
3044 if (ka->sa_flags & TARGET_SA_RESTORER) {
3045 regs->pr = (unsigned long) ka->sa_restorer;
3046 } else {
3047 /* Generate return code (system call to sigreturn) */
3048 err |= __put_user(MOVW(2), &frame->retcode[0]);
3049 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3050 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3051 regs->pr = (unsigned long) frame->retcode;
3054 if (err)
3055 goto give_sigsegv;
3057 /* Set up registers for signal handler */
3058 regs->gregs[15] = (unsigned long) frame;
3059 regs->gregs[4] = signal; /* Arg for signal handler */
3060 regs->gregs[5] = (unsigned long) &frame->info;
3061 regs->gregs[6] = (unsigned long) &frame->uc;
3062 regs->pc = (unsigned long) ka->_sa_handler;
3064 unlock_user_struct(frame, frame_addr, 1);
3065 return;
3067 give_sigsegv:
3068 unlock_user_struct(frame, frame_addr, 1);
3069 force_sig(TARGET_SIGSEGV);
3072 long do_sigreturn(CPUState *regs)
3074 struct target_sigframe *frame;
3075 abi_ulong frame_addr;
3076 sigset_t blocked;
3077 target_sigset_t target_set;
3078 target_ulong r0;
3079 int i;
3080 int err = 0;
3082 #if defined(DEBUG_SIGNAL)
3083 fprintf(stderr, "do_sigreturn\n");
3084 #endif
3085 frame_addr = regs->gregs[15];
3086 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3087 goto badframe;
3089 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3090 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3091 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3094 if (err)
3095 goto badframe;
3097 target_to_host_sigset_internal(&blocked, &target_set);
3098 sigprocmask(SIG_SETMASK, &blocked, NULL);
3100 if (restore_sigcontext(regs, &frame->sc, &r0))
3101 goto badframe;
3103 unlock_user_struct(frame, frame_addr, 0);
3104 return r0;
3106 badframe:
3107 unlock_user_struct(frame, frame_addr, 0);
3108 force_sig(TARGET_SIGSEGV);
3109 return 0;
3112 long do_rt_sigreturn(CPUState *regs)
3114 struct target_rt_sigframe *frame;
3115 abi_ulong frame_addr;
3116 sigset_t blocked;
3117 target_ulong r0;
3119 #if defined(DEBUG_SIGNAL)
3120 fprintf(stderr, "do_rt_sigreturn\n");
3121 #endif
3122 frame_addr = regs->gregs[15];
3123 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3124 goto badframe;
3126 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3127 sigprocmask(SIG_SETMASK, &blocked, NULL);
3129 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3130 goto badframe;
3132 if (do_sigaltstack(frame_addr +
3133 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3134 0, get_sp_from_cpustate(regs)) == -EFAULT)
3135 goto badframe;
3137 unlock_user_struct(frame, frame_addr, 0);
3138 return r0;
3140 badframe:
3141 unlock_user_struct(frame, frame_addr, 0);
3142 force_sig(TARGET_SIGSEGV);
3143 return 0;
3145 #elif defined(TARGET_MICROBLAZE)
3147 struct target_sigcontext {
3148 struct target_pt_regs regs; /* needs to be first */
3149 uint32_t oldmask;
3152 struct target_stack_t {
3153 abi_ulong ss_sp;
3154 int ss_flags;
3155 unsigned int ss_size;
3158 struct target_ucontext {
3159 abi_ulong tuc_flags;
3160 abi_ulong tuc_link;
3161 struct target_stack_t tuc_stack;
3162 struct target_sigcontext tuc_mcontext;
3163 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3166 /* Signal frames. */
3167 struct target_signal_frame {
3168 struct target_ucontext uc;
3169 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3170 uint32_t tramp[2];
3173 struct rt_signal_frame {
3174 struct siginfo info;
3175 struct ucontext uc;
3176 uint32_t tramp[2];
3179 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3181 __put_user(env->regs[0], &sc->regs.r0);
3182 __put_user(env->regs[1], &sc->regs.r1);
3183 __put_user(env->regs[2], &sc->regs.r2);
3184 __put_user(env->regs[3], &sc->regs.r3);
3185 __put_user(env->regs[4], &sc->regs.r4);
3186 __put_user(env->regs[5], &sc->regs.r5);
3187 __put_user(env->regs[6], &sc->regs.r6);
3188 __put_user(env->regs[7], &sc->regs.r7);
3189 __put_user(env->regs[8], &sc->regs.r8);
3190 __put_user(env->regs[9], &sc->regs.r9);
3191 __put_user(env->regs[10], &sc->regs.r10);
3192 __put_user(env->regs[11], &sc->regs.r11);
3193 __put_user(env->regs[12], &sc->regs.r12);
3194 __put_user(env->regs[13], &sc->regs.r13);
3195 __put_user(env->regs[14], &sc->regs.r14);
3196 __put_user(env->regs[15], &sc->regs.r15);
3197 __put_user(env->regs[16], &sc->regs.r16);
3198 __put_user(env->regs[17], &sc->regs.r17);
3199 __put_user(env->regs[18], &sc->regs.r18);
3200 __put_user(env->regs[19], &sc->regs.r19);
3201 __put_user(env->regs[20], &sc->regs.r20);
3202 __put_user(env->regs[21], &sc->regs.r21);
3203 __put_user(env->regs[22], &sc->regs.r22);
3204 __put_user(env->regs[23], &sc->regs.r23);
3205 __put_user(env->regs[24], &sc->regs.r24);
3206 __put_user(env->regs[25], &sc->regs.r25);
3207 __put_user(env->regs[26], &sc->regs.r26);
3208 __put_user(env->regs[27], &sc->regs.r27);
3209 __put_user(env->regs[28], &sc->regs.r28);
3210 __put_user(env->regs[29], &sc->regs.r29);
3211 __put_user(env->regs[30], &sc->regs.r30);
3212 __put_user(env->regs[31], &sc->regs.r31);
3213 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3216 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3218 __get_user(env->regs[0], &sc->regs.r0);
3219 __get_user(env->regs[1], &sc->regs.r1);
3220 __get_user(env->regs[2], &sc->regs.r2);
3221 __get_user(env->regs[3], &sc->regs.r3);
3222 __get_user(env->regs[4], &sc->regs.r4);
3223 __get_user(env->regs[5], &sc->regs.r5);
3224 __get_user(env->regs[6], &sc->regs.r6);
3225 __get_user(env->regs[7], &sc->regs.r7);
3226 __get_user(env->regs[8], &sc->regs.r8);
3227 __get_user(env->regs[9], &sc->regs.r9);
3228 __get_user(env->regs[10], &sc->regs.r10);
3229 __get_user(env->regs[11], &sc->regs.r11);
3230 __get_user(env->regs[12], &sc->regs.r12);
3231 __get_user(env->regs[13], &sc->regs.r13);
3232 __get_user(env->regs[14], &sc->regs.r14);
3233 __get_user(env->regs[15], &sc->regs.r15);
3234 __get_user(env->regs[16], &sc->regs.r16);
3235 __get_user(env->regs[17], &sc->regs.r17);
3236 __get_user(env->regs[18], &sc->regs.r18);
3237 __get_user(env->regs[19], &sc->regs.r19);
3238 __get_user(env->regs[20], &sc->regs.r20);
3239 __get_user(env->regs[21], &sc->regs.r21);
3240 __get_user(env->regs[22], &sc->regs.r22);
3241 __get_user(env->regs[23], &sc->regs.r23);
3242 __get_user(env->regs[24], &sc->regs.r24);
3243 __get_user(env->regs[25], &sc->regs.r25);
3244 __get_user(env->regs[26], &sc->regs.r26);
3245 __get_user(env->regs[27], &sc->regs.r27);
3246 __get_user(env->regs[28], &sc->regs.r28);
3247 __get_user(env->regs[29], &sc->regs.r29);
3248 __get_user(env->regs[30], &sc->regs.r30);
3249 __get_user(env->regs[31], &sc->regs.r31);
3250 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3253 static abi_ulong get_sigframe(struct target_sigaction *ka,
3254 CPUState *env, int frame_size)
3256 abi_ulong sp = env->regs[1];
3258 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3259 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3261 return ((sp - frame_size) & -8UL);
3264 static void setup_frame(int sig, struct target_sigaction *ka,
3265 target_sigset_t *set, CPUState *env)
3267 struct target_signal_frame *frame;
3268 abi_ulong frame_addr;
3269 int err = 0;
3270 int i;
3272 frame_addr = get_sigframe(ka, env, sizeof *frame);
3273 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3274 goto badframe;
3276 /* Save the mask. */
3277 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3278 if (err)
3279 goto badframe;
3281 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3282 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3283 goto badframe;
3286 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3288 /* Set up to return from userspace. If provided, use a stub
3289 already in userspace. */
3290 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3291 if (ka->sa_flags & TARGET_SA_RESTORER) {
3292 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3293 } else {
3294 uint32_t t;
3295 /* Note, these encodings are _big endian_! */
3296 /* addi r12, r0, __NR_sigreturn */
3297 t = 0x31800000UL | TARGET_NR_sigreturn;
3298 err |= __put_user(t, frame->tramp + 0);
3299 /* brki r14, 0x8 */
3300 t = 0xb9cc0008UL;
3301 err |= __put_user(t, frame->tramp + 1);
3303 /* Return from sighandler will jump to the tramp.
3304 Negative 8 offset because return is rtsd r15, 8 */
3305 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3308 if (err)
3309 goto badframe;
3311 /* Set up registers for signal handler */
3312 env->regs[1] = (unsigned long) frame;
3313 /* Signal handler args: */
3314 env->regs[5] = sig; /* Arg 0: signum */
3315 env->regs[6] = 0;
3316 env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
3318 /* Offset of 4 to handle microblaze rtid r14, 0 */
3319 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3321 unlock_user_struct(frame, frame_addr, 1);
3322 return;
3323 badframe:
3324 unlock_user_struct(frame, frame_addr, 1);
3325 force_sig(TARGET_SIGSEGV);
3328 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3329 target_siginfo_t *info,
3330 target_sigset_t *set, CPUState *env)
3332 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3335 long do_sigreturn(CPUState *env)
3337 struct target_signal_frame *frame;
3338 abi_ulong frame_addr;
3339 target_sigset_t target_set;
3340 sigset_t set;
3341 int i;
3343 frame_addr = env->regs[R_SP];
3344 /* Make sure the guest isn't playing games. */
3345 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3346 goto badframe;
3348 /* Restore blocked signals */
3349 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3350 goto badframe;
3351 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3352 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3353 goto badframe;
3355 target_to_host_sigset_internal(&set, &target_set);
3356 sigprocmask(SIG_SETMASK, &set, NULL);
3358 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3359 /* We got here through a sigreturn syscall, our path back is via an
3360 rtb insn so setup r14 for that. */
3361 env->regs[14] = env->sregs[SR_PC];
3363 unlock_user_struct(frame, frame_addr, 0);
3364 return env->regs[10];
3365 badframe:
3366 unlock_user_struct(frame, frame_addr, 0);
3367 force_sig(TARGET_SIGSEGV);
3370 long do_rt_sigreturn(CPUState *env)
3372 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3373 return -TARGET_ENOSYS;
3376 #elif defined(TARGET_CRIS)
3378 struct target_sigcontext {
3379 struct target_pt_regs regs; /* needs to be first */
3380 uint32_t oldmask;
3381 uint32_t usp; /* usp before stacking this gunk on it */
3384 /* Signal frames. */
3385 struct target_signal_frame {
3386 struct target_sigcontext sc;
3387 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3388 uint8_t retcode[8]; /* Trampoline code. */
3391 struct rt_signal_frame {
3392 struct siginfo *pinfo;
3393 void *puc;
3394 struct siginfo info;
3395 struct ucontext uc;
3396 uint8_t retcode[8]; /* Trampoline code. */
3399 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3401 __put_user(env->regs[0], &sc->regs.r0);
3402 __put_user(env->regs[1], &sc->regs.r1);
3403 __put_user(env->regs[2], &sc->regs.r2);
3404 __put_user(env->regs[3], &sc->regs.r3);
3405 __put_user(env->regs[4], &sc->regs.r4);
3406 __put_user(env->regs[5], &sc->regs.r5);
3407 __put_user(env->regs[6], &sc->regs.r6);
3408 __put_user(env->regs[7], &sc->regs.r7);
3409 __put_user(env->regs[8], &sc->regs.r8);
3410 __put_user(env->regs[9], &sc->regs.r9);
3411 __put_user(env->regs[10], &sc->regs.r10);
3412 __put_user(env->regs[11], &sc->regs.r11);
3413 __put_user(env->regs[12], &sc->regs.r12);
3414 __put_user(env->regs[13], &sc->regs.r13);
3415 __put_user(env->regs[14], &sc->usp);
3416 __put_user(env->regs[15], &sc->regs.acr);
3417 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3418 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3419 __put_user(env->pc, &sc->regs.erp);
3422 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3424 __get_user(env->regs[0], &sc->regs.r0);
3425 __get_user(env->regs[1], &sc->regs.r1);
3426 __get_user(env->regs[2], &sc->regs.r2);
3427 __get_user(env->regs[3], &sc->regs.r3);
3428 __get_user(env->regs[4], &sc->regs.r4);
3429 __get_user(env->regs[5], &sc->regs.r5);
3430 __get_user(env->regs[6], &sc->regs.r6);
3431 __get_user(env->regs[7], &sc->regs.r7);
3432 __get_user(env->regs[8], &sc->regs.r8);
3433 __get_user(env->regs[9], &sc->regs.r9);
3434 __get_user(env->regs[10], &sc->regs.r10);
3435 __get_user(env->regs[11], &sc->regs.r11);
3436 __get_user(env->regs[12], &sc->regs.r12);
3437 __get_user(env->regs[13], &sc->regs.r13);
3438 __get_user(env->regs[14], &sc->usp);
3439 __get_user(env->regs[15], &sc->regs.acr);
3440 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3441 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3442 __get_user(env->pc, &sc->regs.erp);
3445 static abi_ulong get_sigframe(CPUState *env, int framesize)
3447 abi_ulong sp;
3448 /* Align the stack downwards to 4. */
3449 sp = (env->regs[R_SP] & ~3);
3450 return sp - framesize;
3453 static void setup_frame(int sig, struct target_sigaction *ka,
3454 target_sigset_t *set, CPUState *env)
3456 struct target_signal_frame *frame;
3457 abi_ulong frame_addr;
3458 int err = 0;
3459 int i;
3461 frame_addr = get_sigframe(env, sizeof *frame);
3462 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3463 goto badframe;
3466 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3467 * use this trampoline anymore but it sets it up for GDB.
3468 * In QEMU, using the trampoline simplifies things a bit so we use it.
3470 * This is movu.w __NR_sigreturn, r9; break 13;
3472 err |= __put_user(0x9c5f, frame->retcode+0);
3473 err |= __put_user(TARGET_NR_sigreturn,
3474 frame->retcode+2);
3475 err |= __put_user(0xe93d, frame->retcode+4);
3477 /* Save the mask. */
3478 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3479 if (err)
3480 goto badframe;
3482 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3483 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3484 goto badframe;
3487 setup_sigcontext(&frame->sc, env);
3489 /* Move the stack and setup the arguments for the handler. */
3490 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3491 env->regs[10] = sig;
3492 env->pc = (unsigned long) ka->_sa_handler;
3493 /* Link SRP so the guest returns through the trampoline. */
3494 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3496 unlock_user_struct(frame, frame_addr, 1);
3497 return;
3498 badframe:
3499 unlock_user_struct(frame, frame_addr, 1);
3500 force_sig(TARGET_SIGSEGV);
3503 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3504 target_siginfo_t *info,
3505 target_sigset_t *set, CPUState *env)
3507 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3510 long do_sigreturn(CPUState *env)
3512 struct target_signal_frame *frame;
3513 abi_ulong frame_addr;
3514 target_sigset_t target_set;
3515 sigset_t set;
3516 int i;
3518 frame_addr = env->regs[R_SP];
3519 /* Make sure the guest isn't playing games. */
3520 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3521 goto badframe;
3523 /* Restore blocked signals */
3524 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3525 goto badframe;
3526 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3527 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3528 goto badframe;
3530 target_to_host_sigset_internal(&set, &target_set);
3531 sigprocmask(SIG_SETMASK, &set, NULL);
3533 restore_sigcontext(&frame->sc, env);
3534 unlock_user_struct(frame, frame_addr, 0);
3535 return env->regs[10];
3536 badframe:
3537 unlock_user_struct(frame, frame_addr, 0);
3538 force_sig(TARGET_SIGSEGV);
3541 long do_rt_sigreturn(CPUState *env)
3543 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3544 return -TARGET_ENOSYS;
3547 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3549 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
3550 the signal handling is different enough that we haven't implemented
3551 support for PPC64 yet. Hence the restriction above.
3553 There are various #if'd blocks for code for TARGET_PPC64. These
3554 blocks should go away so that we can successfully run 32-bit and
3555 64-bit binaries on a QEMU configured for PPC64. */
3557 /* Size of dummy stack frame allocated when calling signal handler.
3558 See arch/powerpc/include/asm/ptrace.h. */
3559 #if defined(TARGET_PPC64)
3560 #define SIGNAL_FRAMESIZE 128
3561 #else
3562 #define SIGNAL_FRAMESIZE 64
3563 #endif
3565 /* See arch/powerpc/include/asm/sigcontext.h. */
3566 struct target_sigcontext {
3567 target_ulong _unused[4];
3568 int32_t signal;
3569 #if defined(TARGET_PPC64)
3570 int32_t pad0;
3571 #endif
3572 target_ulong handler;
3573 target_ulong oldmask;
3574 target_ulong regs; /* struct pt_regs __user * */
3575 /* TODO: PPC64 includes extra bits here. */
3578 /* Indices for target_mcontext.mc_gregs, below.
3579 See arch/powerpc/include/asm/ptrace.h for details. */
3580 enum {
3581 TARGET_PT_R0 = 0,
3582 TARGET_PT_R1 = 1,
3583 TARGET_PT_R2 = 2,
3584 TARGET_PT_R3 = 3,
3585 TARGET_PT_R4 = 4,
3586 TARGET_PT_R5 = 5,
3587 TARGET_PT_R6 = 6,
3588 TARGET_PT_R7 = 7,
3589 TARGET_PT_R8 = 8,
3590 TARGET_PT_R9 = 9,
3591 TARGET_PT_R10 = 10,
3592 TARGET_PT_R11 = 11,
3593 TARGET_PT_R12 = 12,
3594 TARGET_PT_R13 = 13,
3595 TARGET_PT_R14 = 14,
3596 TARGET_PT_R15 = 15,
3597 TARGET_PT_R16 = 16,
3598 TARGET_PT_R17 = 17,
3599 TARGET_PT_R18 = 18,
3600 TARGET_PT_R19 = 19,
3601 TARGET_PT_R20 = 20,
3602 TARGET_PT_R21 = 21,
3603 TARGET_PT_R22 = 22,
3604 TARGET_PT_R23 = 23,
3605 TARGET_PT_R24 = 24,
3606 TARGET_PT_R25 = 25,
3607 TARGET_PT_R26 = 26,
3608 TARGET_PT_R27 = 27,
3609 TARGET_PT_R28 = 28,
3610 TARGET_PT_R29 = 29,
3611 TARGET_PT_R30 = 30,
3612 TARGET_PT_R31 = 31,
3613 TARGET_PT_NIP = 32,
3614 TARGET_PT_MSR = 33,
3615 TARGET_PT_ORIG_R3 = 34,
3616 TARGET_PT_CTR = 35,
3617 TARGET_PT_LNK = 36,
3618 TARGET_PT_XER = 37,
3619 TARGET_PT_CCR = 38,
3620 /* Yes, there are two registers with #39. One is 64-bit only. */
3621 TARGET_PT_MQ = 39,
3622 TARGET_PT_SOFTE = 39,
3623 TARGET_PT_TRAP = 40,
3624 TARGET_PT_DAR = 41,
3625 TARGET_PT_DSISR = 42,
3626 TARGET_PT_RESULT = 43,
3627 TARGET_PT_REGS_COUNT = 44
3630 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
3631 on 64-bit PPC, sigcontext and mcontext are one and the same. */
3632 struct target_mcontext {
3633 target_ulong mc_gregs[48];
3634 /* Includes fpscr. */
3635 uint64_t mc_fregs[33];
3636 target_ulong mc_pad[2];
3637 /* We need to handle Altivec and SPE at the same time, which no
3638 kernel needs to do. Fortunately, the kernel defines this bit to
3639 be Altivec-register-large all the time, rather than trying to
3640 twiddle it based on the specific platform. */
3641 union {
3642 /* SPE vector registers. One extra for SPEFSCR. */
3643 uint32_t spe[33];
3644 /* Altivec vector registers. The packing of VSCR and VRSAVE
3645 varies depending on whether we're PPC64 or not: PPC64 splits
3646 them apart; PPC32 stuffs them together. */
3647 #if defined(TARGET_PPC64)
3648 #define QEMU_NVRREG 34
3649 #else
3650 #define QEMU_NVRREG 33
3651 #endif
3652 ppc_avr_t altivec[QEMU_NVRREG];
3653 #undef QEMU_NVRREG
3654 } mc_vregs __attribute__((__aligned__(16)));
3657 struct target_ucontext {
3658 target_ulong tuc_flags;
3659 target_ulong tuc_link; /* struct ucontext __user * */
3660 struct target_sigaltstack tuc_stack;
3661 #if !defined(TARGET_PPC64)
3662 int32_t tuc_pad[7];
3663 target_ulong tuc_regs; /* struct mcontext __user *
3664 points to uc_mcontext field */
3665 #endif
3666 target_sigset_t tuc_sigmask;
3667 #if defined(TARGET_PPC64)
3668 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
3669 struct target_sigcontext tuc_mcontext;
3670 #else
3671 int32_t tuc_maskext[30];
3672 int32_t tuc_pad2[3];
3673 struct target_mcontext tuc_mcontext;
3674 #endif
3677 /* See arch/powerpc/kernel/signal_32.c. */
3678 struct target_sigframe {
3679 struct target_sigcontext sctx;
3680 struct target_mcontext mctx;
3681 int32_t abigap[56];
3684 struct target_rt_sigframe {
3685 struct target_siginfo info;
3686 struct target_ucontext uc;
3687 int32_t abigap[56];
3690 /* We use the mc_pad field for the signal return trampoline. */
3691 #define tramp mc_pad
3693 /* See arch/powerpc/kernel/signal.c. */
3694 static target_ulong get_sigframe(struct target_sigaction *ka,
3695 CPUState *env,
3696 int frame_size)
3698 target_ulong oldsp, newsp;
3700 oldsp = env->gpr[1];
3702 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
3703 (sas_ss_flags(oldsp))) {
3704 oldsp = (target_sigaltstack_used.ss_sp
3705 + target_sigaltstack_used.ss_size);
3708 newsp = (oldsp - frame_size) & ~0xFUL;
3710 return newsp;
3713 static int save_user_regs(CPUState *env, struct target_mcontext *frame,
3714 int sigret)
3716 target_ulong msr = env->msr;
3717 int i;
3718 target_ulong ccr = 0;
3720 /* In general, the kernel attempts to be intelligent about what it
3721 needs to save for Altivec/FP/SPE registers. We don't care that
3722 much, so we just go ahead and save everything. */
3724 /* Save general registers. */
3725 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3726 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
3727 return 1;
3730 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3731 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3732 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3733 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3734 return 1;
3736 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3737 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
3739 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3740 return 1;
3742 /* Save Altivec registers if necessary. */
3743 if (env->insns_flags & PPC_ALTIVEC) {
3744 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3745 ppc_avr_t *avr = &env->avr[i];
3746 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3748 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
3749 __put_user(avr->u64[1], &vreg->u64[1])) {
3750 return 1;
3753 /* Set MSR_VR in the saved MSR value to indicate that
3754 frame->mc_vregs contains valid data. */
3755 msr |= MSR_VR;
3756 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
3757 &frame->mc_vregs.altivec[32].u32[3]))
3758 return 1;
3761 /* Save floating point registers. */
3762 if (env->insns_flags & PPC_FLOAT) {
3763 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3764 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
3765 return 1;
3768 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
3769 return 1;
3772 /* Save SPE registers. The kernel only saves the high half. */
3773 if (env->insns_flags & PPC_SPE) {
3774 #if defined(TARGET_PPC64)
3775 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3776 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
3777 return 1;
3780 #else
3781 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3782 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3783 return 1;
3786 #endif
3787 /* Set MSR_SPE in the saved MSR value to indicate that
3788 frame->mc_vregs contains valid data. */
3789 msr |= MSR_SPE;
3790 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3791 return 1;
3794 /* Store MSR. */
3795 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3796 return 1;
3798 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
3799 if (sigret) {
3800 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
3801 __put_user(0x44000002UL, &frame->tramp[1])) {
3802 return 1;
3806 return 0;
3809 static int restore_user_regs(CPUState *env,
3810 struct target_mcontext *frame, int sig)
3812 target_ulong save_r2 = 0;
3813 target_ulong msr;
3814 target_ulong ccr;
3816 int i;
3818 if (!sig) {
3819 save_r2 = env->gpr[2];
3822 /* Restore general registers. */
3823 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3824 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
3825 return 1;
3828 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3829 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3830 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3831 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3832 return 1;
3833 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3834 return 1;
3836 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3837 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
3840 if (!sig) {
3841 env->gpr[2] = save_r2;
3843 /* Restore MSR. */
3844 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3845 return 1;
3847 /* If doing signal return, restore the previous little-endian mode. */
3848 if (sig)
3849 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
3851 /* Restore Altivec registers if necessary. */
3852 if (env->insns_flags & PPC_ALTIVEC) {
3853 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3854 ppc_avr_t *avr = &env->avr[i];
3855 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3857 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
3858 __get_user(avr->u64[1], &vreg->u64[1])) {
3859 return 1;
3862 /* Set MSR_VEC in the saved MSR value to indicate that
3863 frame->mc_vregs contains valid data. */
3864 if (__get_user(env->spr[SPR_VRSAVE],
3865 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
3866 return 1;
3869 /* Restore floating point registers. */
3870 if (env->insns_flags & PPC_FLOAT) {
3871 uint64_t fpscr;
3872 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3873 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
3874 return 1;
3877 if (__get_user(fpscr, &frame->mc_fregs[32]))
3878 return 1;
3879 env->fpscr = (uint32_t) fpscr;
3882 /* Save SPE registers. The kernel only saves the high half. */
3883 if (env->insns_flags & PPC_SPE) {
3884 #if defined(TARGET_PPC64)
3885 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3886 uint32_t hi;
3888 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
3889 return 1;
3891 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
3893 #else
3894 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3895 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3896 return 1;
3899 #endif
3900 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3901 return 1;
3904 return 0;
3907 static void setup_frame(int sig, struct target_sigaction *ka,
3908 target_sigset_t *set, CPUState *env)
3910 struct target_sigframe *frame;
3911 struct target_sigcontext *sc;
3912 target_ulong frame_addr, newsp;
3913 int err = 0;
3914 int signal;
3916 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3917 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3918 goto sigsegv;
3919 sc = &frame->sctx;
3921 signal = current_exec_domain_sig(sig);
3923 err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
3924 err |= __put_user(set->sig[0], &sc->oldmask);
3925 #if defined(TARGET_PPC64)
3926 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
3927 #else
3928 err |= __put_user(set->sig[1], &sc->_unused[3]);
3929 #endif
3930 err |= __put_user(h2g(&frame->mctx), &sc->regs);
3931 err |= __put_user(sig, &sc->signal);
3933 /* Save user regs. */
3934 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
3936 /* The kernel checks for the presence of a VDSO here. We don't
3937 emulate a vdso, so use a sigreturn system call. */
3938 env->lr = (target_ulong) h2g(frame->mctx.tramp);
3940 /* Turn off all fp exceptions. */
3941 env->fpscr = 0;
3943 /* Create a stack frame for the caller of the handler. */
3944 newsp = frame_addr - SIGNAL_FRAMESIZE;
3945 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
3947 if (err)
3948 goto sigsegv;
3950 /* Set up registers for signal handler. */
3951 env->gpr[1] = newsp;
3952 env->gpr[3] = signal;
3953 env->gpr[4] = (target_ulong) h2g(sc);
3954 env->nip = (target_ulong) ka->_sa_handler;
3955 /* Signal handlers are entered in big-endian mode. */
3956 env->msr &= ~MSR_LE;
3958 unlock_user_struct(frame, frame_addr, 1);
3959 return;
3961 sigsegv:
3962 unlock_user_struct(frame, frame_addr, 1);
3963 if (logfile)
3964 fprintf (logfile, "segfaulting from setup_frame\n");
3965 force_sig(TARGET_SIGSEGV);
3968 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3969 target_siginfo_t *info,
3970 target_sigset_t *set, CPUState *env)
3972 struct target_rt_sigframe *rt_sf;
3973 struct target_mcontext *frame;
3974 target_ulong rt_sf_addr, newsp = 0;
3975 int i, err = 0;
3976 int signal;
3978 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
3979 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
3980 goto sigsegv;
3982 signal = current_exec_domain_sig(sig);
3984 err |= copy_siginfo_to_user(&rt_sf->info, info);
3986 err |= __put_user(0, &rt_sf->uc.tuc_flags);
3987 err |= __put_user(0, &rt_sf->uc.tuc_link);
3988 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
3989 &rt_sf->uc.tuc_stack.ss_sp);
3990 err |= __put_user(sas_ss_flags(env->gpr[1]),
3991 &rt_sf->uc.tuc_stack.ss_flags);
3992 err |= __put_user(target_sigaltstack_used.ss_size,
3993 &rt_sf->uc.tuc_stack.ss_size);
3994 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
3995 &rt_sf->uc.tuc_regs);
3996 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3997 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4000 frame = &rt_sf->uc.tuc_mcontext;
4001 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4003 /* The kernel checks for the presence of a VDSO here. We don't
4004 emulate a vdso, so use a sigreturn system call. */
4005 env->lr = (target_ulong) h2g(frame->tramp);
4007 /* Turn off all fp exceptions. */
4008 env->fpscr = 0;
4010 /* Create a stack frame for the caller of the handler. */
4011 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4012 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4014 if (err)
4015 goto sigsegv;
4017 /* Set up registers for signal handler. */
4018 env->gpr[1] = newsp;
4019 env->gpr[3] = (target_ulong) signal;
4020 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4021 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4022 env->gpr[6] = (target_ulong) h2g(rt_sf);
4023 env->nip = (target_ulong) ka->_sa_handler;
4024 /* Signal handlers are entered in big-endian mode. */
4025 env->msr &= ~MSR_LE;
4027 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4028 return;
4030 sigsegv:
4031 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4032 if (logfile)
4033 fprintf (logfile, "segfaulting from setup_rt_frame\n");
4034 force_sig(TARGET_SIGSEGV);
4038 long do_sigreturn(CPUState *env)
4040 struct target_sigcontext *sc = NULL;
4041 struct target_mcontext *sr = NULL;
4042 target_ulong sr_addr, sc_addr;
4043 sigset_t blocked;
4044 target_sigset_t set;
4046 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4047 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4048 goto sigsegv;
4050 #if defined(TARGET_PPC64)
4051 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4052 #else
4053 if(__get_user(set.sig[0], &sc->oldmask) ||
4054 __get_user(set.sig[1], &sc->_unused[3]))
4055 goto sigsegv;
4056 #endif
4057 target_to_host_sigset_internal(&blocked, &set);
4058 sigprocmask(SIG_SETMASK, &blocked, NULL);
4060 if (__get_user(sr_addr, &sc->regs))
4061 goto sigsegv;
4062 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4063 goto sigsegv;
4064 if (restore_user_regs(env, sr, 1))
4065 goto sigsegv;
4067 unlock_user_struct(sr, sr_addr, 1);
4068 unlock_user_struct(sc, sc_addr, 1);
4069 return -TARGET_QEMU_ESIGRETURN;
4071 sigsegv:
4072 unlock_user_struct(sr, sr_addr, 1);
4073 unlock_user_struct(sc, sc_addr, 1);
4074 if (logfile)
4075 fprintf (logfile, "segfaulting from do_sigreturn\n");
4076 force_sig(TARGET_SIGSEGV);
4077 return 0;
4080 /* See arch/powerpc/kernel/signal_32.c. */
4081 static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
4083 struct target_mcontext *mcp;
4084 target_ulong mcp_addr;
4085 sigset_t blocked;
4086 target_sigset_t set;
4088 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4089 sizeof (set)))
4090 return 1;
4092 #if defined(TARGET_PPC64)
4093 fprintf (stderr, "do_setcontext: not implemented\n");
4094 return 0;
4095 #else
4096 if (__get_user(mcp_addr, &ucp->tuc_regs))
4097 return 1;
4099 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4100 return 1;
4102 target_to_host_sigset_internal(&blocked, &set);
4103 sigprocmask(SIG_SETMASK, &blocked, NULL);
4104 if (restore_user_regs(env, mcp, sig))
4105 goto sigsegv;
4107 unlock_user_struct(mcp, mcp_addr, 1);
4108 return 0;
4110 sigsegv:
4111 unlock_user_struct(mcp, mcp_addr, 1);
4112 return 1;
4113 #endif
4116 long do_rt_sigreturn(CPUState *env)
4118 struct target_rt_sigframe *rt_sf = NULL;
4119 target_ulong rt_sf_addr;
4121 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4122 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4123 goto sigsegv;
4125 if (do_setcontext(&rt_sf->uc, env, 1))
4126 goto sigsegv;
4128 do_sigaltstack(rt_sf_addr
4129 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4130 0, env->gpr[1]);
4132 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4133 return -TARGET_QEMU_ESIGRETURN;
4135 sigsegv:
4136 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4137 if (logfile)
4138 fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
4139 force_sig(TARGET_SIGSEGV);
4140 return 0;
4143 #elif defined(TARGET_M68K)
4145 struct target_sigcontext {
4146 abi_ulong sc_mask;
4147 abi_ulong sc_usp;
4148 abi_ulong sc_d0;
4149 abi_ulong sc_d1;
4150 abi_ulong sc_a0;
4151 abi_ulong sc_a1;
4152 unsigned short sc_sr;
4153 abi_ulong sc_pc;
4156 struct target_sigframe
4158 abi_ulong pretcode;
4159 int sig;
4160 int code;
4161 abi_ulong psc;
4162 char retcode[8];
4163 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4164 struct target_sigcontext sc;
4167 typedef int target_greg_t;
4168 #define TARGET_NGREG 18
4169 typedef target_greg_t target_gregset_t[TARGET_NGREG];
4171 typedef struct target_fpregset {
4172 int f_fpcntl[3];
4173 int f_fpregs[8*3];
4174 } target_fpregset_t;
4176 struct target_mcontext {
4177 int version;
4178 target_gregset_t gregs;
4179 target_fpregset_t fpregs;
4182 #define TARGET_MCONTEXT_VERSION 2
4184 struct target_ucontext {
4185 abi_ulong tuc_flags;
4186 abi_ulong tuc_link;
4187 target_stack_t tuc_stack;
4188 struct target_mcontext tuc_mcontext;
4189 abi_long tuc_filler[80];
4190 target_sigset_t tuc_sigmask;
4193 struct target_rt_sigframe
4195 abi_ulong pretcode;
4196 int sig;
4197 abi_ulong pinfo;
4198 abi_ulong puc;
4199 char retcode[8];
4200 struct target_siginfo info;
4201 struct target_ucontext uc;
4204 static int
4205 setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask)
4207 int err = 0;
4209 err |= __put_user(mask, &sc->sc_mask);
4210 err |= __put_user(env->aregs[7], &sc->sc_usp);
4211 err |= __put_user(env->dregs[0], &sc->sc_d0);
4212 err |= __put_user(env->dregs[1], &sc->sc_d1);
4213 err |= __put_user(env->aregs[0], &sc->sc_a0);
4214 err |= __put_user(env->aregs[1], &sc->sc_a1);
4215 err |= __put_user(env->sr, &sc->sc_sr);
4216 err |= __put_user(env->pc, &sc->sc_pc);
4218 return err;
4221 static int
4222 restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0)
4224 int err = 0;
4225 int temp;
4227 err |= __get_user(env->aregs[7], &sc->sc_usp);
4228 err |= __get_user(env->dregs[1], &sc->sc_d1);
4229 err |= __get_user(env->aregs[0], &sc->sc_a0);
4230 err |= __get_user(env->aregs[1], &sc->sc_a1);
4231 err |= __get_user(env->pc, &sc->sc_pc);
4232 err |= __get_user(temp, &sc->sc_sr);
4233 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4235 *pd0 = tswapl(sc->sc_d0);
4237 return err;
4241 * Determine which stack to use..
4243 static inline abi_ulong
4244 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
4246 unsigned long sp;
4248 sp = regs->aregs[7];
4250 /* This is the X/Open sanctioned signal stack switching. */
4251 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4252 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4255 return ((sp - frame_size) & -8UL);
4258 static void setup_frame(int sig, struct target_sigaction *ka,
4259 target_sigset_t *set, CPUState *env)
4261 struct target_sigframe *frame;
4262 abi_ulong frame_addr;
4263 abi_ulong retcode_addr;
4264 abi_ulong sc_addr;
4265 int err = 0;
4266 int i;
4268 frame_addr = get_sigframe(ka, env, sizeof *frame);
4269 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4270 goto give_sigsegv;
4272 err |= __put_user(sig, &frame->sig);
4274 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4275 err |= __put_user(sc_addr, &frame->psc);
4277 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4278 if (err)
4279 goto give_sigsegv;
4281 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4282 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4283 goto give_sigsegv;
4286 /* Set up to return from userspace. */
4288 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4289 err |= __put_user(retcode_addr, &frame->pretcode);
4291 /* moveq #,d0; trap #0 */
4293 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4294 (long *)(frame->retcode));
4296 if (err)
4297 goto give_sigsegv;
4299 /* Set up to return from userspace */
4301 env->aregs[7] = frame_addr;
4302 env->pc = ka->_sa_handler;
4304 unlock_user_struct(frame, frame_addr, 1);
4305 return;
4307 give_sigsegv:
4308 unlock_user_struct(frame, frame_addr, 1);
4309 force_sig(TARGET_SIGSEGV);
4312 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
4313 CPUState *env)
4315 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4316 int err;
4318 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
4319 err |= __put_user(env->dregs[0], &gregs[0]);
4320 err |= __put_user(env->dregs[1], &gregs[1]);
4321 err |= __put_user(env->dregs[2], &gregs[2]);
4322 err |= __put_user(env->dregs[3], &gregs[3]);
4323 err |= __put_user(env->dregs[4], &gregs[4]);
4324 err |= __put_user(env->dregs[5], &gregs[5]);
4325 err |= __put_user(env->dregs[6], &gregs[6]);
4326 err |= __put_user(env->dregs[7], &gregs[7]);
4327 err |= __put_user(env->aregs[0], &gregs[8]);
4328 err |= __put_user(env->aregs[1], &gregs[9]);
4329 err |= __put_user(env->aregs[2], &gregs[10]);
4330 err |= __put_user(env->aregs[3], &gregs[11]);
4331 err |= __put_user(env->aregs[4], &gregs[12]);
4332 err |= __put_user(env->aregs[5], &gregs[13]);
4333 err |= __put_user(env->aregs[6], &gregs[14]);
4334 err |= __put_user(env->aregs[7], &gregs[15]);
4335 err |= __put_user(env->pc, &gregs[16]);
4336 err |= __put_user(env->sr, &gregs[17]);
4338 return err;
4341 static inline int target_rt_restore_ucontext(CPUState *env,
4342 struct target_ucontext *uc,
4343 int *pd0)
4345 int temp;
4346 int err;
4347 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4349 err = __get_user(temp, &uc->tuc_mcontext.version);
4350 if (temp != TARGET_MCONTEXT_VERSION)
4351 goto badframe;
4353 /* restore passed registers */
4354 err |= __get_user(env->dregs[0], &gregs[0]);
4355 err |= __get_user(env->dregs[1], &gregs[1]);
4356 err |= __get_user(env->dregs[2], &gregs[2]);
4357 err |= __get_user(env->dregs[3], &gregs[3]);
4358 err |= __get_user(env->dregs[4], &gregs[4]);
4359 err |= __get_user(env->dregs[5], &gregs[5]);
4360 err |= __get_user(env->dregs[6], &gregs[6]);
4361 err |= __get_user(env->dregs[7], &gregs[7]);
4362 err |= __get_user(env->aregs[0], &gregs[8]);
4363 err |= __get_user(env->aregs[1], &gregs[9]);
4364 err |= __get_user(env->aregs[2], &gregs[10]);
4365 err |= __get_user(env->aregs[3], &gregs[11]);
4366 err |= __get_user(env->aregs[4], &gregs[12]);
4367 err |= __get_user(env->aregs[5], &gregs[13]);
4368 err |= __get_user(env->aregs[6], &gregs[14]);
4369 err |= __get_user(env->aregs[7], &gregs[15]);
4370 err |= __get_user(env->pc, &gregs[16]);
4371 err |= __get_user(temp, &gregs[17]);
4372 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4374 *pd0 = env->dregs[0];
4375 return err;
4377 badframe:
4378 return 1;
4381 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4382 target_siginfo_t *info,
4383 target_sigset_t *set, CPUState *env)
4385 struct target_rt_sigframe *frame;
4386 abi_ulong frame_addr;
4387 abi_ulong retcode_addr;
4388 abi_ulong info_addr;
4389 abi_ulong uc_addr;
4390 int err = 0;
4391 int i;
4393 frame_addr = get_sigframe(ka, env, sizeof *frame);
4394 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4395 goto give_sigsegv;
4397 err |= __put_user(sig, &frame->sig);
4399 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4400 err |= __put_user(info_addr, &frame->pinfo);
4402 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4403 err |= __put_user(uc_addr, &frame->puc);
4405 err |= copy_siginfo_to_user(&frame->info, info);
4407 /* Create the ucontext */
4409 err |= __put_user(0, &frame->uc.tuc_flags);
4410 err |= __put_user(0, &frame->uc.tuc_link);
4411 err |= __put_user(target_sigaltstack_used.ss_sp,
4412 &frame->uc.tuc_stack.ss_sp);
4413 err |= __put_user(sas_ss_flags(env->aregs[7]),
4414 &frame->uc.tuc_stack.ss_flags);
4415 err |= __put_user(target_sigaltstack_used.ss_size,
4416 &frame->uc.tuc_stack.ss_size);
4417 err |= target_rt_setup_ucontext(&frame->uc, env);
4419 if (err)
4420 goto give_sigsegv;
4422 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4423 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
4424 goto give_sigsegv;
4427 /* Set up to return from userspace. */
4429 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4430 err |= __put_user(retcode_addr, &frame->pretcode);
4432 /* moveq #,d0; notb d0; trap #0 */
4434 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
4435 (long *)(frame->retcode + 0));
4436 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
4438 if (err)
4439 goto give_sigsegv;
4441 /* Set up to return from userspace */
4443 env->aregs[7] = frame_addr;
4444 env->pc = ka->_sa_handler;
4446 unlock_user_struct(frame, frame_addr, 1);
4447 return;
4449 give_sigsegv:
4450 unlock_user_struct(frame, frame_addr, 1);
4451 force_sig(TARGET_SIGSEGV);
4454 long do_sigreturn(CPUState *env)
4456 struct target_sigframe *frame;
4457 abi_ulong frame_addr = env->aregs[7] - 4;
4458 target_sigset_t target_set;
4459 sigset_t set;
4460 int d0, i;
4462 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4463 goto badframe;
4465 /* set blocked signals */
4467 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4468 goto badframe;
4470 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4471 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4472 goto badframe;
4475 target_to_host_sigset_internal(&set, &target_set);
4476 sigprocmask(SIG_SETMASK, &set, NULL);
4478 /* restore registers */
4480 if (restore_sigcontext(env, &frame->sc, &d0))
4481 goto badframe;
4483 unlock_user_struct(frame, frame_addr, 0);
4484 return d0;
4486 badframe:
4487 unlock_user_struct(frame, frame_addr, 0);
4488 force_sig(TARGET_SIGSEGV);
4489 return 0;
4492 long do_rt_sigreturn(CPUState *env)
4494 struct target_rt_sigframe *frame;
4495 abi_ulong frame_addr = env->aregs[7] - 4;
4496 target_sigset_t target_set;
4497 sigset_t set;
4498 int d0;
4500 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4501 goto badframe;
4503 target_to_host_sigset_internal(&set, &target_set);
4504 sigprocmask(SIG_SETMASK, &set, NULL);
4506 /* restore registers */
4508 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
4509 goto badframe;
4511 if (do_sigaltstack(frame_addr +
4512 offsetof(struct target_rt_sigframe, uc.tuc_stack),
4513 0, get_sp_from_cpustate(env)) == -EFAULT)
4514 goto badframe;
4516 unlock_user_struct(frame, frame_addr, 0);
4517 return d0;
4519 badframe:
4520 unlock_user_struct(frame, frame_addr, 0);
4521 force_sig(TARGET_SIGSEGV);
4522 return 0;
4525 #elif defined(TARGET_ALPHA)
4527 struct target_sigcontext {
4528 abi_long sc_onstack;
4529 abi_long sc_mask;
4530 abi_long sc_pc;
4531 abi_long sc_ps;
4532 abi_long sc_regs[32];
4533 abi_long sc_ownedfp;
4534 abi_long sc_fpregs[32];
4535 abi_ulong sc_fpcr;
4536 abi_ulong sc_fp_control;
4537 abi_ulong sc_reserved1;
4538 abi_ulong sc_reserved2;
4539 abi_ulong sc_ssize;
4540 abi_ulong sc_sbase;
4541 abi_ulong sc_traparg_a0;
4542 abi_ulong sc_traparg_a1;
4543 abi_ulong sc_traparg_a2;
4544 abi_ulong sc_fp_trap_pc;
4545 abi_ulong sc_fp_trigger_sum;
4546 abi_ulong sc_fp_trigger_inst;
4549 struct target_ucontext {
4550 abi_ulong tuc_flags;
4551 abi_ulong tuc_link;
4552 abi_ulong tuc_osf_sigmask;
4553 target_stack_t tuc_stack;
4554 struct target_sigcontext tuc_mcontext;
4555 target_sigset_t tuc_sigmask;
4558 struct target_sigframe {
4559 struct target_sigcontext sc;
4560 unsigned int retcode[3];
4563 struct target_rt_sigframe {
4564 target_siginfo_t info;
4565 struct target_ucontext uc;
4566 unsigned int retcode[3];
4569 #define INSN_MOV_R30_R16 0x47fe0410
4570 #define INSN_LDI_R0 0x201f0000
4571 #define INSN_CALLSYS 0x00000083
4573 static int setup_sigcontext(struct target_sigcontext *sc, CPUState *env,
4574 abi_ulong frame_addr, target_sigset_t *set)
4576 int i, err = 0;
4578 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4579 err |= __put_user(set->sig[0], &sc->sc_mask);
4580 err |= __put_user(env->pc, &sc->sc_pc);
4581 err |= __put_user(8, &sc->sc_ps);
4583 for (i = 0; i < 31; ++i) {
4584 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
4586 err |= __put_user(0, &sc->sc_regs[31]);
4588 for (i = 0; i < 31; ++i) {
4589 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
4591 err |= __put_user(0, &sc->sc_fpregs[31]);
4592 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
4594 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
4595 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
4596 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
4598 return err;
4601 static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
4603 uint64_t fpcr;
4604 int i, err = 0;
4606 err |= __get_user(env->pc, &sc->sc_pc);
4608 for (i = 0; i < 31; ++i) {
4609 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
4611 for (i = 0; i < 31; ++i) {
4612 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
4615 err |= __get_user(fpcr, &sc->sc_fpcr);
4616 cpu_alpha_store_fpcr(env, fpcr);
4618 return err;
4621 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
4622 CPUState *env, unsigned long framesize)
4624 abi_ulong sp = env->ir[IR_SP];
4626 /* This is the X/Open sanctioned signal stack switching. */
4627 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
4628 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4630 return (sp - framesize) & -32;
4633 static void setup_frame(int sig, struct target_sigaction *ka,
4634 target_sigset_t *set, CPUState *env)
4636 abi_ulong frame_addr, r26;
4637 struct target_sigframe *frame;
4638 int err = 0;
4640 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4641 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4642 goto give_sigsegv;
4645 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
4647 if (ka->sa_restorer) {
4648 r26 = ka->sa_restorer;
4649 } else {
4650 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4651 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
4652 &frame->retcode[1]);
4653 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4654 /* imb() */
4655 r26 = frame_addr;
4658 unlock_user_struct(frame, frame_addr, 1);
4660 if (err) {
4661 give_sigsegv:
4662 if (sig == TARGET_SIGSEGV) {
4663 ka->_sa_handler = TARGET_SIG_DFL;
4665 force_sig(TARGET_SIGSEGV);
4668 env->ir[IR_RA] = r26;
4669 env->ir[IR_PV] = env->pc = ka->_sa_handler;
4670 env->ir[IR_A0] = sig;
4671 env->ir[IR_A1] = 0;
4672 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
4673 env->ir[IR_SP] = frame_addr;
4676 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4677 target_siginfo_t *info,
4678 target_sigset_t *set, CPUState *env)
4680 abi_ulong frame_addr, r26;
4681 struct target_rt_sigframe *frame;
4682 int i, err = 0;
4684 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4685 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4686 goto give_sigsegv;
4689 err |= copy_siginfo_to_user(&frame->info, info);
4691 err |= __put_user(0, &frame->uc.tuc_flags);
4692 err |= __put_user(0, &frame->uc.tuc_link);
4693 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
4694 err |= __put_user(target_sigaltstack_used.ss_sp,
4695 &frame->uc.tuc_stack.ss_sp);
4696 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
4697 &frame->uc.tuc_stack.ss_flags);
4698 err |= __put_user(target_sigaltstack_used.ss_size,
4699 &frame->uc.tuc_stack.ss_size);
4700 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
4701 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
4702 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
4705 if (ka->sa_restorer) {
4706 r26 = ka->sa_restorer;
4707 } else {
4708 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4709 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
4710 &frame->retcode[1]);
4711 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4712 /* imb(); */
4713 r26 = frame_addr;
4716 if (err) {
4717 give_sigsegv:
4718 if (sig == TARGET_SIGSEGV) {
4719 ka->_sa_handler = TARGET_SIG_DFL;
4721 force_sig(TARGET_SIGSEGV);
4724 env->ir[IR_RA] = r26;
4725 env->ir[IR_PV] = env->pc = ka->_sa_handler;
4726 env->ir[IR_A0] = sig;
4727 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
4728 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
4729 env->ir[IR_SP] = frame_addr;
4732 long do_sigreturn(CPUState *env)
4734 struct target_sigcontext *sc;
4735 abi_ulong sc_addr = env->ir[IR_A0];
4736 target_sigset_t target_set;
4737 sigset_t set;
4739 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
4740 goto badframe;
4743 target_sigemptyset(&target_set);
4744 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
4745 goto badframe;
4748 target_to_host_sigset_internal(&set, &target_set);
4749 sigprocmask(SIG_SETMASK, &set, NULL);
4751 if (restore_sigcontext(env, sc)) {
4752 goto badframe;
4754 unlock_user_struct(sc, sc_addr, 0);
4755 return env->ir[IR_V0];
4757 badframe:
4758 unlock_user_struct(sc, sc_addr, 0);
4759 force_sig(TARGET_SIGSEGV);
4762 long do_rt_sigreturn(CPUState *env)
4764 abi_ulong frame_addr = env->ir[IR_A0];
4765 struct target_rt_sigframe *frame;
4766 sigset_t set;
4768 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4769 goto badframe;
4771 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4772 sigprocmask(SIG_SETMASK, &set, NULL);
4774 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
4775 goto badframe;
4777 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
4778 uc.tuc_stack),
4779 0, env->ir[IR_SP]) == -EFAULT) {
4780 goto badframe;
4783 unlock_user_struct(frame, frame_addr, 0);
4784 return env->ir[IR_V0];
4787 badframe:
4788 unlock_user_struct(frame, frame_addr, 0);
4789 force_sig(TARGET_SIGSEGV);
4792 #else
4794 static void setup_frame(int sig, struct target_sigaction *ka,
4795 target_sigset_t *set, CPUState *env)
4797 fprintf(stderr, "setup_frame: not implemented\n");
4800 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4801 target_siginfo_t *info,
4802 target_sigset_t *set, CPUState *env)
4804 fprintf(stderr, "setup_rt_frame: not implemented\n");
4807 long do_sigreturn(CPUState *env)
4809 fprintf(stderr, "do_sigreturn: not implemented\n");
4810 return -TARGET_ENOSYS;
4813 long do_rt_sigreturn(CPUState *env)
4815 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
4816 return -TARGET_ENOSYS;
4819 #endif
4821 void process_pending_signals(CPUState *cpu_env)
4823 int sig;
4824 abi_ulong handler;
4825 sigset_t set, old_set;
4826 target_sigset_t target_old_set;
4827 struct emulated_sigtable *k;
4828 struct target_sigaction *sa;
4829 struct sigqueue *q;
4830 TaskState *ts = cpu_env->opaque;
4832 if (!ts->signal_pending)
4833 return;
4835 /* FIXME: This is not threadsafe. */
4836 k = ts->sigtab;
4837 for(sig = 1; sig <= TARGET_NSIG; sig++) {
4838 if (k->pending)
4839 goto handle_signal;
4840 k++;
4842 /* if no signal is pending, just return */
4843 ts->signal_pending = 0;
4844 return;
4846 handle_signal:
4847 #ifdef DEBUG_SIGNAL
4848 fprintf(stderr, "qemu: process signal %d\n", sig);
4849 #endif
4850 /* dequeue signal */
4851 q = k->first;
4852 k->first = q->next;
4853 if (!k->first)
4854 k->pending = 0;
4856 sig = gdb_handlesig (cpu_env, sig);
4857 if (!sig) {
4858 sa = NULL;
4859 handler = TARGET_SIG_IGN;
4860 } else {
4861 sa = &sigact_table[sig - 1];
4862 handler = sa->_sa_handler;
4865 if (handler == TARGET_SIG_DFL) {
4866 /* default handler : ignore some signal. The other are job control or fatal */
4867 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
4868 kill(getpid(),SIGSTOP);
4869 } else if (sig != TARGET_SIGCHLD &&
4870 sig != TARGET_SIGURG &&
4871 sig != TARGET_SIGWINCH &&
4872 sig != TARGET_SIGCONT) {
4873 force_sig(sig);
4875 } else if (handler == TARGET_SIG_IGN) {
4876 /* ignore sig */
4877 } else if (handler == TARGET_SIG_ERR) {
4878 force_sig(sig);
4879 } else {
4880 /* compute the blocked signals during the handler execution */
4881 target_to_host_sigset(&set, &sa->sa_mask);
4882 /* SA_NODEFER indicates that the current signal should not be
4883 blocked during the handler */
4884 if (!(sa->sa_flags & TARGET_SA_NODEFER))
4885 sigaddset(&set, target_to_host_signal(sig));
4887 /* block signals in the handler using Linux */
4888 sigprocmask(SIG_BLOCK, &set, &old_set);
4889 /* save the previous blocked signal state to restore it at the
4890 end of the signal execution (see do_sigreturn) */
4891 host_to_target_sigset_internal(&target_old_set, &old_set);
4893 /* if the CPU is in VM86 mode, we restore the 32 bit values */
4894 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
4896 CPUX86State *env = cpu_env;
4897 if (env->eflags & VM_MASK)
4898 save_v86_state(env);
4900 #endif
4901 /* prepare the stack frame of the virtual CPU */
4902 if (sa->sa_flags & TARGET_SA_SIGINFO)
4903 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
4904 else
4905 setup_frame(sig, sa, &target_old_set, cpu_env);
4906 if (sa->sa_flags & TARGET_SA_RESETHAND)
4907 sa->_sa_handler = TARGET_SIG_DFL;
4909 if (q != &k->info)
4910 free_sigqueue(cpu_env, q);