2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include <sys/ucontext.h>
27 #include <sys/resource.h>
30 #include "qemu-common.h"
31 #include "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used = {
38 .ss_flags = TARGET_SS_DISABLE,
41 static struct target_sigaction sigact_table[TARGET_NSIG];
43 static void host_signal_handler(int host_signum, siginfo_t *info,
46 static uint8_t host_to_target_signal_table[_NSIG] = {
47 [SIGHUP] = TARGET_SIGHUP,
48 [SIGINT] = TARGET_SIGINT,
49 [SIGQUIT] = TARGET_SIGQUIT,
50 [SIGILL] = TARGET_SIGILL,
51 [SIGTRAP] = TARGET_SIGTRAP,
52 [SIGABRT] = TARGET_SIGABRT,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS] = TARGET_SIGBUS,
55 [SIGFPE] = TARGET_SIGFPE,
56 [SIGKILL] = TARGET_SIGKILL,
57 [SIGUSR1] = TARGET_SIGUSR1,
58 [SIGSEGV] = TARGET_SIGSEGV,
59 [SIGUSR2] = TARGET_SIGUSR2,
60 [SIGPIPE] = TARGET_SIGPIPE,
61 [SIGALRM] = TARGET_SIGALRM,
62 [SIGTERM] = TARGET_SIGTERM,
64 [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 [SIGCHLD] = TARGET_SIGCHLD,
67 [SIGCONT] = TARGET_SIGCONT,
68 [SIGSTOP] = TARGET_SIGSTOP,
69 [SIGTSTP] = TARGET_SIGTSTP,
70 [SIGTTIN] = TARGET_SIGTTIN,
71 [SIGTTOU] = TARGET_SIGTTOU,
72 [SIGURG] = TARGET_SIGURG,
73 [SIGXCPU] = TARGET_SIGXCPU,
74 [SIGXFSZ] = TARGET_SIGXFSZ,
75 [SIGVTALRM] = TARGET_SIGVTALRM,
76 [SIGPROF] = TARGET_SIGPROF,
77 [SIGWINCH] = TARGET_SIGWINCH,
78 [SIGIO] = TARGET_SIGIO,
79 [SIGPWR] = TARGET_SIGPWR,
80 [SIGSYS] = TARGET_SIGSYS,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN] = __SIGRTMAX,
87 [__SIGRTMAX] = __SIGRTMIN,
89 static uint8_t target_to_host_signal_table[_NSIG];
91 static inline int on_sig_stack(unsigned long sp)
93 return (sp - target_sigaltstack_used.ss_sp
94 < target_sigaltstack_used.ss_size);
97 static inline int sas_ss_flags(unsigned long sp)
99 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
100 : on_sig_stack(sp) ? SS_ONSTACK : 0);
103 int host_to_target_signal(int sig)
105 if (sig < 0 || sig >= _NSIG)
107 return host_to_target_signal_table[sig];
110 int target_to_host_signal(int sig)
112 if (sig < 0 || sig >= _NSIG)
114 return target_to_host_signal_table[sig];
117 static inline void target_sigemptyset(target_sigset_t *set)
119 memset(set, 0, sizeof(*set));
122 static inline void target_sigaddset(target_sigset_t *set, int signum)
125 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
126 set->sig[signum / TARGET_NSIG_BPW] |= mask;
129 static inline int target_sigismember(const target_sigset_t *set, int signum)
132 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
133 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
136 static void host_to_target_sigset_internal(target_sigset_t *d,
140 target_sigemptyset(d);
141 for (i = 1; i <= TARGET_NSIG; i++) {
142 if (sigismember(s, i)) {
143 target_sigaddset(d, host_to_target_signal(i));
148 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
153 host_to_target_sigset_internal(&d1, s);
154 for(i = 0;i < TARGET_NSIG_WORDS; i++)
155 d->sig[i] = tswapal(d1.sig[i]);
158 static void target_to_host_sigset_internal(sigset_t *d,
159 const target_sigset_t *s)
163 for (i = 1; i <= TARGET_NSIG; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
170 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
175 for(i = 0;i < TARGET_NSIG_WORDS; i++)
176 s1.sig[i] = tswapal(s->sig[i]);
177 target_to_host_sigset_internal(d, &s1);
180 void host_to_target_old_sigset(abi_ulong *old_sigset,
181 const sigset_t *sigset)
184 host_to_target_sigset(&d, sigset);
185 *old_sigset = d.sig[0];
188 void target_to_host_old_sigset(sigset_t *sigset,
189 const abi_ulong *old_sigset)
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS; i++)
197 target_to_host_sigset(sigset, &d);
200 /* Wrapper for sigprocmask function
201 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
202 * are host signal set, not guest ones. This wraps the sigprocmask host calls
203 * that should be protected (calls originated from guest)
205 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
207 return sigprocmask(how, set, oldset);
210 /* siginfo conversion */
212 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
213 const siginfo_t *info)
215 int sig = host_to_target_signal(info->si_signo);
216 tinfo->si_signo = sig;
218 tinfo->si_code = info->si_code;
220 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
221 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
222 /* Should never come here, but who knows. The information for
223 the target is irrelevant. */
224 tinfo->_sifields._sigfault._addr = 0;
225 } else if (sig == TARGET_SIGIO) {
226 tinfo->_sifields._sigpoll._band = info->si_band;
227 tinfo->_sifields._sigpoll._fd = info->si_fd;
228 } else if (sig == TARGET_SIGCHLD) {
229 tinfo->_sifields._sigchld._pid = info->si_pid;
230 tinfo->_sifields._sigchld._uid = info->si_uid;
231 tinfo->_sifields._sigchld._status
232 = host_to_target_waitstatus(info->si_status);
233 tinfo->_sifields._sigchld._utime = info->si_utime;
234 tinfo->_sifields._sigchld._stime = info->si_stime;
235 } else if (sig >= TARGET_SIGRTMIN) {
236 tinfo->_sifields._rt._pid = info->si_pid;
237 tinfo->_sifields._rt._uid = info->si_uid;
238 /* XXX: potential problem if 64 bit */
239 tinfo->_sifields._rt._sigval.sival_ptr
240 = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
244 static void tswap_siginfo(target_siginfo_t *tinfo,
245 const target_siginfo_t *info)
247 int sig = info->si_signo;
248 tinfo->si_signo = tswap32(sig);
249 tinfo->si_errno = tswap32(info->si_errno);
250 tinfo->si_code = tswap32(info->si_code);
252 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
253 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
254 tinfo->_sifields._sigfault._addr
255 = tswapal(info->_sifields._sigfault._addr);
256 } else if (sig == TARGET_SIGIO) {
257 tinfo->_sifields._sigpoll._band
258 = tswap32(info->_sifields._sigpoll._band);
259 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
260 } else if (sig == TARGET_SIGCHLD) {
261 tinfo->_sifields._sigchld._pid
262 = tswap32(info->_sifields._sigchld._pid);
263 tinfo->_sifields._sigchld._uid
264 = tswap32(info->_sifields._sigchld._uid);
265 tinfo->_sifields._sigchld._status
266 = tswap32(info->_sifields._sigchld._status);
267 tinfo->_sifields._sigchld._utime
268 = tswapal(info->_sifields._sigchld._utime);
269 tinfo->_sifields._sigchld._stime
270 = tswapal(info->_sifields._sigchld._stime);
271 } else if (sig >= TARGET_SIGRTMIN) {
272 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
273 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
274 tinfo->_sifields._rt._sigval.sival_ptr
275 = tswapal(info->_sifields._rt._sigval.sival_ptr);
280 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
282 host_to_target_siginfo_noswap(tinfo, info);
283 tswap_siginfo(tinfo, tinfo);
286 /* XXX: we support only POSIX RT signals are used. */
287 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
288 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
290 info->si_signo = tswap32(tinfo->si_signo);
291 info->si_errno = tswap32(tinfo->si_errno);
292 info->si_code = tswap32(tinfo->si_code);
293 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
294 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
295 info->si_value.sival_ptr =
296 (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
299 static int fatal_signal (int sig)
304 case TARGET_SIGWINCH:
305 /* Ignored by default. */
312 /* Job control signals. */
319 /* returns 1 if given signal should dump core if not handled */
320 static int core_dump_signal(int sig)
336 void signal_init(void)
338 struct sigaction act;
339 struct sigaction oact;
343 /* generate signal conversion tables */
344 for(i = 1; i < _NSIG; i++) {
345 if (host_to_target_signal_table[i] == 0)
346 host_to_target_signal_table[i] = i;
348 for(i = 1; i < _NSIG; i++) {
349 j = host_to_target_signal_table[i];
350 target_to_host_signal_table[j] = i;
353 /* set all host signal handlers. ALL signals are blocked during
354 the handlers to serialize them. */
355 memset(sigact_table, 0, sizeof(sigact_table));
357 sigfillset(&act.sa_mask);
358 act.sa_flags = SA_SIGINFO;
359 act.sa_sigaction = host_signal_handler;
360 for(i = 1; i <= TARGET_NSIG; i++) {
361 host_sig = target_to_host_signal(i);
362 sigaction(host_sig, NULL, &oact);
363 if (oact.sa_sigaction == (void *)SIG_IGN) {
364 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
365 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
366 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
368 /* If there's already a handler installed then something has
369 gone horribly wrong, so don't even try to handle that case. */
370 /* Install some handlers for our own use. We need at least
371 SIGSEGV and SIGBUS, to detect exceptions. We can not just
372 trap all signals because it affects syscall interrupt
373 behavior. But do trap all default-fatal signals. */
374 if (fatal_signal (i))
375 sigaction(host_sig, &act, NULL);
379 /* signal queue handling */
381 static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
383 CPUState *cpu = ENV_GET_CPU(env);
384 TaskState *ts = cpu->opaque;
385 struct sigqueue *q = ts->first_free;
388 ts->first_free = q->next;
392 static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
394 CPUState *cpu = ENV_GET_CPU(env);
395 TaskState *ts = cpu->opaque;
397 q->next = ts->first_free;
401 /* abort execution with signal */
402 static void QEMU_NORETURN force_sig(int target_sig)
404 CPUState *cpu = thread_cpu;
405 CPUArchState *env = cpu->env_ptr;
406 TaskState *ts = (TaskState *)cpu->opaque;
407 int host_sig, core_dumped = 0;
408 struct sigaction act;
409 host_sig = target_to_host_signal(target_sig);
410 gdb_signalled(env, target_sig);
412 /* dump core if supported by target binary format */
413 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
416 ((*ts->bprm->core_dump)(target_sig, env) == 0);
419 /* we already dumped the core of target process, we don't want
420 * a coredump of qemu itself */
421 struct rlimit nodump;
422 getrlimit(RLIMIT_CORE, &nodump);
424 setrlimit(RLIMIT_CORE, &nodump);
425 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
426 target_sig, strsignal(host_sig), "core dumped" );
429 /* The proper exit code for dying from an uncaught signal is
430 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
431 * a negative value. To get the proper exit code we need to
432 * actually die from an uncaught signal. Here the default signal
433 * handler is installed, we send ourself a signal and we wait for
435 sigfillset(&act.sa_mask);
436 act.sa_handler = SIG_DFL;
438 sigaction(host_sig, &act, NULL);
440 /* For some reason raise(host_sig) doesn't send the signal when
441 * statically linked on x86-64. */
442 kill(getpid(), host_sig);
444 /* Make sure the signal isn't masked (just reuse the mask inside
446 sigdelset(&act.sa_mask, host_sig);
447 sigsuspend(&act.sa_mask);
453 /* queue a signal so that it will be send to the virtual CPU as soon
455 int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
457 CPUState *cpu = ENV_GET_CPU(env);
458 TaskState *ts = cpu->opaque;
459 struct emulated_sigtable *k;
460 struct sigqueue *q, **pq;
464 #if defined(DEBUG_SIGNAL)
465 fprintf(stderr, "queue_signal: sig=%d\n",
468 k = &ts->sigtab[sig - 1];
469 queue = gdb_queuesig ();
470 handler = sigact_table[sig - 1]._sa_handler;
471 if (!queue && handler == TARGET_SIG_DFL) {
472 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
473 kill(getpid(),SIGSTOP);
476 /* default handler : ignore some signal. The other are fatal */
477 if (sig != TARGET_SIGCHLD &&
478 sig != TARGET_SIGURG &&
479 sig != TARGET_SIGWINCH &&
480 sig != TARGET_SIGCONT) {
483 return 0; /* indicate ignored */
485 } else if (!queue && handler == TARGET_SIG_IGN) {
488 } else if (!queue && handler == TARGET_SIG_ERR) {
492 if (sig < TARGET_SIGRTMIN) {
493 /* if non real time signal, we queue exactly one signal */
503 q = alloc_sigqueue(env);
514 /* signal that a new signal is pending */
515 ts->signal_pending = 1;
516 return 1; /* indicates that the signal was queued */
520 static void host_signal_handler(int host_signum, siginfo_t *info,
523 CPUArchState *env = thread_cpu->env_ptr;
525 target_siginfo_t tinfo;
527 /* the CPU emulator uses some host signals to detect exceptions,
528 we forward to it some signals */
529 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
530 && info->si_code > 0) {
531 if (cpu_signal_handler(host_signum, info, puc))
535 /* get target signal number */
536 sig = host_to_target_signal(host_signum);
537 if (sig < 1 || sig > TARGET_NSIG)
539 #if defined(DEBUG_SIGNAL)
540 fprintf(stderr, "qemu: got signal %d\n", sig);
542 host_to_target_siginfo_noswap(&tinfo, info);
543 if (queue_signal(env, sig, &tinfo) == 1) {
544 /* interrupt the virtual CPU as soon as possible */
545 cpu_exit(thread_cpu);
549 /* do_sigaltstack() returns target values and errnos. */
550 /* compare linux/kernel/signal.c:do_sigaltstack() */
551 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
554 struct target_sigaltstack oss;
556 /* XXX: test errors */
559 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
560 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
561 __put_user(sas_ss_flags(sp), &oss.ss_flags);
566 struct target_sigaltstack *uss;
567 struct target_sigaltstack ss;
569 ret = -TARGET_EFAULT;
570 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
571 || __get_user(ss.ss_sp, &uss->ss_sp)
572 || __get_user(ss.ss_size, &uss->ss_size)
573 || __get_user(ss.ss_flags, &uss->ss_flags))
575 unlock_user_struct(uss, uss_addr, 0);
578 if (on_sig_stack(sp))
581 ret = -TARGET_EINVAL;
582 if (ss.ss_flags != TARGET_SS_DISABLE
583 && ss.ss_flags != TARGET_SS_ONSTACK
587 if (ss.ss_flags == TARGET_SS_DISABLE) {
591 ret = -TARGET_ENOMEM;
592 if (ss.ss_size < MINSIGSTKSZ)
596 target_sigaltstack_used.ss_sp = ss.ss_sp;
597 target_sigaltstack_used.ss_size = ss.ss_size;
601 ret = -TARGET_EFAULT;
602 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
611 /* do_sigaction() return host values and errnos */
612 int do_sigaction(int sig, const struct target_sigaction *act,
613 struct target_sigaction *oact)
615 struct target_sigaction *k;
616 struct sigaction act1;
620 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
622 k = &sigact_table[sig - 1];
623 #if defined(DEBUG_SIGNAL)
624 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
628 __put_user(k->_sa_handler, &oact->_sa_handler);
629 __put_user(k->sa_flags, &oact->sa_flags);
630 #if !defined(TARGET_MIPS)
631 __put_user(k->sa_restorer, &oact->sa_restorer);
634 oact->sa_mask = k->sa_mask;
637 /* FIXME: This is not threadsafe. */
638 __get_user(k->_sa_handler, &act->_sa_handler);
639 __get_user(k->sa_flags, &act->sa_flags);
640 #if !defined(TARGET_MIPS)
641 __get_user(k->sa_restorer, &act->sa_restorer);
643 /* To be swapped in target_to_host_sigset. */
644 k->sa_mask = act->sa_mask;
646 /* we update the host linux signal state */
647 host_sig = target_to_host_signal(sig);
648 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
649 sigfillset(&act1.sa_mask);
650 act1.sa_flags = SA_SIGINFO;
651 if (k->sa_flags & TARGET_SA_RESTART)
652 act1.sa_flags |= SA_RESTART;
653 /* NOTE: it is important to update the host kernel signal
654 ignore state to avoid getting unexpected interrupted
656 if (k->_sa_handler == TARGET_SIG_IGN) {
657 act1.sa_sigaction = (void *)SIG_IGN;
658 } else if (k->_sa_handler == TARGET_SIG_DFL) {
659 if (fatal_signal (sig))
660 act1.sa_sigaction = host_signal_handler;
662 act1.sa_sigaction = (void *)SIG_DFL;
664 act1.sa_sigaction = host_signal_handler;
666 ret = sigaction(host_sig, &act1, NULL);
672 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
673 const target_siginfo_t *info)
675 tswap_siginfo(tinfo, info);
679 static inline int current_exec_domain_sig(int sig)
681 return /* current->exec_domain && current->exec_domain->signal_invmap
682 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
685 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
687 /* from the Linux kernel */
689 struct target_fpreg {
690 uint16_t significand[4];
694 struct target_fpxreg {
695 uint16_t significand[4];
700 struct target_xmmreg {
701 abi_ulong element[4];
704 struct target_fpstate {
705 /* Regular FPU environment */
713 struct target_fpreg _st[8];
715 uint16_t magic; /* 0xffff = regular FPU data only */
717 /* FXSR FPU environment */
718 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
721 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
722 struct target_xmmreg _xmm[8];
723 abi_ulong padding[56];
726 #define X86_FXSR_MAGIC 0x0000
728 struct target_sigcontext {
746 abi_ulong esp_at_signal;
748 abi_ulong fpstate; /* pointer */
753 struct target_ucontext {
756 target_stack_t tuc_stack;
757 struct target_sigcontext tuc_mcontext;
758 target_sigset_t tuc_sigmask; /* mask last for extensibility */
765 struct target_sigcontext sc;
766 struct target_fpstate fpstate;
767 abi_ulong extramask[TARGET_NSIG_WORDS-1];
777 struct target_siginfo info;
778 struct target_ucontext uc;
779 struct target_fpstate fpstate;
784 * Set up a signal frame.
787 /* XXX: save x87 state */
789 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
790 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
792 CPUState *cs = CPU(x86_env_get_cpu(env));
796 /* already locked in setup_frame() */
797 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
798 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
799 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
800 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
801 err |= __put_user(env->regs[R_EDI], &sc->edi);
802 err |= __put_user(env->regs[R_ESI], &sc->esi);
803 err |= __put_user(env->regs[R_EBP], &sc->ebp);
804 err |= __put_user(env->regs[R_ESP], &sc->esp);
805 err |= __put_user(env->regs[R_EBX], &sc->ebx);
806 err |= __put_user(env->regs[R_EDX], &sc->edx);
807 err |= __put_user(env->regs[R_ECX], &sc->ecx);
808 err |= __put_user(env->regs[R_EAX], &sc->eax);
809 err |= __put_user(cs->exception_index, &sc->trapno);
810 err |= __put_user(env->error_code, &sc->err);
811 err |= __put_user(env->eip, &sc->eip);
812 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
813 err |= __put_user(env->eflags, &sc->eflags);
814 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
815 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
817 cpu_x86_fsave(env, fpstate_addr, 1);
818 fpstate->status = fpstate->sw;
820 err |= __put_user(magic, &fpstate->magic);
821 err |= __put_user(fpstate_addr, &sc->fpstate);
823 /* non-iBCS2 extensions.. */
824 err |= __put_user(mask, &sc->oldmask);
825 err |= __put_user(env->cr[2], &sc->cr2);
830 * Determine which stack to use..
833 static inline abi_ulong
834 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
838 /* Default to using normal stack */
839 esp = env->regs[R_ESP];
840 /* This is the X/Open sanctioned signal stack switching. */
841 if (ka->sa_flags & TARGET_SA_ONSTACK) {
842 if (sas_ss_flags(esp) == 0)
843 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
846 /* This is the legacy signal stack switching. */
848 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
849 !(ka->sa_flags & TARGET_SA_RESTORER) &&
851 esp = (unsigned long) ka->sa_restorer;
853 return (esp - frame_size) & -8ul;
856 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
857 static void setup_frame(int sig, struct target_sigaction *ka,
858 target_sigset_t *set, CPUX86State *env)
860 abi_ulong frame_addr;
861 struct sigframe *frame;
864 frame_addr = get_sigframe(ka, env, sizeof(*frame));
866 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
869 err |= __put_user(current_exec_domain_sig(sig),
874 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
875 frame_addr + offsetof(struct sigframe, fpstate));
879 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
880 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
884 /* Set up to return from userspace. If provided, use a stub
885 already in userspace. */
886 if (ka->sa_flags & TARGET_SA_RESTORER) {
887 err |= __put_user(ka->sa_restorer, &frame->pretcode);
890 abi_ulong retcode_addr;
891 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
892 err |= __put_user(retcode_addr, &frame->pretcode);
893 /* This is popl %eax ; movl $,%eax ; int $0x80 */
895 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
896 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
898 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
904 /* Set up registers for signal handler */
905 env->regs[R_ESP] = frame_addr;
906 env->eip = ka->_sa_handler;
908 cpu_x86_load_seg(env, R_DS, __USER_DS);
909 cpu_x86_load_seg(env, R_ES, __USER_DS);
910 cpu_x86_load_seg(env, R_SS, __USER_DS);
911 cpu_x86_load_seg(env, R_CS, __USER_CS);
912 env->eflags &= ~TF_MASK;
914 unlock_user_struct(frame, frame_addr, 1);
919 unlock_user_struct(frame, frame_addr, 1);
920 if (sig == TARGET_SIGSEGV)
921 ka->_sa_handler = TARGET_SIG_DFL;
922 force_sig(TARGET_SIGSEGV /* , current */);
925 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
926 static void setup_rt_frame(int sig, struct target_sigaction *ka,
927 target_siginfo_t *info,
928 target_sigset_t *set, CPUX86State *env)
930 abi_ulong frame_addr, addr;
931 struct rt_sigframe *frame;
934 frame_addr = get_sigframe(ka, env, sizeof(*frame));
936 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
939 err |= __put_user(current_exec_domain_sig(sig),
941 addr = frame_addr + offsetof(struct rt_sigframe, info);
942 err |= __put_user(addr, &frame->pinfo);
943 addr = frame_addr + offsetof(struct rt_sigframe, uc);
944 err |= __put_user(addr, &frame->puc);
945 err |= copy_siginfo_to_user(&frame->info, info);
949 /* Create the ucontext. */
950 err |= __put_user(0, &frame->uc.tuc_flags);
951 err |= __put_user(0, &frame->uc.tuc_link);
952 err |= __put_user(target_sigaltstack_used.ss_sp,
953 &frame->uc.tuc_stack.ss_sp);
954 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
955 &frame->uc.tuc_stack.ss_flags);
956 err |= __put_user(target_sigaltstack_used.ss_size,
957 &frame->uc.tuc_stack.ss_size);
958 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
960 frame_addr + offsetof(struct rt_sigframe, fpstate));
961 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
962 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
966 /* Set up to return from userspace. If provided, use a stub
967 already in userspace. */
968 if (ka->sa_flags & TARGET_SA_RESTORER) {
969 err |= __put_user(ka->sa_restorer, &frame->pretcode);
972 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
973 err |= __put_user(addr, &frame->pretcode);
974 /* This is movl $,%eax ; int $0x80 */
975 err |= __put_user(0xb8, (char *)(frame->retcode+0));
976 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
978 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
984 /* Set up registers for signal handler */
985 env->regs[R_ESP] = frame_addr;
986 env->eip = ka->_sa_handler;
988 cpu_x86_load_seg(env, R_DS, __USER_DS);
989 cpu_x86_load_seg(env, R_ES, __USER_DS);
990 cpu_x86_load_seg(env, R_SS, __USER_DS);
991 cpu_x86_load_seg(env, R_CS, __USER_CS);
992 env->eflags &= ~TF_MASK;
994 unlock_user_struct(frame, frame_addr, 1);
999 unlock_user_struct(frame, frame_addr, 1);
1000 if (sig == TARGET_SIGSEGV)
1001 ka->_sa_handler = TARGET_SIG_DFL;
1002 force_sig(TARGET_SIGSEGV /* , current */);
1006 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
1008 unsigned int err = 0;
1009 abi_ulong fpstate_addr;
1010 unsigned int tmpflags;
1012 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
1013 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
1014 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
1015 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
1017 env->regs[R_EDI] = tswapl(sc->edi);
1018 env->regs[R_ESI] = tswapl(sc->esi);
1019 env->regs[R_EBP] = tswapl(sc->ebp);
1020 env->regs[R_ESP] = tswapl(sc->esp);
1021 env->regs[R_EBX] = tswapl(sc->ebx);
1022 env->regs[R_EDX] = tswapl(sc->edx);
1023 env->regs[R_ECX] = tswapl(sc->ecx);
1024 env->eip = tswapl(sc->eip);
1026 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
1027 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
1029 tmpflags = tswapl(sc->eflags);
1030 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1031 // regs->orig_eax = -1; /* disable syscall checks */
1033 fpstate_addr = tswapl(sc->fpstate);
1034 if (fpstate_addr != 0) {
1035 if (!access_ok(VERIFY_READ, fpstate_addr,
1036 sizeof(struct target_fpstate)))
1038 cpu_x86_frstor(env, fpstate_addr, 1);
1041 *peax = tswapl(sc->eax);
1047 long do_sigreturn(CPUX86State *env)
1049 struct sigframe *frame;
1050 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1051 target_sigset_t target_set;
1055 #if defined(DEBUG_SIGNAL)
1056 fprintf(stderr, "do_sigreturn\n");
1058 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1060 /* set blocked signals */
1061 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1063 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1064 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1068 target_to_host_sigset_internal(&set, &target_set);
1069 do_sigprocmask(SIG_SETMASK, &set, NULL);
1071 /* restore registers */
1072 if (restore_sigcontext(env, &frame->sc, &eax))
1074 unlock_user_struct(frame, frame_addr, 0);
1078 unlock_user_struct(frame, frame_addr, 0);
1079 force_sig(TARGET_SIGSEGV);
1083 long do_rt_sigreturn(CPUX86State *env)
1085 abi_ulong frame_addr;
1086 struct rt_sigframe *frame;
1090 frame_addr = env->regs[R_ESP] - 4;
1091 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1093 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1094 do_sigprocmask(SIG_SETMASK, &set, NULL);
1096 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1099 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1100 get_sp_from_cpustate(env)) == -EFAULT)
1103 unlock_user_struct(frame, frame_addr, 0);
1107 unlock_user_struct(frame, frame_addr, 0);
1108 force_sig(TARGET_SIGSEGV);
1112 #elif defined(TARGET_AARCH64)
1114 struct target_sigcontext {
1115 uint64_t fault_address;
1116 /* AArch64 registers */
1121 /* 4K reserved for FP/SIMD state and future expansion */
1122 char __reserved[4096] __attribute__((__aligned__(16)));
1125 struct target_ucontext {
1126 abi_ulong tuc_flags;
1128 target_stack_t tuc_stack;
1129 target_sigset_t tuc_sigmask;
1130 /* glibc uses a 1024-bit sigset_t */
1131 char __unused[1024 / 8 - sizeof(target_sigset_t)];
1132 /* last for future expansion */
1133 struct target_sigcontext tuc_mcontext;
1137 * Header to be used at the beginning of structures extending the user
1138 * context. Such structures must be placed after the rt_sigframe on the stack
1139 * and be 16-byte aligned. The last structure must be a dummy one with the
1140 * magic and size set to 0.
1142 struct target_aarch64_ctx {
1147 #define TARGET_FPSIMD_MAGIC 0x46508001
1149 struct target_fpsimd_context {
1150 struct target_aarch64_ctx head;
1153 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
1157 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1158 * user space as it will change with the addition of new context. User space
1159 * should check the magic/size information.
1161 struct target_aux_context {
1162 struct target_fpsimd_context fpsimd;
1163 /* additional context to be added before "end" */
1164 struct target_aarch64_ctx end;
1167 struct target_rt_sigframe {
1168 struct target_siginfo info;
1169 struct target_ucontext uc;
1175 static int target_setup_sigframe(struct target_rt_sigframe *sf,
1176 CPUARMState *env, target_sigset_t *set)
1179 struct target_aux_context *aux =
1180 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1182 /* set up the stack frame for unwinding */
1183 __put_user(env->xregs[29], &sf->fp);
1184 __put_user(env->xregs[30], &sf->lr);
1186 for (i = 0; i < 31; i++) {
1187 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1189 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1190 __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
1191 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
1193 __put_user(/*current->thread.fault_address*/ 0,
1194 &sf->uc.tuc_mcontext.fault_address);
1196 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
1197 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
1200 for (i = 0; i < 32; i++) {
1201 #ifdef TARGET_WORDS_BIGENDIAN
1202 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1203 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1205 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1206 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1209 __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
1210 __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
1211 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
1212 __put_user(sizeof(struct target_fpsimd_context),
1213 &aux->fpsimd.head.size);
1215 /* set the "end" magic */
1216 __put_user(0, &aux->end.magic);
1217 __put_user(0, &aux->end.size);
1222 static int target_restore_sigframe(CPUARMState *env,
1223 struct target_rt_sigframe *sf)
1227 struct target_aux_context *aux =
1228 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1229 uint32_t magic, size, fpsr, fpcr;
1232 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1233 do_sigprocmask(SIG_SETMASK, &set, NULL);
1235 for (i = 0; i < 31; i++) {
1236 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1239 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1240 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
1241 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
1242 pstate_write(env, pstate);
1244 __get_user(magic, &aux->fpsimd.head.magic);
1245 __get_user(size, &aux->fpsimd.head.size);
1247 if (magic != TARGET_FPSIMD_MAGIC
1248 || size != sizeof(struct target_fpsimd_context)) {
1252 for (i = 0; i < 32; i++) {
1253 #ifdef TARGET_WORDS_BIGENDIAN
1254 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1255 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1257 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1258 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1261 __get_user(fpsr, &aux->fpsimd.fpsr);
1262 vfp_set_fpsr(env, fpsr);
1263 __get_user(fpcr, &aux->fpsimd.fpcr);
1264 vfp_set_fpcr(env, fpcr);
1269 static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1273 sp = env->xregs[31];
1276 * This is the X/Open sanctioned signal stack switching.
1278 if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
1279 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1282 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1287 static void target_setup_frame(int usig, struct target_sigaction *ka,
1288 target_siginfo_t *info, target_sigset_t *set,
1291 struct target_rt_sigframe *frame;
1292 abi_ulong frame_addr, return_addr;
1294 frame_addr = get_sigframe(ka, env);
1295 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1299 __put_user(0, &frame->uc.tuc_flags);
1300 __put_user(0, &frame->uc.tuc_link);
1302 __put_user(target_sigaltstack_used.ss_sp,
1303 &frame->uc.tuc_stack.ss_sp);
1304 __put_user(sas_ss_flags(env->xregs[31]),
1305 &frame->uc.tuc_stack.ss_flags);
1306 __put_user(target_sigaltstack_used.ss_size,
1307 &frame->uc.tuc_stack.ss_size);
1308 target_setup_sigframe(frame, env, set);
1309 if (ka->sa_flags & TARGET_SA_RESTORER) {
1310 return_addr = ka->sa_restorer;
1312 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1313 __put_user(0xd2801168, &frame->tramp[0]);
1314 __put_user(0xd4000001, &frame->tramp[1]);
1315 return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
1317 env->xregs[0] = usig;
1318 env->xregs[31] = frame_addr;
1319 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
1320 env->pc = ka->_sa_handler;
1321 env->xregs[30] = return_addr;
1323 if (copy_siginfo_to_user(&frame->info, info)) {
1326 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1327 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1330 unlock_user_struct(frame, frame_addr, 1);
1334 unlock_user_struct(frame, frame_addr, 1);
1335 force_sig(TARGET_SIGSEGV);
1338 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1339 target_siginfo_t *info, target_sigset_t *set,
1342 target_setup_frame(sig, ka, info, set, env);
1345 static void setup_frame(int sig, struct target_sigaction *ka,
1346 target_sigset_t *set, CPUARMState *env)
1348 target_setup_frame(sig, ka, 0, set, env);
1351 long do_rt_sigreturn(CPUARMState *env)
1353 struct target_rt_sigframe *frame = NULL;
1354 abi_ulong frame_addr = env->xregs[31];
1356 if (frame_addr & 15) {
1360 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1364 if (target_restore_sigframe(env, frame)) {
1368 if (do_sigaltstack(frame_addr +
1369 offsetof(struct target_rt_sigframe, uc.tuc_stack),
1370 0, get_sp_from_cpustate(env)) == -EFAULT) {
1374 unlock_user_struct(frame, frame_addr, 0);
1375 return env->xregs[0];
1378 unlock_user_struct(frame, frame_addr, 0);
1379 force_sig(TARGET_SIGSEGV);
1383 long do_sigreturn(CPUARMState *env)
1385 return do_rt_sigreturn(env);
1388 #elif defined(TARGET_ARM)
1390 struct target_sigcontext {
1392 abi_ulong error_code;
1411 abi_ulong fault_address;
1414 struct target_ucontext_v1 {
1415 abi_ulong tuc_flags;
1417 target_stack_t tuc_stack;
1418 struct target_sigcontext tuc_mcontext;
1419 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1422 struct target_ucontext_v2 {
1423 abi_ulong tuc_flags;
1425 target_stack_t tuc_stack;
1426 struct target_sigcontext tuc_mcontext;
1427 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1428 char __unused[128 - sizeof(target_sigset_t)];
1429 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1432 struct target_user_vfp {
1433 uint64_t fpregs[32];
1437 struct target_user_vfp_exc {
1443 struct target_vfp_sigframe {
1446 struct target_user_vfp ufp;
1447 struct target_user_vfp_exc ufp_exc;
1448 } __attribute__((__aligned__(8)));
1450 struct target_iwmmxt_sigframe {
1454 /* Note that not all the coprocessor control registers are stored here */
1461 } __attribute__((__aligned__(8)));
1463 #define TARGET_VFP_MAGIC 0x56465001
1464 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1468 struct target_sigcontext sc;
1469 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1475 struct target_ucontext_v2 uc;
1479 struct rt_sigframe_v1
1483 struct target_siginfo info;
1484 struct target_ucontext_v1 uc;
1488 struct rt_sigframe_v2
1490 struct target_siginfo info;
1491 struct target_ucontext_v2 uc;
1495 #define TARGET_CONFIG_CPU_32 1
1498 * For ARM syscalls, we encode the syscall number into the instruction.
1500 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1501 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1504 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1505 * need two 16-bit instructions.
1507 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1508 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1510 static const abi_ulong retcodes[4] = {
1511 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1512 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1516 #define __get_user_error(x,p,e) __get_user(x, p)
1518 static inline int valid_user_regs(CPUARMState *regs)
1524 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1525 CPUARMState *env, abi_ulong mask)
1527 __put_user(env->regs[0], &sc->arm_r0);
1528 __put_user(env->regs[1], &sc->arm_r1);
1529 __put_user(env->regs[2], &sc->arm_r2);
1530 __put_user(env->regs[3], &sc->arm_r3);
1531 __put_user(env->regs[4], &sc->arm_r4);
1532 __put_user(env->regs[5], &sc->arm_r5);
1533 __put_user(env->regs[6], &sc->arm_r6);
1534 __put_user(env->regs[7], &sc->arm_r7);
1535 __put_user(env->regs[8], &sc->arm_r8);
1536 __put_user(env->regs[9], &sc->arm_r9);
1537 __put_user(env->regs[10], &sc->arm_r10);
1538 __put_user(env->regs[11], &sc->arm_fp);
1539 __put_user(env->regs[12], &sc->arm_ip);
1540 __put_user(env->regs[13], &sc->arm_sp);
1541 __put_user(env->regs[14], &sc->arm_lr);
1542 __put_user(env->regs[15], &sc->arm_pc);
1543 #ifdef TARGET_CONFIG_CPU_32
1544 __put_user(cpsr_read(env), &sc->arm_cpsr);
1547 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1548 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1549 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1550 __put_user(mask, &sc->oldmask);
1553 static inline abi_ulong
1554 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1556 unsigned long sp = regs->regs[13];
1559 * This is the X/Open sanctioned signal stack switching.
1561 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1562 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1564 * ATPCS B01 mandates 8-byte alignment
1566 return (sp - framesize) & ~7;
1570 setup_return(CPUARMState *env, struct target_sigaction *ka,
1571 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1573 abi_ulong handler = ka->_sa_handler;
1575 int thumb = handler & 1;
1576 uint32_t cpsr = cpsr_read(env);
1585 if (ka->sa_flags & TARGET_SA_RESTORER) {
1586 retcode = ka->sa_restorer;
1588 unsigned int idx = thumb;
1590 if (ka->sa_flags & TARGET_SA_SIGINFO)
1593 if (__put_user(retcodes[idx], rc))
1596 retcode = rc_addr + thumb;
1599 env->regs[0] = usig;
1600 env->regs[13] = frame_addr;
1601 env->regs[14] = retcode;
1602 env->regs[15] = handler & (thumb ? ~1 : ~3);
1603 cpsr_write(env, cpsr, 0xffffffff);
1608 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1611 struct target_vfp_sigframe *vfpframe;
1612 vfpframe = (struct target_vfp_sigframe *)regspace;
1613 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1614 __put_user(sizeof(*vfpframe), &vfpframe->size);
1615 for (i = 0; i < 32; i++) {
1616 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1618 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1619 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1620 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1621 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1622 return (abi_ulong*)(vfpframe+1);
1625 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1629 struct target_iwmmxt_sigframe *iwmmxtframe;
1630 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1631 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1632 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1633 for (i = 0; i < 16; i++) {
1634 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1636 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1637 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1638 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1639 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1640 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1641 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1642 return (abi_ulong*)(iwmmxtframe+1);
1645 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1646 target_sigset_t *set, CPUARMState *env)
1648 struct target_sigaltstack stack;
1650 abi_ulong *regspace;
1652 /* Clear all the bits of the ucontext we don't use. */
1653 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1655 memset(&stack, 0, sizeof(stack));
1656 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1657 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1658 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1659 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1661 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1662 /* Save coprocessor signal frame. */
1663 regspace = uc->tuc_regspace;
1664 if (arm_feature(env, ARM_FEATURE_VFP)) {
1665 regspace = setup_sigframe_v2_vfp(regspace, env);
1667 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1668 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1671 /* Write terminating magic word */
1672 __put_user(0, regspace);
1674 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1675 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1679 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1680 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1681 target_sigset_t *set, CPUARMState *regs)
1683 struct sigframe_v1 *frame;
1684 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1687 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1690 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1692 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1693 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1697 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1698 frame_addr + offsetof(struct sigframe_v1, retcode));
1701 unlock_user_struct(frame, frame_addr, 1);
1704 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1705 target_sigset_t *set, CPUARMState *regs)
1707 struct sigframe_v2 *frame;
1708 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1710 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1713 setup_sigframe_v2(&frame->uc, set, regs);
1715 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1716 frame_addr + offsetof(struct sigframe_v2, retcode));
1718 unlock_user_struct(frame, frame_addr, 1);
1721 static void setup_frame(int usig, struct target_sigaction *ka,
1722 target_sigset_t *set, CPUARMState *regs)
1724 if (get_osversion() >= 0x020612) {
1725 setup_frame_v2(usig, ka, set, regs);
1727 setup_frame_v1(usig, ka, set, regs);
1731 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1732 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1733 target_siginfo_t *info,
1734 target_sigset_t *set, CPUARMState *env)
1736 struct rt_sigframe_v1 *frame;
1737 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1738 struct target_sigaltstack stack;
1740 abi_ulong info_addr, uc_addr;
1742 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1745 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1746 __put_user(info_addr, &frame->pinfo);
1747 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1748 __put_user(uc_addr, &frame->puc);
1749 copy_siginfo_to_user(&frame->info, info);
1751 /* Clear all the bits of the ucontext we don't use. */
1752 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1754 memset(&stack, 0, sizeof(stack));
1755 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1756 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1757 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1758 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1760 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1761 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1762 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1766 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1767 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1769 env->regs[1] = info_addr;
1770 env->regs[2] = uc_addr;
1773 unlock_user_struct(frame, frame_addr, 1);
1776 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1777 target_siginfo_t *info,
1778 target_sigset_t *set, CPUARMState *env)
1780 struct rt_sigframe_v2 *frame;
1781 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1782 abi_ulong info_addr, uc_addr;
1784 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1787 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1788 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1789 copy_siginfo_to_user(&frame->info, info);
1791 setup_sigframe_v2(&frame->uc, set, env);
1793 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1794 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1796 env->regs[1] = info_addr;
1797 env->regs[2] = uc_addr;
1799 unlock_user_struct(frame, frame_addr, 1);
1802 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1803 target_siginfo_t *info,
1804 target_sigset_t *set, CPUARMState *env)
1806 if (get_osversion() >= 0x020612) {
1807 setup_rt_frame_v2(usig, ka, info, set, env);
1809 setup_rt_frame_v1(usig, ka, info, set, env);
1814 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1819 __get_user_error(env->regs[0], &sc->arm_r0, err);
1820 __get_user_error(env->regs[1], &sc->arm_r1, err);
1821 __get_user_error(env->regs[2], &sc->arm_r2, err);
1822 __get_user_error(env->regs[3], &sc->arm_r3, err);
1823 __get_user_error(env->regs[4], &sc->arm_r4, err);
1824 __get_user_error(env->regs[5], &sc->arm_r5, err);
1825 __get_user_error(env->regs[6], &sc->arm_r6, err);
1826 __get_user_error(env->regs[7], &sc->arm_r7, err);
1827 __get_user_error(env->regs[8], &sc->arm_r8, err);
1828 __get_user_error(env->regs[9], &sc->arm_r9, err);
1829 __get_user_error(env->regs[10], &sc->arm_r10, err);
1830 __get_user_error(env->regs[11], &sc->arm_fp, err);
1831 __get_user_error(env->regs[12], &sc->arm_ip, err);
1832 __get_user_error(env->regs[13], &sc->arm_sp, err);
1833 __get_user_error(env->regs[14], &sc->arm_lr, err);
1834 __get_user_error(env->regs[15], &sc->arm_pc, err);
1835 #ifdef TARGET_CONFIG_CPU_32
1836 __get_user_error(cpsr, &sc->arm_cpsr, err);
1837 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1840 err |= !valid_user_regs(env);
1845 static long do_sigreturn_v1(CPUARMState *env)
1847 abi_ulong frame_addr;
1848 struct sigframe_v1 *frame = NULL;
1849 target_sigset_t set;
1854 * Since we stacked the signal on a 64-bit boundary,
1855 * then 'sp' should be word aligned here. If it's
1856 * not, then the user is trying to mess with us.
1858 frame_addr = env->regs[13];
1859 if (frame_addr & 7) {
1863 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1866 if (__get_user(set.sig[0], &frame->sc.oldmask))
1868 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1869 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1873 target_to_host_sigset_internal(&host_set, &set);
1874 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
1876 if (restore_sigcontext(env, &frame->sc))
1880 /* Send SIGTRAP if we're single-stepping */
1881 if (ptrace_cancel_bpt(current))
1882 send_sig(SIGTRAP, current, 1);
1884 unlock_user_struct(frame, frame_addr, 0);
1885 return env->regs[0];
1888 unlock_user_struct(frame, frame_addr, 0);
1889 force_sig(TARGET_SIGSEGV /* , current */);
1893 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1896 abi_ulong magic, sz;
1897 uint32_t fpscr, fpexc;
1898 struct target_vfp_sigframe *vfpframe;
1899 vfpframe = (struct target_vfp_sigframe *)regspace;
1901 __get_user(magic, &vfpframe->magic);
1902 __get_user(sz, &vfpframe->size);
1903 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1906 for (i = 0; i < 32; i++) {
1907 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1909 __get_user(fpscr, &vfpframe->ufp.fpscr);
1910 vfp_set_fpscr(env, fpscr);
1911 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1912 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1913 * and the exception flag is cleared
1916 fpexc &= ~((1 << 31) | (1 << 28));
1917 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1918 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1919 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1920 return (abi_ulong*)(vfpframe + 1);
1923 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1924 abi_ulong *regspace)
1927 abi_ulong magic, sz;
1928 struct target_iwmmxt_sigframe *iwmmxtframe;
1929 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1931 __get_user(magic, &iwmmxtframe->magic);
1932 __get_user(sz, &iwmmxtframe->size);
1933 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1936 for (i = 0; i < 16; i++) {
1937 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1939 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1940 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1941 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1942 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1943 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1944 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1945 return (abi_ulong*)(iwmmxtframe + 1);
1948 static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1949 struct target_ucontext_v2 *uc)
1952 abi_ulong *regspace;
1954 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1955 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
1957 if (restore_sigcontext(env, &uc->tuc_mcontext))
1960 /* Restore coprocessor signal frame */
1961 regspace = uc->tuc_regspace;
1962 if (arm_feature(env, ARM_FEATURE_VFP)) {
1963 regspace = restore_sigframe_v2_vfp(env, regspace);
1968 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1969 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1975 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1979 /* Send SIGTRAP if we're single-stepping */
1980 if (ptrace_cancel_bpt(current))
1981 send_sig(SIGTRAP, current, 1);
1987 static long do_sigreturn_v2(CPUARMState *env)
1989 abi_ulong frame_addr;
1990 struct sigframe_v2 *frame = NULL;
1993 * Since we stacked the signal on a 64-bit boundary,
1994 * then 'sp' should be word aligned here. If it's
1995 * not, then the user is trying to mess with us.
1997 frame_addr = env->regs[13];
1998 if (frame_addr & 7) {
2002 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2005 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2008 unlock_user_struct(frame, frame_addr, 0);
2009 return env->regs[0];
2012 unlock_user_struct(frame, frame_addr, 0);
2013 force_sig(TARGET_SIGSEGV /* , current */);
2017 long do_sigreturn(CPUARMState *env)
2019 if (get_osversion() >= 0x020612) {
2020 return do_sigreturn_v2(env);
2022 return do_sigreturn_v1(env);
2026 static long do_rt_sigreturn_v1(CPUARMState *env)
2028 abi_ulong frame_addr;
2029 struct rt_sigframe_v1 *frame = NULL;
2033 * Since we stacked the signal on a 64-bit boundary,
2034 * then 'sp' should be word aligned here. If it's
2035 * not, then the user is trying to mess with us.
2037 frame_addr = env->regs[13];
2038 if (frame_addr & 7) {
2042 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2045 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2046 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
2048 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2051 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2055 /* Send SIGTRAP if we're single-stepping */
2056 if (ptrace_cancel_bpt(current))
2057 send_sig(SIGTRAP, current, 1);
2059 unlock_user_struct(frame, frame_addr, 0);
2060 return env->regs[0];
2063 unlock_user_struct(frame, frame_addr, 0);
2064 force_sig(TARGET_SIGSEGV /* , current */);
2068 static long do_rt_sigreturn_v2(CPUARMState *env)
2070 abi_ulong frame_addr;
2071 struct rt_sigframe_v2 *frame = NULL;
2074 * Since we stacked the signal on a 64-bit boundary,
2075 * then 'sp' should be word aligned here. If it's
2076 * not, then the user is trying to mess with us.
2078 frame_addr = env->regs[13];
2079 if (frame_addr & 7) {
2083 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2086 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2089 unlock_user_struct(frame, frame_addr, 0);
2090 return env->regs[0];
2093 unlock_user_struct(frame, frame_addr, 0);
2094 force_sig(TARGET_SIGSEGV /* , current */);
2098 long do_rt_sigreturn(CPUARMState *env)
2100 if (get_osversion() >= 0x020612) {
2101 return do_rt_sigreturn_v2(env);
2103 return do_rt_sigreturn_v1(env);
2107 #elif defined(TARGET_SPARC)
2109 #define __SUNOS_MAXWIN 31
2111 /* This is what SunOS does, so shall I. */
2112 struct target_sigcontext {
2113 abi_ulong sigc_onstack; /* state to restore */
2115 abi_ulong sigc_mask; /* sigmask to restore */
2116 abi_ulong sigc_sp; /* stack pointer */
2117 abi_ulong sigc_pc; /* program counter */
2118 abi_ulong sigc_npc; /* next program counter */
2119 abi_ulong sigc_psr; /* for condition codes etc */
2120 abi_ulong sigc_g1; /* User uses these two registers */
2121 abi_ulong sigc_o0; /* within the trampoline code. */
2123 /* Now comes information regarding the users window set
2124 * at the time of the signal.
2126 abi_ulong sigc_oswins; /* outstanding windows */
2128 /* stack ptrs for each regwin buf */
2129 char *sigc_spbuf[__SUNOS_MAXWIN];
2131 /* Windows to restore after signal */
2133 abi_ulong locals[8];
2135 } sigc_wbuf[__SUNOS_MAXWIN];
2137 /* A Sparc stack frame */
2138 struct sparc_stackf {
2139 abi_ulong locals[8];
2141 /* It's simpler to treat fp and callers_pc as elements of ins[]
2142 * since we never need to access them ourselves.
2146 abi_ulong xxargs[1];
2155 abi_ulong u_regs[16]; /* globals and ins */
2161 abi_ulong si_float_regs[32];
2162 unsigned long si_fsr;
2163 unsigned long si_fpqdepth;
2165 unsigned long *insn_addr;
2168 } qemu_siginfo_fpu_t;
2171 struct target_signal_frame {
2172 struct sparc_stackf ss;
2175 abi_ulong insns[2] __attribute__ ((aligned (8)));
2176 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
2177 abi_ulong extra_size; /* Should be 0 */
2178 qemu_siginfo_fpu_t fpu_state;
2180 struct target_rt_signal_frame {
2181 struct sparc_stackf ss;
2186 unsigned int insns[2];
2188 unsigned int extra_size; /* Should be 0 */
2189 qemu_siginfo_fpu_t fpu_state;
2203 #define UREG_FP UREG_I6
2204 #define UREG_SP UREG_O6
2206 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2208 unsigned long framesize)
2212 sp = env->regwptr[UREG_FP];
2214 /* This is the X/Open sanctioned signal stack switching. */
2215 if (sa->sa_flags & TARGET_SA_ONSTACK) {
2216 if (!on_sig_stack(sp)
2217 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2218 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2220 return sp - framesize;
2224 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2228 err |= __put_user(env->psr, &si->si_regs.psr);
2229 err |= __put_user(env->pc, &si->si_regs.pc);
2230 err |= __put_user(env->npc, &si->si_regs.npc);
2231 err |= __put_user(env->y, &si->si_regs.y);
2232 for (i=0; i < 8; i++) {
2233 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
2235 for (i=0; i < 8; i++) {
2236 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2238 err |= __put_user(mask, &si->si_mask);
2244 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2245 CPUSPARCState *env, unsigned long mask)
2249 err |= __put_user(mask, &sc->sigc_mask);
2250 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
2251 err |= __put_user(env->pc, &sc->sigc_pc);
2252 err |= __put_user(env->npc, &sc->sigc_npc);
2253 err |= __put_user(env->psr, &sc->sigc_psr);
2254 err |= __put_user(env->gregs[1], &sc->sigc_g1);
2255 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
2260 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2262 static void setup_frame(int sig, struct target_sigaction *ka,
2263 target_sigset_t *set, CPUSPARCState *env)
2266 struct target_signal_frame *sf;
2267 int sigframe_size, err, i;
2269 /* 1. Make sure everything is clean */
2270 //synchronize_user_stack();
2272 sigframe_size = NF_ALIGNEDSZ;
2273 sf_addr = get_sigframe(ka, env, sigframe_size);
2275 sf = lock_user(VERIFY_WRITE, sf_addr,
2276 sizeof(struct target_signal_frame), 0);
2280 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2282 if (invalid_frame_pointer(sf, sigframe_size))
2283 goto sigill_and_return;
2285 /* 2. Save the current process state */
2286 err = setup___siginfo(&sf->info, env, set->sig[0]);
2287 err |= __put_user(0, &sf->extra_size);
2289 //err |= save_fpu_state(regs, &sf->fpu_state);
2290 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
2292 err |= __put_user(set->sig[0], &sf->info.si_mask);
2293 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2294 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
2297 for (i = 0; i < 8; i++) {
2298 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2300 for (i = 0; i < 8; i++) {
2301 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
2306 /* 3. signal handler back-trampoline and parameters */
2307 env->regwptr[UREG_FP] = sf_addr;
2308 env->regwptr[UREG_I0] = sig;
2309 env->regwptr[UREG_I1] = sf_addr +
2310 offsetof(struct target_signal_frame, info);
2311 env->regwptr[UREG_I2] = sf_addr +
2312 offsetof(struct target_signal_frame, info);
2314 /* 4. signal handler */
2315 env->pc = ka->_sa_handler;
2316 env->npc = (env->pc + 4);
2317 /* 5. return to kernel instructions */
2318 if (ka->sa_restorer)
2319 env->regwptr[UREG_I7] = ka->sa_restorer;
2323 env->regwptr[UREG_I7] = sf_addr +
2324 offsetof(struct target_signal_frame, insns) - 2 * 4;
2326 /* mov __NR_sigreturn, %g1 */
2328 err |= __put_user(val32, &sf->insns[0]);
2332 err |= __put_user(val32, &sf->insns[1]);
2336 /* Flush instruction space. */
2337 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2340 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2344 force_sig(TARGET_SIGILL);
2347 //fprintf(stderr, "force_sig\n");
2348 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2349 force_sig(TARGET_SIGSEGV);
2352 restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2357 if (current->flags & PF_USEDFPU)
2358 regs->psr &= ~PSR_EF;
2360 if (current == last_task_used_math) {
2361 last_task_used_math = 0;
2362 regs->psr &= ~PSR_EF;
2365 current->used_math = 1;
2366 current->flags &= ~PF_USEDFPU;
2369 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2373 /* XXX: incorrect */
2374 err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],
2375 (sizeof(abi_ulong) * 32));
2376 err |= __get_user(env->fsr, &fpu->si_fsr);
2378 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2379 if (current->thread.fpqdepth != 0)
2380 err |= __copy_from_user(¤t->thread.fpqueue[0],
2381 &fpu->si_fpqueue[0],
2382 ((sizeof(unsigned long) +
2383 (sizeof(unsigned long *)))*16));
2389 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2390 target_siginfo_t *info,
2391 target_sigset_t *set, CPUSPARCState *env)
2393 fprintf(stderr, "setup_rt_frame: not implemented\n");
2396 long do_sigreturn(CPUSPARCState *env)
2399 struct target_signal_frame *sf;
2400 uint32_t up_psr, pc, npc;
2401 target_sigset_t set;
2405 sf_addr = env->regwptr[UREG_FP];
2406 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2409 fprintf(stderr, "sigreturn\n");
2410 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2412 //cpu_dump_state(env, stderr, fprintf, 0);
2414 /* 1. Make sure we are not getting garbage from the user */
2419 err = __get_user(pc, &sf->info.si_regs.pc);
2420 err |= __get_user(npc, &sf->info.si_regs.npc);
2425 /* 2. Restore the state */
2426 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2428 /* User can only change condition codes and FPU enabling in %psr. */
2429 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2430 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2434 err |= __get_user(env->y, &sf->info.si_regs.y);
2435 for (i=0; i < 8; i++) {
2436 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2438 for (i=0; i < 8; i++) {
2439 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2442 /* FIXME: implement FPU save/restore:
2443 * __get_user(fpu_save, &sf->fpu_save);
2445 * err |= restore_fpu_state(env, fpu_save);
2448 /* This is pretty much atomic, no amount locking would prevent
2449 * the races which exist anyways.
2451 err |= __get_user(set.sig[0], &sf->info.si_mask);
2452 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2453 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2456 target_to_host_sigset_internal(&host_set, &set);
2457 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
2461 unlock_user_struct(sf, sf_addr, 0);
2462 return env->regwptr[0];
2465 unlock_user_struct(sf, sf_addr, 0);
2466 force_sig(TARGET_SIGSEGV);
2469 long do_rt_sigreturn(CPUSPARCState *env)
2471 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2472 return -TARGET_ENOSYS;
2475 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2497 typedef abi_ulong target_mc_greg_t;
2498 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2500 struct target_mc_fq {
2501 abi_ulong *mcfq_addr;
2505 struct target_mc_fpu {
2509 //uint128_t qregs[16];
2511 abi_ulong mcfpu_fsr;
2512 abi_ulong mcfpu_fprs;
2513 abi_ulong mcfpu_gsr;
2514 struct target_mc_fq *mcfpu_fq;
2515 unsigned char mcfpu_qcnt;
2516 unsigned char mcfpu_qentsz;
2517 unsigned char mcfpu_enab;
2519 typedef struct target_mc_fpu target_mc_fpu_t;
2522 target_mc_gregset_t mc_gregs;
2523 target_mc_greg_t mc_fp;
2524 target_mc_greg_t mc_i7;
2525 target_mc_fpu_t mc_fpregs;
2526 } target_mcontext_t;
2528 struct target_ucontext {
2529 struct target_ucontext *tuc_link;
2530 abi_ulong tuc_flags;
2531 target_sigset_t tuc_sigmask;
2532 target_mcontext_t tuc_mcontext;
2535 /* A V9 register window */
2536 struct target_reg_window {
2537 abi_ulong locals[8];
2541 #define TARGET_STACK_BIAS 2047
2543 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2544 void sparc64_set_context(CPUSPARCState *env)
2547 struct target_ucontext *ucp;
2548 target_mc_gregset_t *grp;
2549 abi_ulong pc, npc, tstate;
2550 abi_ulong fp, i7, w_addr;
2554 ucp_addr = env->regwptr[UREG_I0];
2555 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2557 grp = &ucp->tuc_mcontext.mc_gregs;
2558 err = __get_user(pc, &((*grp)[MC_PC]));
2559 err |= __get_user(npc, &((*grp)[MC_NPC]));
2560 if (err || ((pc | npc) & 3))
2562 if (env->regwptr[UREG_I1]) {
2563 target_sigset_t target_set;
2566 if (TARGET_NSIG_WORDS == 1) {
2567 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2570 abi_ulong *src, *dst;
2571 src = ucp->tuc_sigmask.sig;
2572 dst = target_set.sig;
2573 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2574 err |= __get_user(*dst, src);
2579 target_to_host_sigset_internal(&set, &target_set);
2580 do_sigprocmask(SIG_SETMASK, &set, NULL);
2584 err |= __get_user(env->y, &((*grp)[MC_Y]));
2585 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2586 env->asi = (tstate >> 24) & 0xff;
2587 cpu_put_ccr(env, tstate >> 32);
2588 cpu_put_cwp64(env, tstate & 0x1f);
2589 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2590 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2591 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2592 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2593 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2594 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2595 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2596 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2597 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2598 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2599 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2600 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2601 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2602 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2603 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2605 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2606 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2608 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2609 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2612 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2615 /* FIXME this does not match how the kernel handles the FPU in
2616 * its sparc64_set_context implementation. In particular the FPU
2617 * is only restored if fenab is non-zero in:
2618 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2620 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2622 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2623 for (i = 0; i < 64; i++, src++) {
2625 err |= __get_user(env->fpr[i/2].l.lower, src);
2627 err |= __get_user(env->fpr[i/2].l.upper, src);
2631 err |= __get_user(env->fsr,
2632 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2633 err |= __get_user(env->gsr,
2634 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2637 unlock_user_struct(ucp, ucp_addr, 0);
2640 unlock_user_struct(ucp, ucp_addr, 0);
2641 force_sig(TARGET_SIGSEGV);
2644 void sparc64_get_context(CPUSPARCState *env)
2647 struct target_ucontext *ucp;
2648 target_mc_gregset_t *grp;
2649 target_mcontext_t *mcp;
2650 abi_ulong fp, i7, w_addr;
2653 target_sigset_t target_set;
2656 ucp_addr = env->regwptr[UREG_I0];
2657 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2660 mcp = &ucp->tuc_mcontext;
2661 grp = &mcp->mc_gregs;
2663 /* Skip over the trap instruction, first. */
2669 do_sigprocmask(0, NULL, &set);
2670 host_to_target_sigset_internal(&target_set, &set);
2671 if (TARGET_NSIG_WORDS == 1) {
2672 err |= __put_user(target_set.sig[0],
2673 (abi_ulong *)&ucp->tuc_sigmask);
2675 abi_ulong *src, *dst;
2676 src = target_set.sig;
2677 dst = ucp->tuc_sigmask.sig;
2678 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2679 err |= __put_user(*src, dst);
2685 /* XXX: tstate must be saved properly */
2686 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2687 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2688 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2689 err |= __put_user(env->y, &((*grp)[MC_Y]));
2690 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2691 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2692 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2693 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2694 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2695 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2696 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2697 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2698 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2699 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2700 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2701 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2702 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2703 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2704 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2706 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2708 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2711 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2714 err |= __put_user(fp, &(mcp->mc_fp));
2715 err |= __put_user(i7, &(mcp->mc_i7));
2718 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2719 for (i = 0; i < 64; i++, dst++) {
2721 err |= __put_user(env->fpr[i/2].l.lower, dst);
2723 err |= __put_user(env->fpr[i/2].l.upper, dst);
2727 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2728 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2729 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2733 unlock_user_struct(ucp, ucp_addr, 1);
2736 unlock_user_struct(ucp, ucp_addr, 1);
2737 force_sig(TARGET_SIGSEGV);
2740 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2742 # if defined(TARGET_ABI_MIPSO32)
2743 struct target_sigcontext {
2744 uint32_t sc_regmask; /* Unused */
2747 uint64_t sc_regs[32];
2748 uint64_t sc_fpregs[32];
2749 uint32_t sc_ownedfp; /* Unused */
2750 uint32_t sc_fpc_csr;
2751 uint32_t sc_fpc_eir; /* Unused */
2752 uint32_t sc_used_math;
2753 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2757 target_ulong sc_hi1; /* Was sc_cause */
2758 target_ulong sc_lo1; /* Was sc_badvaddr */
2759 target_ulong sc_hi2; /* Was sc_sigset[4] */
2760 target_ulong sc_lo2;
2761 target_ulong sc_hi3;
2762 target_ulong sc_lo3;
2764 # else /* N32 || N64 */
2765 struct target_sigcontext {
2766 uint64_t sc_regs[32];
2767 uint64_t sc_fpregs[32];
2777 uint32_t sc_fpc_csr;
2778 uint32_t sc_used_math;
2780 uint32_t sc_reserved;
2785 uint32_t sf_ass[4]; /* argument save space for o32 */
2786 uint32_t sf_code[2]; /* signal trampoline */
2787 struct target_sigcontext sf_sc;
2788 target_sigset_t sf_mask;
2791 struct target_ucontext {
2792 target_ulong tuc_flags;
2793 target_ulong tuc_link;
2794 target_stack_t tuc_stack;
2796 struct target_sigcontext tuc_mcontext;
2797 target_sigset_t tuc_sigmask;
2800 struct target_rt_sigframe {
2801 uint32_t rs_ass[4]; /* argument save space for o32 */
2802 uint32_t rs_code[2]; /* signal trampoline */
2803 struct target_siginfo rs_info;
2804 struct target_ucontext rs_uc;
2807 /* Install trampoline to jump back from signal handler */
2808 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2813 * Set up the return code ...
2815 * li v0, __NR__foo_sigreturn
2819 err |= __put_user(0x24020000 + syscall, tramp + 0);
2820 err |= __put_user(0x0000000c , tramp + 1);
2825 setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2830 err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
2831 regs->hflags &= ~MIPS_HFLAG_BMASK;
2833 __put_user(0, &sc->sc_regs[0]);
2834 for (i = 1; i < 32; ++i) {
2835 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2838 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2839 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2841 /* Rather than checking for dsp existence, always copy. The storage
2842 would just be garbage otherwise. */
2843 err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
2844 err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
2845 err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
2846 err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
2847 err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
2848 err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
2850 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2851 err |= __put_user(dsp, &sc->sc_dsp);
2854 err |= __put_user(1, &sc->sc_used_math);
2856 for (i = 0; i < 32; ++i) {
2857 err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2864 restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2869 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2871 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2872 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2874 for (i = 1; i < 32; ++i) {
2875 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2878 err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
2879 err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
2880 err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
2881 err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
2882 err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
2883 err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
2886 err |= __get_user(dsp, &sc->sc_dsp);
2887 cpu_wrdsp(dsp, 0x3ff, regs);
2890 for (i = 0; i < 32; ++i) {
2891 err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2898 * Determine which stack to use..
2900 static inline abi_ulong
2901 get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2905 /* Default to using normal stack */
2906 sp = regs->active_tc.gpr[29];
2909 * FPU emulator may have its own trampoline active just
2910 * above the user stack, 16-bytes before the next lowest
2911 * 16 byte boundary. Try to avoid trashing it.
2915 /* This is the X/Open sanctioned signal stack switching. */
2916 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2917 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2920 return (sp - frame_size) & ~7;
2923 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2925 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2926 env->hflags &= ~MIPS_HFLAG_M16;
2927 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2928 env->active_tc.PC &= ~(target_ulong) 1;
2932 # if defined(TARGET_ABI_MIPSO32)
2933 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2934 static void setup_frame(int sig, struct target_sigaction * ka,
2935 target_sigset_t *set, CPUMIPSState *regs)
2937 struct sigframe *frame;
2938 abi_ulong frame_addr;
2941 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2942 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2945 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2947 if(setup_sigcontext(regs, &frame->sf_sc))
2950 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2951 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2956 * Arguments to signal handler:
2958 * a0 = signal number
2959 * a1 = 0 (should be cause)
2960 * a2 = pointer to struct sigcontext
2962 * $25 and PC point to the signal handler, $29 points to the
2965 regs->active_tc.gpr[ 4] = sig;
2966 regs->active_tc.gpr[ 5] = 0;
2967 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2968 regs->active_tc.gpr[29] = frame_addr;
2969 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2970 /* The original kernel code sets CP0_EPC to the handler
2971 * since it returns to userland using eret
2972 * we cannot do this here, and we must set PC directly */
2973 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2974 mips_set_hflags_isa_mode_from_pc(regs);
2975 unlock_user_struct(frame, frame_addr, 1);
2979 unlock_user_struct(frame, frame_addr, 1);
2980 force_sig(TARGET_SIGSEGV/*, current*/);
2983 long do_sigreturn(CPUMIPSState *regs)
2985 struct sigframe *frame;
2986 abi_ulong frame_addr;
2988 target_sigset_t target_set;
2991 #if defined(DEBUG_SIGNAL)
2992 fprintf(stderr, "do_sigreturn\n");
2994 frame_addr = regs->active_tc.gpr[29];
2995 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2998 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2999 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
3003 target_to_host_sigset_internal(&blocked, &target_set);
3004 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3006 if (restore_sigcontext(regs, &frame->sf_sc))
3011 * Don't let your children do this ...
3013 __asm__ __volatile__(
3021 regs->active_tc.PC = regs->CP0_EPC;
3022 mips_set_hflags_isa_mode_from_pc(regs);
3023 /* I am not sure this is right, but it seems to work
3024 * maybe a problem with nested signals ? */
3026 return -TARGET_QEMU_ESIGRETURN;
3029 force_sig(TARGET_SIGSEGV/*, current*/);
3034 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3035 target_siginfo_t *info,
3036 target_sigset_t *set, CPUMIPSState *env)
3038 struct target_rt_sigframe *frame;
3039 abi_ulong frame_addr;
3042 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3043 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3046 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3048 copy_siginfo_to_user(&frame->rs_info, info);
3050 __put_user(0, &frame->rs_uc.tuc_flags);
3051 __put_user(0, &frame->rs_uc.tuc_link);
3052 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
3053 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
3054 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3055 &frame->rs_uc.tuc_stack.ss_flags);
3057 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3059 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3060 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3064 * Arguments to signal handler:
3066 * a0 = signal number
3067 * a1 = pointer to siginfo_t
3068 * a2 = pointer to struct ucontext
3070 * $25 and PC point to the signal handler, $29 points to the
3073 env->active_tc.gpr[ 4] = sig;
3074 env->active_tc.gpr[ 5] = frame_addr
3075 + offsetof(struct target_rt_sigframe, rs_info);
3076 env->active_tc.gpr[ 6] = frame_addr
3077 + offsetof(struct target_rt_sigframe, rs_uc);
3078 env->active_tc.gpr[29] = frame_addr;
3079 env->active_tc.gpr[31] = frame_addr
3080 + offsetof(struct target_rt_sigframe, rs_code);
3081 /* The original kernel code sets CP0_EPC to the handler
3082 * since it returns to userland using eret
3083 * we cannot do this here, and we must set PC directly */
3084 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3085 mips_set_hflags_isa_mode_from_pc(env);
3086 unlock_user_struct(frame, frame_addr, 1);
3090 unlock_user_struct(frame, frame_addr, 1);
3091 force_sig(TARGET_SIGSEGV/*, current*/);
3094 long do_rt_sigreturn(CPUMIPSState *env)
3096 struct target_rt_sigframe *frame;
3097 abi_ulong frame_addr;
3100 #if defined(DEBUG_SIGNAL)
3101 fprintf(stderr, "do_rt_sigreturn\n");
3103 frame_addr = env->active_tc.gpr[29];
3104 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3107 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3108 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3110 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
3113 if (do_sigaltstack(frame_addr +
3114 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3115 0, get_sp_from_cpustate(env)) == -EFAULT)
3118 env->active_tc.PC = env->CP0_EPC;
3119 mips_set_hflags_isa_mode_from_pc(env);
3120 /* I am not sure this is right, but it seems to work
3121 * maybe a problem with nested signals ? */
3123 return -TARGET_QEMU_ESIGRETURN;
3126 force_sig(TARGET_SIGSEGV/*, current*/);
3130 #elif defined(TARGET_SH4)
3133 * code and data structures from linux kernel:
3134 * include/asm-sh/sigcontext.h
3135 * arch/sh/kernel/signal.c
3138 struct target_sigcontext {
3139 target_ulong oldmask;
3142 target_ulong sc_gregs[16];
3146 target_ulong sc_gbr;
3147 target_ulong sc_mach;
3148 target_ulong sc_macl;
3151 target_ulong sc_fpregs[16];
3152 target_ulong sc_xfpregs[16];
3153 unsigned int sc_fpscr;
3154 unsigned int sc_fpul;
3155 unsigned int sc_ownedfp;
3158 struct target_sigframe
3160 struct target_sigcontext sc;
3161 target_ulong extramask[TARGET_NSIG_WORDS-1];
3162 uint16_t retcode[3];
3166 struct target_ucontext {
3167 target_ulong tuc_flags;
3168 struct target_ucontext *tuc_link;
3169 target_stack_t tuc_stack;
3170 struct target_sigcontext tuc_mcontext;
3171 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3174 struct target_rt_sigframe
3176 struct target_siginfo info;
3177 struct target_ucontext uc;
3178 uint16_t retcode[3];
3182 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3183 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3185 static abi_ulong get_sigframe(struct target_sigaction *ka,
3186 unsigned long sp, size_t frame_size)
3188 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
3189 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3192 return (sp - frame_size) & -8ul;
3195 static int setup_sigcontext(struct target_sigcontext *sc,
3196 CPUSH4State *regs, unsigned long mask)
3201 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
3202 COPY(gregs[0]); COPY(gregs[1]);
3203 COPY(gregs[2]); COPY(gregs[3]);
3204 COPY(gregs[4]); COPY(gregs[5]);
3205 COPY(gregs[6]); COPY(gregs[7]);
3206 COPY(gregs[8]); COPY(gregs[9]);
3207 COPY(gregs[10]); COPY(gregs[11]);
3208 COPY(gregs[12]); COPY(gregs[13]);
3209 COPY(gregs[14]); COPY(gregs[15]);
3210 COPY(gbr); COPY(mach);
3211 COPY(macl); COPY(pr);
3215 for (i=0; i<16; i++) {
3216 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3218 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
3219 err |= __put_user(regs->fpul, &sc->sc_fpul);
3221 /* non-iBCS2 extensions.. */
3222 err |= __put_user(mask, &sc->oldmask);
3227 static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3230 unsigned int err = 0;
3233 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3235 COPY(gregs[2]); COPY(gregs[3]);
3236 COPY(gregs[4]); COPY(gregs[5]);
3237 COPY(gregs[6]); COPY(gregs[7]);
3238 COPY(gregs[8]); COPY(gregs[9]);
3239 COPY(gregs[10]); COPY(gregs[11]);
3240 COPY(gregs[12]); COPY(gregs[13]);
3241 COPY(gregs[14]); COPY(gregs[15]);
3242 COPY(gbr); COPY(mach);
3243 COPY(macl); COPY(pr);
3247 for (i=0; i<16; i++) {
3248 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3250 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3251 err |= __get_user(regs->fpul, &sc->sc_fpul);
3253 regs->tra = -1; /* disable syscall checks */
3254 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3258 static void setup_frame(int sig, struct target_sigaction *ka,
3259 target_sigset_t *set, CPUSH4State *regs)
3261 struct target_sigframe *frame;
3262 abi_ulong frame_addr;
3267 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3268 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3271 signal = current_exec_domain_sig(sig);
3273 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3275 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3276 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3279 /* Set up to return from userspace. If provided, use a stub
3280 already in userspace. */
3281 if (ka->sa_flags & TARGET_SA_RESTORER) {
3282 regs->pr = (unsigned long) ka->sa_restorer;
3284 /* Generate return code (system call to sigreturn) */
3285 err |= __put_user(MOVW(2), &frame->retcode[0]);
3286 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3287 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3288 regs->pr = (unsigned long) frame->retcode;
3294 /* Set up registers for signal handler */
3295 regs->gregs[15] = frame_addr;
3296 regs->gregs[4] = signal; /* Arg for signal handler */
3298 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3299 regs->pc = (unsigned long) ka->_sa_handler;
3301 unlock_user_struct(frame, frame_addr, 1);
3305 unlock_user_struct(frame, frame_addr, 1);
3306 force_sig(TARGET_SIGSEGV);
3309 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3310 target_siginfo_t *info,
3311 target_sigset_t *set, CPUSH4State *regs)
3313 struct target_rt_sigframe *frame;
3314 abi_ulong frame_addr;
3319 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3320 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3323 signal = current_exec_domain_sig(sig);
3325 err |= copy_siginfo_to_user(&frame->info, info);
3327 /* Create the ucontext. */
3328 err |= __put_user(0, &frame->uc.tuc_flags);
3329 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3330 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3331 &frame->uc.tuc_stack.ss_sp);
3332 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3333 &frame->uc.tuc_stack.ss_flags);
3334 err |= __put_user(target_sigaltstack_used.ss_size,
3335 &frame->uc.tuc_stack.ss_size);
3336 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3338 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3339 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3342 /* Set up to return from userspace. If provided, use a stub
3343 already in userspace. */
3344 if (ka->sa_flags & TARGET_SA_RESTORER) {
3345 regs->pr = (unsigned long) ka->sa_restorer;
3347 /* Generate return code (system call to sigreturn) */
3348 err |= __put_user(MOVW(2), &frame->retcode[0]);
3349 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3350 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3351 regs->pr = (unsigned long) frame->retcode;
3357 /* Set up registers for signal handler */
3358 regs->gregs[15] = frame_addr;
3359 regs->gregs[4] = signal; /* Arg for signal handler */
3360 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3361 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3362 regs->pc = (unsigned long) ka->_sa_handler;
3364 unlock_user_struct(frame, frame_addr, 1);
3368 unlock_user_struct(frame, frame_addr, 1);
3369 force_sig(TARGET_SIGSEGV);
3372 long do_sigreturn(CPUSH4State *regs)
3374 struct target_sigframe *frame;
3375 abi_ulong frame_addr;
3377 target_sigset_t target_set;
3382 #if defined(DEBUG_SIGNAL)
3383 fprintf(stderr, "do_sigreturn\n");
3385 frame_addr = regs->gregs[15];
3386 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3389 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3390 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3391 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3397 target_to_host_sigset_internal(&blocked, &target_set);
3398 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3400 if (restore_sigcontext(regs, &frame->sc, &r0))
3403 unlock_user_struct(frame, frame_addr, 0);
3407 unlock_user_struct(frame, frame_addr, 0);
3408 force_sig(TARGET_SIGSEGV);
3412 long do_rt_sigreturn(CPUSH4State *regs)
3414 struct target_rt_sigframe *frame;
3415 abi_ulong frame_addr;
3419 #if defined(DEBUG_SIGNAL)
3420 fprintf(stderr, "do_rt_sigreturn\n");
3422 frame_addr = regs->gregs[15];
3423 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3426 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3427 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3429 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3432 if (do_sigaltstack(frame_addr +
3433 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3434 0, get_sp_from_cpustate(regs)) == -EFAULT)
3437 unlock_user_struct(frame, frame_addr, 0);
3441 unlock_user_struct(frame, frame_addr, 0);
3442 force_sig(TARGET_SIGSEGV);
3445 #elif defined(TARGET_MICROBLAZE)
3447 struct target_sigcontext {
3448 struct target_pt_regs regs; /* needs to be first */
3452 struct target_stack_t {
3455 unsigned int ss_size;
3458 struct target_ucontext {
3459 abi_ulong tuc_flags;
3461 struct target_stack_t tuc_stack;
3462 struct target_sigcontext tuc_mcontext;
3463 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3466 /* Signal frames. */
3467 struct target_signal_frame {
3468 struct target_ucontext uc;
3469 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3473 struct rt_signal_frame {
3479 static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3481 __put_user(env->regs[0], &sc->regs.r0);
3482 __put_user(env->regs[1], &sc->regs.r1);
3483 __put_user(env->regs[2], &sc->regs.r2);
3484 __put_user(env->regs[3], &sc->regs.r3);
3485 __put_user(env->regs[4], &sc->regs.r4);
3486 __put_user(env->regs[5], &sc->regs.r5);
3487 __put_user(env->regs[6], &sc->regs.r6);
3488 __put_user(env->regs[7], &sc->regs.r7);
3489 __put_user(env->regs[8], &sc->regs.r8);
3490 __put_user(env->regs[9], &sc->regs.r9);
3491 __put_user(env->regs[10], &sc->regs.r10);
3492 __put_user(env->regs[11], &sc->regs.r11);
3493 __put_user(env->regs[12], &sc->regs.r12);
3494 __put_user(env->regs[13], &sc->regs.r13);
3495 __put_user(env->regs[14], &sc->regs.r14);
3496 __put_user(env->regs[15], &sc->regs.r15);
3497 __put_user(env->regs[16], &sc->regs.r16);
3498 __put_user(env->regs[17], &sc->regs.r17);
3499 __put_user(env->regs[18], &sc->regs.r18);
3500 __put_user(env->regs[19], &sc->regs.r19);
3501 __put_user(env->regs[20], &sc->regs.r20);
3502 __put_user(env->regs[21], &sc->regs.r21);
3503 __put_user(env->regs[22], &sc->regs.r22);
3504 __put_user(env->regs[23], &sc->regs.r23);
3505 __put_user(env->regs[24], &sc->regs.r24);
3506 __put_user(env->regs[25], &sc->regs.r25);
3507 __put_user(env->regs[26], &sc->regs.r26);
3508 __put_user(env->regs[27], &sc->regs.r27);
3509 __put_user(env->regs[28], &sc->regs.r28);
3510 __put_user(env->regs[29], &sc->regs.r29);
3511 __put_user(env->regs[30], &sc->regs.r30);
3512 __put_user(env->regs[31], &sc->regs.r31);
3513 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3516 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3518 __get_user(env->regs[0], &sc->regs.r0);
3519 __get_user(env->regs[1], &sc->regs.r1);
3520 __get_user(env->regs[2], &sc->regs.r2);
3521 __get_user(env->regs[3], &sc->regs.r3);
3522 __get_user(env->regs[4], &sc->regs.r4);
3523 __get_user(env->regs[5], &sc->regs.r5);
3524 __get_user(env->regs[6], &sc->regs.r6);
3525 __get_user(env->regs[7], &sc->regs.r7);
3526 __get_user(env->regs[8], &sc->regs.r8);
3527 __get_user(env->regs[9], &sc->regs.r9);
3528 __get_user(env->regs[10], &sc->regs.r10);
3529 __get_user(env->regs[11], &sc->regs.r11);
3530 __get_user(env->regs[12], &sc->regs.r12);
3531 __get_user(env->regs[13], &sc->regs.r13);
3532 __get_user(env->regs[14], &sc->regs.r14);
3533 __get_user(env->regs[15], &sc->regs.r15);
3534 __get_user(env->regs[16], &sc->regs.r16);
3535 __get_user(env->regs[17], &sc->regs.r17);
3536 __get_user(env->regs[18], &sc->regs.r18);
3537 __get_user(env->regs[19], &sc->regs.r19);
3538 __get_user(env->regs[20], &sc->regs.r20);
3539 __get_user(env->regs[21], &sc->regs.r21);
3540 __get_user(env->regs[22], &sc->regs.r22);
3541 __get_user(env->regs[23], &sc->regs.r23);
3542 __get_user(env->regs[24], &sc->regs.r24);
3543 __get_user(env->regs[25], &sc->regs.r25);
3544 __get_user(env->regs[26], &sc->regs.r26);
3545 __get_user(env->regs[27], &sc->regs.r27);
3546 __get_user(env->regs[28], &sc->regs.r28);
3547 __get_user(env->regs[29], &sc->regs.r29);
3548 __get_user(env->regs[30], &sc->regs.r30);
3549 __get_user(env->regs[31], &sc->regs.r31);
3550 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3553 static abi_ulong get_sigframe(struct target_sigaction *ka,
3554 CPUMBState *env, int frame_size)
3556 abi_ulong sp = env->regs[1];
3558 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3559 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3561 return ((sp - frame_size) & -8UL);
3564 static void setup_frame(int sig, struct target_sigaction *ka,
3565 target_sigset_t *set, CPUMBState *env)
3567 struct target_signal_frame *frame;
3568 abi_ulong frame_addr;
3572 frame_addr = get_sigframe(ka, env, sizeof *frame);
3573 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3576 /* Save the mask. */
3577 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3581 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3582 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3586 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3588 /* Set up to return from userspace. If provided, use a stub
3589 already in userspace. */
3590 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3591 if (ka->sa_flags & TARGET_SA_RESTORER) {
3592 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3595 /* Note, these encodings are _big endian_! */
3596 /* addi r12, r0, __NR_sigreturn */
3597 t = 0x31800000UL | TARGET_NR_sigreturn;
3598 err |= __put_user(t, frame->tramp + 0);
3601 err |= __put_user(t, frame->tramp + 1);
3603 /* Return from sighandler will jump to the tramp.
3604 Negative 8 offset because return is rtsd r15, 8 */
3605 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3611 /* Set up registers for signal handler */
3612 env->regs[1] = frame_addr;
3613 /* Signal handler args: */
3614 env->regs[5] = sig; /* Arg 0: signum */
3616 /* arg 1: sigcontext */
3617 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3619 /* Offset of 4 to handle microblaze rtid r14, 0 */
3620 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3622 unlock_user_struct(frame, frame_addr, 1);
3625 unlock_user_struct(frame, frame_addr, 1);
3626 force_sig(TARGET_SIGSEGV);
3629 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3630 target_siginfo_t *info,
3631 target_sigset_t *set, CPUMBState *env)
3633 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3636 long do_sigreturn(CPUMBState *env)
3638 struct target_signal_frame *frame;
3639 abi_ulong frame_addr;
3640 target_sigset_t target_set;
3644 frame_addr = env->regs[R_SP];
3645 /* Make sure the guest isn't playing games. */
3646 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3649 /* Restore blocked signals */
3650 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3652 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3653 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3656 target_to_host_sigset_internal(&set, &target_set);
3657 do_sigprocmask(SIG_SETMASK, &set, NULL);
3659 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3660 /* We got here through a sigreturn syscall, our path back is via an
3661 rtb insn so setup r14 for that. */
3662 env->regs[14] = env->sregs[SR_PC];
3664 unlock_user_struct(frame, frame_addr, 0);
3665 return env->regs[10];
3667 unlock_user_struct(frame, frame_addr, 0);
3668 force_sig(TARGET_SIGSEGV);
3671 long do_rt_sigreturn(CPUMBState *env)
3673 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3674 return -TARGET_ENOSYS;
3677 #elif defined(TARGET_CRIS)
3679 struct target_sigcontext {
3680 struct target_pt_regs regs; /* needs to be first */
3682 uint32_t usp; /* usp before stacking this gunk on it */
3685 /* Signal frames. */
3686 struct target_signal_frame {
3687 struct target_sigcontext sc;
3688 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3689 uint16_t retcode[4]; /* Trampoline code. */
3692 struct rt_signal_frame {
3697 uint16_t retcode[4]; /* Trampoline code. */
3700 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3702 __put_user(env->regs[0], &sc->regs.r0);
3703 __put_user(env->regs[1], &sc->regs.r1);
3704 __put_user(env->regs[2], &sc->regs.r2);
3705 __put_user(env->regs[3], &sc->regs.r3);
3706 __put_user(env->regs[4], &sc->regs.r4);
3707 __put_user(env->regs[5], &sc->regs.r5);
3708 __put_user(env->regs[6], &sc->regs.r6);
3709 __put_user(env->regs[7], &sc->regs.r7);
3710 __put_user(env->regs[8], &sc->regs.r8);
3711 __put_user(env->regs[9], &sc->regs.r9);
3712 __put_user(env->regs[10], &sc->regs.r10);
3713 __put_user(env->regs[11], &sc->regs.r11);
3714 __put_user(env->regs[12], &sc->regs.r12);
3715 __put_user(env->regs[13], &sc->regs.r13);
3716 __put_user(env->regs[14], &sc->usp);
3717 __put_user(env->regs[15], &sc->regs.acr);
3718 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3719 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3720 __put_user(env->pc, &sc->regs.erp);
3723 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3725 __get_user(env->regs[0], &sc->regs.r0);
3726 __get_user(env->regs[1], &sc->regs.r1);
3727 __get_user(env->regs[2], &sc->regs.r2);
3728 __get_user(env->regs[3], &sc->regs.r3);
3729 __get_user(env->regs[4], &sc->regs.r4);
3730 __get_user(env->regs[5], &sc->regs.r5);
3731 __get_user(env->regs[6], &sc->regs.r6);
3732 __get_user(env->regs[7], &sc->regs.r7);
3733 __get_user(env->regs[8], &sc->regs.r8);
3734 __get_user(env->regs[9], &sc->regs.r9);
3735 __get_user(env->regs[10], &sc->regs.r10);
3736 __get_user(env->regs[11], &sc->regs.r11);
3737 __get_user(env->regs[12], &sc->regs.r12);
3738 __get_user(env->regs[13], &sc->regs.r13);
3739 __get_user(env->regs[14], &sc->usp);
3740 __get_user(env->regs[15], &sc->regs.acr);
3741 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3742 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3743 __get_user(env->pc, &sc->regs.erp);
3746 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3749 /* Align the stack downwards to 4. */
3750 sp = (env->regs[R_SP] & ~3);
3751 return sp - framesize;
3754 static void setup_frame(int sig, struct target_sigaction *ka,
3755 target_sigset_t *set, CPUCRISState *env)
3757 struct target_signal_frame *frame;
3758 abi_ulong frame_addr;
3762 frame_addr = get_sigframe(env, sizeof *frame);
3763 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3767 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3768 * use this trampoline anymore but it sets it up for GDB.
3769 * In QEMU, using the trampoline simplifies things a bit so we use it.
3771 * This is movu.w __NR_sigreturn, r9; break 13;
3773 err |= __put_user(0x9c5f, frame->retcode+0);
3774 err |= __put_user(TARGET_NR_sigreturn,
3775 frame->retcode + 1);
3776 err |= __put_user(0xe93d, frame->retcode + 2);
3778 /* Save the mask. */
3779 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3783 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3784 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3788 setup_sigcontext(&frame->sc, env);
3790 /* Move the stack and setup the arguments for the handler. */
3791 env->regs[R_SP] = frame_addr;
3792 env->regs[10] = sig;
3793 env->pc = (unsigned long) ka->_sa_handler;
3794 /* Link SRP so the guest returns through the trampoline. */
3795 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3797 unlock_user_struct(frame, frame_addr, 1);
3800 unlock_user_struct(frame, frame_addr, 1);
3801 force_sig(TARGET_SIGSEGV);
3804 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3805 target_siginfo_t *info,
3806 target_sigset_t *set, CPUCRISState *env)
3808 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3811 long do_sigreturn(CPUCRISState *env)
3813 struct target_signal_frame *frame;
3814 abi_ulong frame_addr;
3815 target_sigset_t target_set;
3819 frame_addr = env->regs[R_SP];
3820 /* Make sure the guest isn't playing games. */
3821 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3824 /* Restore blocked signals */
3825 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3827 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3828 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3831 target_to_host_sigset_internal(&set, &target_set);
3832 do_sigprocmask(SIG_SETMASK, &set, NULL);
3834 restore_sigcontext(&frame->sc, env);
3835 unlock_user_struct(frame, frame_addr, 0);
3836 return env->regs[10];
3838 unlock_user_struct(frame, frame_addr, 0);
3839 force_sig(TARGET_SIGSEGV);
3842 long do_rt_sigreturn(CPUCRISState *env)
3844 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3845 return -TARGET_ENOSYS;
3848 #elif defined(TARGET_OPENRISC)
3850 struct target_sigcontext {
3851 struct target_pt_regs regs;
3856 struct target_ucontext {
3857 abi_ulong tuc_flags;
3859 target_stack_t tuc_stack;
3860 struct target_sigcontext tuc_mcontext;
3861 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3864 struct target_rt_sigframe {
3867 struct target_siginfo info;
3868 struct target_sigcontext sc;
3869 struct target_ucontext uc;
3870 unsigned char retcode[16]; /* trampoline code */
3873 /* This is the asm-generic/ucontext.h version */
3875 static int restore_sigcontext(CPUOpenRISCState *regs,
3876 struct target_sigcontext *sc)
3878 unsigned int err = 0;
3879 unsigned long old_usp;
3881 /* Alwys make any pending restarted system call return -EINTR */
3882 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3884 /* restore the regs from &sc->regs (same as sc, since regs is first)
3885 * (sc is already checked for VERIFY_READ since the sigframe was
3886 * checked in sys_sigreturn previously)
3889 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3893 /* make sure the U-flag is set so user-mode cannot fool us */
3897 /* restore the old USP as it was before we stacked the sc etc.
3898 * (we cannot just pop the sigcontext since we aligned the sp and
3899 * stuff after pushing it)
3902 err |= __get_user(old_usp, &sc->usp);
3903 phx_signal("old_usp 0x%lx", old_usp);
3905 __PHX__ REALLY /* ??? */
3907 regs->gpr[1] = old_usp;
3909 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3910 * after this completes, but we don't use that mechanism. maybe we can
3921 /* Set up a signal frame. */
3923 static int setup_sigcontext(struct target_sigcontext *sc,
3924 CPUOpenRISCState *regs,
3928 unsigned long usp = regs->gpr[1];
3930 /* copy the regs. they are first in sc so we can use sc directly */
3932 /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3934 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3935 the signal handler. The frametype will be restored to its previous
3936 value in restore_sigcontext. */
3937 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3939 /* then some other stuff */
3940 err |= __put_user(mask, &sc->oldmask);
3941 err |= __put_user(usp, &sc->usp); return err;
3944 static inline unsigned long align_sigframe(unsigned long sp)
3951 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3952 CPUOpenRISCState *regs,
3955 unsigned long sp = regs->gpr[1];
3956 int onsigstack = on_sig_stack(sp);
3959 /* This is the X/Open sanctioned signal stack switching. */
3960 if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
3961 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3964 sp = align_sigframe(sp - frame_size);
3967 * If we are on the alternate signal stack and would overflow it, don't.
3968 * Return an always-bogus address instead so we will die with SIGSEGV.
3971 if (onsigstack && !likely(on_sig_stack(sp))) {
3978 static void setup_frame(int sig, struct target_sigaction *ka,
3979 target_sigset_t *set, CPUOpenRISCState *env)
3981 qemu_log("Not implement.\n");
3984 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3985 target_siginfo_t *info,
3986 target_sigset_t *set, CPUOpenRISCState *env)
3989 abi_ulong frame_addr;
3990 unsigned long return_ip;
3991 struct target_rt_sigframe *frame;
3992 abi_ulong info_addr, uc_addr;
3994 frame_addr = get_sigframe(ka, env, sizeof *frame);
3996 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3997 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4001 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4002 err |= __put_user(info_addr, &frame->pinfo);
4003 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4004 err |= __put_user(uc_addr, &frame->puc);
4006 if (ka->sa_flags & SA_SIGINFO) {
4007 err |= copy_siginfo_to_user(&frame->info, info);
4013 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
4014 err |= __put_user(0, &frame->uc.tuc_flags);
4015 err |= __put_user(0, &frame->uc.tuc_link);
4016 err |= __put_user(target_sigaltstack_used.ss_sp,
4017 &frame->uc.tuc_stack.ss_sp);
4018 err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
4019 err |= __put_user(target_sigaltstack_used.ss_size,
4020 &frame->uc.tuc_stack.ss_size);
4021 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4023 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
4029 /* trampoline - the desired return ip is the retcode itself */
4030 return_ip = (unsigned long)&frame->retcode;
4031 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
4032 err |= __put_user(0xa960, (short *)(frame->retcode + 0));
4033 err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
4034 err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
4035 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
4041 /* TODO what is the current->exec_domain stuff and invmap ? */
4043 /* Set up registers for signal handler */
4044 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
4045 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
4046 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
4047 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
4048 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
4050 /* actually move the usp to reflect the stacked frame */
4051 env->gpr[1] = (unsigned long)frame;
4056 unlock_user_struct(frame, frame_addr, 1);
4057 if (sig == TARGET_SIGSEGV) {
4058 ka->_sa_handler = TARGET_SIG_DFL;
4060 force_sig(TARGET_SIGSEGV);
4063 long do_sigreturn(CPUOpenRISCState *env)
4066 qemu_log("do_sigreturn: not implemented\n");
4067 return -TARGET_ENOSYS;
4070 long do_rt_sigreturn(CPUOpenRISCState *env)
4072 qemu_log("do_rt_sigreturn: not implemented\n");
4073 return -TARGET_ENOSYS;
4075 /* TARGET_OPENRISC */
4077 #elif defined(TARGET_S390X)
4079 #define __NUM_GPRS 16
4080 #define __NUM_FPRS 16
4081 #define __NUM_ACRS 16
4083 #define S390_SYSCALL_SIZE 2
4084 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4086 #define _SIGCONTEXT_NSIG 64
4087 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4088 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4089 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4090 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4091 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4095 target_ulong gprs[__NUM_GPRS];
4096 unsigned int acrs[__NUM_ACRS];
4097 } target_s390_regs_common;
4101 double fprs[__NUM_FPRS];
4102 } target_s390_fp_regs;
4105 target_s390_regs_common regs;
4106 target_s390_fp_regs fpregs;
4109 struct target_sigcontext {
4110 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4111 target_sigregs *sregs;
4115 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4116 struct target_sigcontext sc;
4117 target_sigregs sregs;
4119 uint8_t retcode[S390_SYSCALL_SIZE];
4122 struct target_ucontext {
4123 target_ulong tuc_flags;
4124 struct target_ucontext *tuc_link;
4125 target_stack_t tuc_stack;
4126 target_sigregs tuc_mcontext;
4127 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4131 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4132 uint8_t retcode[S390_SYSCALL_SIZE];
4133 struct target_siginfo info;
4134 struct target_ucontext uc;
4137 static inline abi_ulong
4138 get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4142 /* Default to using normal stack */
4145 /* This is the X/Open sanctioned signal stack switching. */
4146 if (ka->sa_flags & TARGET_SA_ONSTACK) {
4147 if (!sas_ss_flags(sp)) {
4148 sp = target_sigaltstack_used.ss_sp +
4149 target_sigaltstack_used.ss_size;
4153 /* This is the legacy signal stack switching. */
4154 else if (/* FIXME !user_mode(regs) */ 0 &&
4155 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4157 sp = (abi_ulong) ka->sa_restorer;
4160 return (sp - frame_size) & -8ul;
4163 static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4166 //save_access_regs(current->thread.acrs); FIXME
4168 /* Copy a 'clean' PSW mask to the user to avoid leaking
4169 information about whether PER is currently on. */
4170 __put_user(env->psw.mask, &sregs->regs.psw.mask);
4171 __put_user(env->psw.addr, &sregs->regs.psw.addr);
4172 for (i = 0; i < 16; i++) {
4173 __put_user(env->regs[i], &sregs->regs.gprs[i]);
4175 for (i = 0; i < 16; i++) {
4176 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
4179 * We have to store the fp registers to current->thread.fp_regs
4180 * to merge them with the emulated registers.
4182 //save_fp_regs(¤t->thread.fp_regs); FIXME
4183 for (i = 0; i < 16; i++) {
4184 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4188 static void setup_frame(int sig, struct target_sigaction *ka,
4189 target_sigset_t *set, CPUS390XState *env)
4192 abi_ulong frame_addr;
4194 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4195 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4196 (unsigned long long)frame_addr);
4197 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4201 qemu_log("%s: 1\n", __FUNCTION__);
4202 if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
4206 save_sigregs(env, &frame->sregs);
4208 __put_user((abi_ulong)(unsigned long)&frame->sregs,
4209 (abi_ulong *)&frame->sc.sregs);
4211 /* Set up to return from userspace. If provided, use a stub
4212 already in userspace. */
4213 if (ka->sa_flags & TARGET_SA_RESTORER) {
4214 env->regs[14] = (unsigned long)
4215 ka->sa_restorer | PSW_ADDR_AMODE;
4217 env->regs[14] = (unsigned long)
4218 frame->retcode | PSW_ADDR_AMODE;
4219 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
4220 (uint16_t *)(frame->retcode)))
4224 /* Set up backchain. */
4225 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4229 /* Set up registers for signal handler */
4230 env->regs[15] = frame_addr;
4231 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4233 env->regs[2] = sig; //map_signal(sig);
4234 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
4236 /* We forgot to include these in the sigcontext.
4237 To avoid breaking binary compatibility, they are passed as args. */
4238 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4239 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4241 /* Place signal number on stack to allow backtrace from handler. */
4242 if (__put_user(env->regs[2], (int *) &frame->signo)) {
4245 unlock_user_struct(frame, frame_addr, 1);
4249 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4250 unlock_user_struct(frame, frame_addr, 1);
4251 force_sig(TARGET_SIGSEGV);
4254 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4255 target_siginfo_t *info,
4256 target_sigset_t *set, CPUS390XState *env)
4260 abi_ulong frame_addr;
4262 frame_addr = get_sigframe(ka, env, sizeof *frame);
4263 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4264 (unsigned long long)frame_addr);
4265 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4269 qemu_log("%s: 1\n", __FUNCTION__);
4270 if (copy_siginfo_to_user(&frame->info, info)) {
4274 /* Create the ucontext. */
4275 __put_user(0, &frame->uc.tuc_flags);
4276 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
4277 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
4278 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
4279 &frame->uc.tuc_stack.ss_flags);
4280 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
4281 save_sigregs(env, &frame->uc.tuc_mcontext);
4282 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
4283 __put_user((abi_ulong)set->sig[i],
4284 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
4287 /* Set up to return from userspace. If provided, use a stub
4288 already in userspace. */
4289 if (ka->sa_flags & TARGET_SA_RESTORER) {
4290 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4292 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4293 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
4294 (uint16_t *)(frame->retcode))) {
4299 /* Set up backchain. */
4300 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4304 /* Set up registers for signal handler */
4305 env->regs[15] = frame_addr;
4306 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4308 env->regs[2] = sig; //map_signal(sig);
4309 env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
4310 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
4314 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4315 unlock_user_struct(frame, frame_addr, 1);
4316 force_sig(TARGET_SIGSEGV);
4320 restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4325 for (i = 0; i < 16; i++) {
4326 err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
4329 err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
4330 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4331 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4332 (unsigned long long)env->psw.addr);
4333 err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
4334 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4336 for (i = 0; i < 16; i++) {
4337 err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
4339 for (i = 0; i < 16; i++) {
4340 err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4346 long do_sigreturn(CPUS390XState *env)
4349 abi_ulong frame_addr = env->regs[15];
4350 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4351 (unsigned long long)frame_addr);
4352 target_sigset_t target_set;
4355 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4358 if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
4362 target_to_host_sigset_internal(&set, &target_set);
4363 do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4365 if (restore_sigregs(env, &frame->sregs)) {
4369 unlock_user_struct(frame, frame_addr, 0);
4370 return env->regs[2];
4373 unlock_user_struct(frame, frame_addr, 0);
4374 force_sig(TARGET_SIGSEGV);
4378 long do_rt_sigreturn(CPUS390XState *env)
4381 abi_ulong frame_addr = env->regs[15];
4382 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4383 (unsigned long long)frame_addr);
4386 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4389 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4391 do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4393 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4397 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4398 get_sp_from_cpustate(env)) == -EFAULT) {
4401 unlock_user_struct(frame, frame_addr, 0);
4402 return env->regs[2];
4405 unlock_user_struct(frame, frame_addr, 0);
4406 force_sig(TARGET_SIGSEGV);
4410 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4412 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4413 the signal handling is different enough that we haven't implemented
4414 support for PPC64 yet. Hence the restriction above.
4416 There are various #if'd blocks for code for TARGET_PPC64. These
4417 blocks should go away so that we can successfully run 32-bit and
4418 64-bit binaries on a QEMU configured for PPC64. */
4420 /* Size of dummy stack frame allocated when calling signal handler.
4421 See arch/powerpc/include/asm/ptrace.h. */
4422 #if defined(TARGET_PPC64)
4423 #define SIGNAL_FRAMESIZE 128
4425 #define SIGNAL_FRAMESIZE 64
4428 /* See arch/powerpc/include/asm/sigcontext.h. */
4429 struct target_sigcontext {
4430 target_ulong _unused[4];
4432 #if defined(TARGET_PPC64)
4435 target_ulong handler;
4436 target_ulong oldmask;
4437 target_ulong regs; /* struct pt_regs __user * */
4438 /* TODO: PPC64 includes extra bits here. */
4441 /* Indices for target_mcontext.mc_gregs, below.
4442 See arch/powerpc/include/asm/ptrace.h for details. */
4478 TARGET_PT_ORIG_R3 = 34,
4483 /* Yes, there are two registers with #39. One is 64-bit only. */
4485 TARGET_PT_SOFTE = 39,
4486 TARGET_PT_TRAP = 40,
4488 TARGET_PT_DSISR = 42,
4489 TARGET_PT_RESULT = 43,
4490 TARGET_PT_REGS_COUNT = 44
4493 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4494 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4495 struct target_mcontext {
4496 target_ulong mc_gregs[48];
4497 /* Includes fpscr. */
4498 uint64_t mc_fregs[33];
4499 target_ulong mc_pad[2];
4500 /* We need to handle Altivec and SPE at the same time, which no
4501 kernel needs to do. Fortunately, the kernel defines this bit to
4502 be Altivec-register-large all the time, rather than trying to
4503 twiddle it based on the specific platform. */
4505 /* SPE vector registers. One extra for SPEFSCR. */
4507 /* Altivec vector registers. The packing of VSCR and VRSAVE
4508 varies depending on whether we're PPC64 or not: PPC64 splits
4509 them apart; PPC32 stuffs them together. */
4510 #if defined(TARGET_PPC64)
4511 #define QEMU_NVRREG 34
4513 #define QEMU_NVRREG 33
4515 ppc_avr_t altivec[QEMU_NVRREG];
4517 } mc_vregs __attribute__((__aligned__(16)));
4520 struct target_ucontext {
4521 target_ulong tuc_flags;
4522 target_ulong tuc_link; /* struct ucontext __user * */
4523 struct target_sigaltstack tuc_stack;
4524 #if !defined(TARGET_PPC64)
4526 target_ulong tuc_regs; /* struct mcontext __user *
4527 points to uc_mcontext field */
4529 target_sigset_t tuc_sigmask;
4530 #if defined(TARGET_PPC64)
4531 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4532 struct target_sigcontext tuc_mcontext;
4534 int32_t tuc_maskext[30];
4535 int32_t tuc_pad2[3];
4536 struct target_mcontext tuc_mcontext;
4540 /* See arch/powerpc/kernel/signal_32.c. */
4541 struct target_sigframe {
4542 struct target_sigcontext sctx;
4543 struct target_mcontext mctx;
4547 struct target_rt_sigframe {
4548 struct target_siginfo info;
4549 struct target_ucontext uc;
4553 /* We use the mc_pad field for the signal return trampoline. */
4554 #define tramp mc_pad
4556 /* See arch/powerpc/kernel/signal.c. */
4557 static target_ulong get_sigframe(struct target_sigaction *ka,
4561 target_ulong oldsp, newsp;
4563 oldsp = env->gpr[1];
4565 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4566 (sas_ss_flags(oldsp) == 0)) {
4567 oldsp = (target_sigaltstack_used.ss_sp
4568 + target_sigaltstack_used.ss_size);
4571 newsp = (oldsp - frame_size) & ~0xFUL;
4576 static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4579 target_ulong msr = env->msr;
4581 target_ulong ccr = 0;
4583 /* In general, the kernel attempts to be intelligent about what it
4584 needs to save for Altivec/FP/SPE registers. We don't care that
4585 much, so we just go ahead and save everything. */
4587 /* Save general registers. */
4588 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4589 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
4593 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4594 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4595 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4596 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4599 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4600 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4602 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4605 /* Save Altivec registers if necessary. */
4606 if (env->insns_flags & PPC_ALTIVEC) {
4607 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4608 ppc_avr_t *avr = &env->avr[i];
4609 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4611 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4612 __put_user(avr->u64[1], &vreg->u64[1])) {
4616 /* Set MSR_VR in the saved MSR value to indicate that
4617 frame->mc_vregs contains valid data. */
4619 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4620 &frame->mc_vregs.altivec[32].u32[3]))
4624 /* Save floating point registers. */
4625 if (env->insns_flags & PPC_FLOAT) {
4626 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4627 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
4631 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
4635 /* Save SPE registers. The kernel only saves the high half. */
4636 if (env->insns_flags & PPC_SPE) {
4637 #if defined(TARGET_PPC64)
4638 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4639 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
4644 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4645 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4650 /* Set MSR_SPE in the saved MSR value to indicate that
4651 frame->mc_vregs contains valid data. */
4653 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4658 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4661 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4663 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4664 __put_user(0x44000002UL, &frame->tramp[1])) {
4672 static int restore_user_regs(CPUPPCState *env,
4673 struct target_mcontext *frame, int sig)
4675 target_ulong save_r2 = 0;
4682 save_r2 = env->gpr[2];
4685 /* Restore general registers. */
4686 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4687 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
4691 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4692 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4693 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4694 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4696 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4699 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4700 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4704 env->gpr[2] = save_r2;
4707 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4710 /* If doing signal return, restore the previous little-endian mode. */
4712 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4714 /* Restore Altivec registers if necessary. */
4715 if (env->insns_flags & PPC_ALTIVEC) {
4716 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4717 ppc_avr_t *avr = &env->avr[i];
4718 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4720 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4721 __get_user(avr->u64[1], &vreg->u64[1])) {
4725 /* Set MSR_VEC in the saved MSR value to indicate that
4726 frame->mc_vregs contains valid data. */
4727 if (__get_user(env->spr[SPR_VRSAVE],
4728 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
4732 /* Restore floating point registers. */
4733 if (env->insns_flags & PPC_FLOAT) {
4735 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4736 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4740 if (__get_user(fpscr, &frame->mc_fregs[32]))
4742 env->fpscr = (uint32_t) fpscr;
4745 /* Save SPE registers. The kernel only saves the high half. */
4746 if (env->insns_flags & PPC_SPE) {
4747 #if defined(TARGET_PPC64)
4748 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4751 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4754 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4757 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4758 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4763 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4770 static void setup_frame(int sig, struct target_sigaction *ka,
4771 target_sigset_t *set, CPUPPCState *env)
4773 struct target_sigframe *frame;
4774 struct target_sigcontext *sc;
4775 target_ulong frame_addr, newsp;
4779 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4780 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4784 signal = current_exec_domain_sig(sig);
4786 err |= __put_user(ka->_sa_handler, &sc->handler);
4787 err |= __put_user(set->sig[0], &sc->oldmask);
4788 #if defined(TARGET_PPC64)
4789 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4791 err |= __put_user(set->sig[1], &sc->_unused[3]);
4793 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4794 err |= __put_user(sig, &sc->signal);
4796 /* Save user regs. */
4797 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4799 /* The kernel checks for the presence of a VDSO here. We don't
4800 emulate a vdso, so use a sigreturn system call. */
4801 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4803 /* Turn off all fp exceptions. */
4806 /* Create a stack frame for the caller of the handler. */
4807 newsp = frame_addr - SIGNAL_FRAMESIZE;
4808 err |= put_user(env->gpr[1], newsp, target_ulong);
4813 /* Set up registers for signal handler. */
4814 env->gpr[1] = newsp;
4815 env->gpr[3] = signal;
4816 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
4817 env->nip = (target_ulong) ka->_sa_handler;
4818 /* Signal handlers are entered in big-endian mode. */
4819 env->msr &= ~MSR_LE;
4821 unlock_user_struct(frame, frame_addr, 1);
4825 unlock_user_struct(frame, frame_addr, 1);
4826 qemu_log("segfaulting from setup_frame\n");
4827 force_sig(TARGET_SIGSEGV);
4830 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4831 target_siginfo_t *info,
4832 target_sigset_t *set, CPUPPCState *env)
4834 struct target_rt_sigframe *rt_sf;
4835 struct target_mcontext *frame;
4836 target_ulong rt_sf_addr, newsp = 0;
4840 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4841 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4844 signal = current_exec_domain_sig(sig);
4846 err |= copy_siginfo_to_user(&rt_sf->info, info);
4848 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4849 err |= __put_user(0, &rt_sf->uc.tuc_link);
4850 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4851 &rt_sf->uc.tuc_stack.ss_sp);
4852 err |= __put_user(sas_ss_flags(env->gpr[1]),
4853 &rt_sf->uc.tuc_stack.ss_flags);
4854 err |= __put_user(target_sigaltstack_used.ss_size,
4855 &rt_sf->uc.tuc_stack.ss_size);
4856 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4857 &rt_sf->uc.tuc_regs);
4858 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4859 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4862 frame = &rt_sf->uc.tuc_mcontext;
4863 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4865 /* The kernel checks for the presence of a VDSO here. We don't
4866 emulate a vdso, so use a sigreturn system call. */
4867 env->lr = (target_ulong) h2g(frame->tramp);
4869 /* Turn off all fp exceptions. */
4872 /* Create a stack frame for the caller of the handler. */
4873 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4874 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4879 /* Set up registers for signal handler. */
4880 env->gpr[1] = newsp;
4881 env->gpr[3] = (target_ulong) signal;
4882 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4883 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4884 env->gpr[6] = (target_ulong) h2g(rt_sf);
4885 env->nip = (target_ulong) ka->_sa_handler;
4886 /* Signal handlers are entered in big-endian mode. */
4887 env->msr &= ~MSR_LE;
4889 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4893 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4894 qemu_log("segfaulting from setup_rt_frame\n");
4895 force_sig(TARGET_SIGSEGV);
4899 long do_sigreturn(CPUPPCState *env)
4901 struct target_sigcontext *sc = NULL;
4902 struct target_mcontext *sr = NULL;
4903 target_ulong sr_addr = 0, sc_addr;
4905 target_sigset_t set;
4907 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4908 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4911 #if defined(TARGET_PPC64)
4912 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4914 if(__get_user(set.sig[0], &sc->oldmask) ||
4915 __get_user(set.sig[1], &sc->_unused[3]))
4918 target_to_host_sigset_internal(&blocked, &set);
4919 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
4921 if (__get_user(sr_addr, &sc->regs))
4923 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4925 if (restore_user_regs(env, sr, 1))
4928 unlock_user_struct(sr, sr_addr, 1);
4929 unlock_user_struct(sc, sc_addr, 1);
4930 return -TARGET_QEMU_ESIGRETURN;
4933 unlock_user_struct(sr, sr_addr, 1);
4934 unlock_user_struct(sc, sc_addr, 1);
4935 qemu_log("segfaulting from do_sigreturn\n");
4936 force_sig(TARGET_SIGSEGV);
4940 /* See arch/powerpc/kernel/signal_32.c. */
4941 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4943 struct target_mcontext *mcp;
4944 target_ulong mcp_addr;
4946 target_sigset_t set;
4948 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4952 #if defined(TARGET_PPC64)
4953 fprintf (stderr, "do_setcontext: not implemented\n");
4956 if (__get_user(mcp_addr, &ucp->tuc_regs))
4959 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4962 target_to_host_sigset_internal(&blocked, &set);
4963 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
4964 if (restore_user_regs(env, mcp, sig))
4967 unlock_user_struct(mcp, mcp_addr, 1);
4971 unlock_user_struct(mcp, mcp_addr, 1);
4976 long do_rt_sigreturn(CPUPPCState *env)
4978 struct target_rt_sigframe *rt_sf = NULL;
4979 target_ulong rt_sf_addr;
4981 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4982 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4985 if (do_setcontext(&rt_sf->uc, env, 1))
4988 do_sigaltstack(rt_sf_addr
4989 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4992 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4993 return -TARGET_QEMU_ESIGRETURN;
4996 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4997 qemu_log("segfaulting from do_rt_sigreturn\n");
4998 force_sig(TARGET_SIGSEGV);
5002 #elif defined(TARGET_M68K)
5004 struct target_sigcontext {
5011 unsigned short sc_sr;
5015 struct target_sigframe
5022 abi_ulong extramask[TARGET_NSIG_WORDS-1];
5023 struct target_sigcontext sc;
5026 typedef int target_greg_t;
5027 #define TARGET_NGREG 18
5028 typedef target_greg_t target_gregset_t[TARGET_NGREG];
5030 typedef struct target_fpregset {
5033 } target_fpregset_t;
5035 struct target_mcontext {
5037 target_gregset_t gregs;
5038 target_fpregset_t fpregs;
5041 #define TARGET_MCONTEXT_VERSION 2
5043 struct target_ucontext {
5044 abi_ulong tuc_flags;
5046 target_stack_t tuc_stack;
5047 struct target_mcontext tuc_mcontext;
5048 abi_long tuc_filler[80];
5049 target_sigset_t tuc_sigmask;
5052 struct target_rt_sigframe
5059 struct target_siginfo info;
5060 struct target_ucontext uc;
5064 setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
5069 err |= __put_user(mask, &sc->sc_mask);
5070 err |= __put_user(env->aregs[7], &sc->sc_usp);
5071 err |= __put_user(env->dregs[0], &sc->sc_d0);
5072 err |= __put_user(env->dregs[1], &sc->sc_d1);
5073 err |= __put_user(env->aregs[0], &sc->sc_a0);
5074 err |= __put_user(env->aregs[1], &sc->sc_a1);
5075 err |= __put_user(env->sr, &sc->sc_sr);
5076 err |= __put_user(env->pc, &sc->sc_pc);
5082 restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
5087 err |= __get_user(env->aregs[7], &sc->sc_usp);
5088 err |= __get_user(env->dregs[1], &sc->sc_d1);
5089 err |= __get_user(env->aregs[0], &sc->sc_a0);
5090 err |= __get_user(env->aregs[1], &sc->sc_a1);
5091 err |= __get_user(env->pc, &sc->sc_pc);
5092 err |= __get_user(temp, &sc->sc_sr);
5093 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5095 *pd0 = tswapl(sc->sc_d0);
5101 * Determine which stack to use..
5103 static inline abi_ulong
5104 get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5109 sp = regs->aregs[7];
5111 /* This is the X/Open sanctioned signal stack switching. */
5112 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
5113 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5116 return ((sp - frame_size) & -8UL);
5119 static void setup_frame(int sig, struct target_sigaction *ka,
5120 target_sigset_t *set, CPUM68KState *env)
5122 struct target_sigframe *frame;
5123 abi_ulong frame_addr;
5124 abi_ulong retcode_addr;
5129 frame_addr = get_sigframe(ka, env, sizeof *frame);
5130 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5133 err |= __put_user(sig, &frame->sig);
5135 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
5136 err |= __put_user(sc_addr, &frame->psc);
5138 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
5142 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5143 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
5147 /* Set up to return from userspace. */
5149 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5150 err |= __put_user(retcode_addr, &frame->pretcode);
5152 /* moveq #,d0; trap #0 */
5154 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5155 (long *)(frame->retcode));
5160 /* Set up to return from userspace */
5162 env->aregs[7] = frame_addr;
5163 env->pc = ka->_sa_handler;
5165 unlock_user_struct(frame, frame_addr, 1);
5169 unlock_user_struct(frame, frame_addr, 1);
5170 force_sig(TARGET_SIGSEGV);
5173 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5176 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5179 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
5180 err |= __put_user(env->dregs[0], &gregs[0]);
5181 err |= __put_user(env->dregs[1], &gregs[1]);
5182 err |= __put_user(env->dregs[2], &gregs[2]);
5183 err |= __put_user(env->dregs[3], &gregs[3]);
5184 err |= __put_user(env->dregs[4], &gregs[4]);
5185 err |= __put_user(env->dregs[5], &gregs[5]);
5186 err |= __put_user(env->dregs[6], &gregs[6]);
5187 err |= __put_user(env->dregs[7], &gregs[7]);
5188 err |= __put_user(env->aregs[0], &gregs[8]);
5189 err |= __put_user(env->aregs[1], &gregs[9]);
5190 err |= __put_user(env->aregs[2], &gregs[10]);
5191 err |= __put_user(env->aregs[3], &gregs[11]);
5192 err |= __put_user(env->aregs[4], &gregs[12]);
5193 err |= __put_user(env->aregs[5], &gregs[13]);
5194 err |= __put_user(env->aregs[6], &gregs[14]);
5195 err |= __put_user(env->aregs[7], &gregs[15]);
5196 err |= __put_user(env->pc, &gregs[16]);
5197 err |= __put_user(env->sr, &gregs[17]);
5202 static inline int target_rt_restore_ucontext(CPUM68KState *env,
5203 struct target_ucontext *uc,
5208 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5210 err = __get_user(temp, &uc->tuc_mcontext.version);
5211 if (temp != TARGET_MCONTEXT_VERSION)
5214 /* restore passed registers */
5215 err |= __get_user(env->dregs[0], &gregs[0]);
5216 err |= __get_user(env->dregs[1], &gregs[1]);
5217 err |= __get_user(env->dregs[2], &gregs[2]);
5218 err |= __get_user(env->dregs[3], &gregs[3]);
5219 err |= __get_user(env->dregs[4], &gregs[4]);
5220 err |= __get_user(env->dregs[5], &gregs[5]);
5221 err |= __get_user(env->dregs[6], &gregs[6]);
5222 err |= __get_user(env->dregs[7], &gregs[7]);
5223 err |= __get_user(env->aregs[0], &gregs[8]);
5224 err |= __get_user(env->aregs[1], &gregs[9]);
5225 err |= __get_user(env->aregs[2], &gregs[10]);
5226 err |= __get_user(env->aregs[3], &gregs[11]);
5227 err |= __get_user(env->aregs[4], &gregs[12]);
5228 err |= __get_user(env->aregs[5], &gregs[13]);
5229 err |= __get_user(env->aregs[6], &gregs[14]);
5230 err |= __get_user(env->aregs[7], &gregs[15]);
5231 err |= __get_user(env->pc, &gregs[16]);
5232 err |= __get_user(temp, &gregs[17]);
5233 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5235 *pd0 = env->dregs[0];
5242 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5243 target_siginfo_t *info,
5244 target_sigset_t *set, CPUM68KState *env)
5246 struct target_rt_sigframe *frame;
5247 abi_ulong frame_addr;
5248 abi_ulong retcode_addr;
5249 abi_ulong info_addr;
5254 frame_addr = get_sigframe(ka, env, sizeof *frame);
5255 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5258 err |= __put_user(sig, &frame->sig);
5260 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5261 err |= __put_user(info_addr, &frame->pinfo);
5263 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5264 err |= __put_user(uc_addr, &frame->puc);
5266 err |= copy_siginfo_to_user(&frame->info, info);
5268 /* Create the ucontext */
5270 err |= __put_user(0, &frame->uc.tuc_flags);
5271 err |= __put_user(0, &frame->uc.tuc_link);
5272 err |= __put_user(target_sigaltstack_used.ss_sp,
5273 &frame->uc.tuc_stack.ss_sp);
5274 err |= __put_user(sas_ss_flags(env->aregs[7]),
5275 &frame->uc.tuc_stack.ss_flags);
5276 err |= __put_user(target_sigaltstack_used.ss_size,
5277 &frame->uc.tuc_stack.ss_size);
5278 err |= target_rt_setup_ucontext(&frame->uc, env);
5283 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5284 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
5288 /* Set up to return from userspace. */
5290 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5291 err |= __put_user(retcode_addr, &frame->pretcode);
5293 /* moveq #,d0; notb d0; trap #0 */
5295 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
5296 (long *)(frame->retcode + 0));
5297 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
5302 /* Set up to return from userspace */
5304 env->aregs[7] = frame_addr;
5305 env->pc = ka->_sa_handler;
5307 unlock_user_struct(frame, frame_addr, 1);
5311 unlock_user_struct(frame, frame_addr, 1);
5312 force_sig(TARGET_SIGSEGV);
5315 long do_sigreturn(CPUM68KState *env)
5317 struct target_sigframe *frame;
5318 abi_ulong frame_addr = env->aregs[7] - 4;
5319 target_sigset_t target_set;
5323 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5326 /* set blocked signals */
5328 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
5331 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5332 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
5336 target_to_host_sigset_internal(&set, &target_set);
5337 do_sigprocmask(SIG_SETMASK, &set, NULL);
5339 /* restore registers */
5341 if (restore_sigcontext(env, &frame->sc, &d0))
5344 unlock_user_struct(frame, frame_addr, 0);
5348 unlock_user_struct(frame, frame_addr, 0);
5349 force_sig(TARGET_SIGSEGV);
5353 long do_rt_sigreturn(CPUM68KState *env)
5355 struct target_rt_sigframe *frame;
5356 abi_ulong frame_addr = env->aregs[7] - 4;
5357 target_sigset_t target_set;
5361 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5364 target_to_host_sigset_internal(&set, &target_set);
5365 do_sigprocmask(SIG_SETMASK, &set, NULL);
5367 /* restore registers */
5369 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5372 if (do_sigaltstack(frame_addr +
5373 offsetof(struct target_rt_sigframe, uc.tuc_stack),
5374 0, get_sp_from_cpustate(env)) == -EFAULT)
5377 unlock_user_struct(frame, frame_addr, 0);
5381 unlock_user_struct(frame, frame_addr, 0);
5382 force_sig(TARGET_SIGSEGV);
5386 #elif defined(TARGET_ALPHA)
5388 struct target_sigcontext {
5389 abi_long sc_onstack;
5393 abi_long sc_regs[32];
5394 abi_long sc_ownedfp;
5395 abi_long sc_fpregs[32];
5397 abi_ulong sc_fp_control;
5398 abi_ulong sc_reserved1;
5399 abi_ulong sc_reserved2;
5402 abi_ulong sc_traparg_a0;
5403 abi_ulong sc_traparg_a1;
5404 abi_ulong sc_traparg_a2;
5405 abi_ulong sc_fp_trap_pc;
5406 abi_ulong sc_fp_trigger_sum;
5407 abi_ulong sc_fp_trigger_inst;
5410 struct target_ucontext {
5411 abi_ulong tuc_flags;
5413 abi_ulong tuc_osf_sigmask;
5414 target_stack_t tuc_stack;
5415 struct target_sigcontext tuc_mcontext;
5416 target_sigset_t tuc_sigmask;
5419 struct target_sigframe {
5420 struct target_sigcontext sc;
5421 unsigned int retcode[3];
5424 struct target_rt_sigframe {
5425 target_siginfo_t info;
5426 struct target_ucontext uc;
5427 unsigned int retcode[3];
5430 #define INSN_MOV_R30_R16 0x47fe0410
5431 #define INSN_LDI_R0 0x201f0000
5432 #define INSN_CALLSYS 0x00000083
5434 static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5435 abi_ulong frame_addr, target_sigset_t *set)
5439 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
5440 err |= __put_user(set->sig[0], &sc->sc_mask);
5441 err |= __put_user(env->pc, &sc->sc_pc);
5442 err |= __put_user(8, &sc->sc_ps);
5444 for (i = 0; i < 31; ++i) {
5445 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
5447 err |= __put_user(0, &sc->sc_regs[31]);
5449 for (i = 0; i < 31; ++i) {
5450 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
5452 err |= __put_user(0, &sc->sc_fpregs[31]);
5453 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5455 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5456 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5457 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5462 static int restore_sigcontext(CPUAlphaState *env,
5463 struct target_sigcontext *sc)
5468 err |= __get_user(env->pc, &sc->sc_pc);
5470 for (i = 0; i < 31; ++i) {
5471 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5473 for (i = 0; i < 31; ++i) {
5474 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5477 err |= __get_user(fpcr, &sc->sc_fpcr);
5478 cpu_alpha_store_fpcr(env, fpcr);
5483 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5485 unsigned long framesize)
5487 abi_ulong sp = env->ir[IR_SP];
5489 /* This is the X/Open sanctioned signal stack switching. */
5490 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5491 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5493 return (sp - framesize) & -32;
5496 static void setup_frame(int sig, struct target_sigaction *ka,
5497 target_sigset_t *set, CPUAlphaState *env)
5499 abi_ulong frame_addr, r26;
5500 struct target_sigframe *frame;
5503 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5504 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5508 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5510 if (ka->sa_restorer) {
5511 r26 = ka->sa_restorer;
5513 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5514 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5515 &frame->retcode[1]);
5516 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5521 unlock_user_struct(frame, frame_addr, 1);
5525 if (sig == TARGET_SIGSEGV) {
5526 ka->_sa_handler = TARGET_SIG_DFL;
5528 force_sig(TARGET_SIGSEGV);
5531 env->ir[IR_RA] = r26;
5532 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5533 env->ir[IR_A0] = sig;
5535 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5536 env->ir[IR_SP] = frame_addr;
5539 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5540 target_siginfo_t *info,
5541 target_sigset_t *set, CPUAlphaState *env)
5543 abi_ulong frame_addr, r26;
5544 struct target_rt_sigframe *frame;
5547 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5548 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5552 err |= copy_siginfo_to_user(&frame->info, info);
5554 err |= __put_user(0, &frame->uc.tuc_flags);
5555 err |= __put_user(0, &frame->uc.tuc_link);
5556 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5557 err |= __put_user(target_sigaltstack_used.ss_sp,
5558 &frame->uc.tuc_stack.ss_sp);
5559 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
5560 &frame->uc.tuc_stack.ss_flags);
5561 err |= __put_user(target_sigaltstack_used.ss_size,
5562 &frame->uc.tuc_stack.ss_size);
5563 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5564 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5565 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5568 if (ka->sa_restorer) {
5569 r26 = ka->sa_restorer;
5571 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5572 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5573 &frame->retcode[1]);
5574 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5581 if (sig == TARGET_SIGSEGV) {
5582 ka->_sa_handler = TARGET_SIG_DFL;
5584 force_sig(TARGET_SIGSEGV);
5587 env->ir[IR_RA] = r26;
5588 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5589 env->ir[IR_A0] = sig;
5590 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5591 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5592 env->ir[IR_SP] = frame_addr;
5595 long do_sigreturn(CPUAlphaState *env)
5597 struct target_sigcontext *sc;
5598 abi_ulong sc_addr = env->ir[IR_A0];
5599 target_sigset_t target_set;
5602 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5606 target_sigemptyset(&target_set);
5607 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5611 target_to_host_sigset_internal(&set, &target_set);
5612 do_sigprocmask(SIG_SETMASK, &set, NULL);
5614 if (restore_sigcontext(env, sc)) {
5617 unlock_user_struct(sc, sc_addr, 0);
5618 return env->ir[IR_V0];
5621 unlock_user_struct(sc, sc_addr, 0);
5622 force_sig(TARGET_SIGSEGV);
5625 long do_rt_sigreturn(CPUAlphaState *env)
5627 abi_ulong frame_addr = env->ir[IR_A0];
5628 struct target_rt_sigframe *frame;
5631 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5634 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5635 do_sigprocmask(SIG_SETMASK, &set, NULL);
5637 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5640 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5642 0, env->ir[IR_SP]) == -EFAULT) {
5646 unlock_user_struct(frame, frame_addr, 0);
5647 return env->ir[IR_V0];
5651 unlock_user_struct(frame, frame_addr, 0);
5652 force_sig(TARGET_SIGSEGV);
5657 static void setup_frame(int sig, struct target_sigaction *ka,
5658 target_sigset_t *set, CPUArchState *env)
5660 fprintf(stderr, "setup_frame: not implemented\n");
5663 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5664 target_siginfo_t *info,
5665 target_sigset_t *set, CPUArchState *env)
5667 fprintf(stderr, "setup_rt_frame: not implemented\n");
5670 long do_sigreturn(CPUArchState *env)
5672 fprintf(stderr, "do_sigreturn: not implemented\n");
5673 return -TARGET_ENOSYS;
5676 long do_rt_sigreturn(CPUArchState *env)
5678 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5679 return -TARGET_ENOSYS;
5684 void process_pending_signals(CPUArchState *cpu_env)
5686 CPUState *cpu = ENV_GET_CPU(cpu_env);
5689 sigset_t set, old_set;
5690 target_sigset_t target_old_set;
5691 struct emulated_sigtable *k;
5692 struct target_sigaction *sa;
5694 TaskState *ts = cpu->opaque;
5696 if (!ts->signal_pending)
5699 /* FIXME: This is not threadsafe. */
5701 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5706 /* if no signal is pending, just return */
5707 ts->signal_pending = 0;
5712 fprintf(stderr, "qemu: process signal %d\n", sig);
5714 /* dequeue signal */
5720 sig = gdb_handlesig(cpu, sig);
5723 handler = TARGET_SIG_IGN;
5725 sa = &sigact_table[sig - 1];
5726 handler = sa->_sa_handler;
5729 if (handler == TARGET_SIG_DFL) {
5730 /* default handler : ignore some signal. The other are job control or fatal */
5731 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5732 kill(getpid(),SIGSTOP);
5733 } else if (sig != TARGET_SIGCHLD &&
5734 sig != TARGET_SIGURG &&
5735 sig != TARGET_SIGWINCH &&
5736 sig != TARGET_SIGCONT) {
5739 } else if (handler == TARGET_SIG_IGN) {
5741 } else if (handler == TARGET_SIG_ERR) {
5744 /* compute the blocked signals during the handler execution */
5745 target_to_host_sigset(&set, &sa->sa_mask);
5746 /* SA_NODEFER indicates that the current signal should not be
5747 blocked during the handler */
5748 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5749 sigaddset(&set, target_to_host_signal(sig));
5751 /* block signals in the handler using Linux */
5752 do_sigprocmask(SIG_BLOCK, &set, &old_set);
5753 /* save the previous blocked signal state to restore it at the
5754 end of the signal execution (see do_sigreturn) */
5755 host_to_target_sigset_internal(&target_old_set, &old_set);
5757 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5758 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5760 CPUX86State *env = cpu_env;
5761 if (env->eflags & VM_MASK)
5762 save_v86_state(env);
5765 /* prepare the stack frame of the virtual CPU */
5766 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5767 /* These targets do not have traditional signals. */
5768 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5770 if (sa->sa_flags & TARGET_SA_SIGINFO)
5771 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5773 setup_frame(sig, sa, &target_old_set, cpu_env);
5775 if (sa->sa_flags & TARGET_SA_RESETHAND)
5776 sa->_sa_handler = TARGET_SIG_DFL;
5779 free_sigqueue(cpu_env, q);