2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include <sys/ucontext.h>
27 #include <sys/resource.h>
30 #include "qemu-common.h"
31 #include "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used = {
38 .ss_flags = TARGET_SS_DISABLE,
41 static struct target_sigaction sigact_table[TARGET_NSIG];
43 static void host_signal_handler(int host_signum, siginfo_t *info,
46 static uint8_t host_to_target_signal_table[_NSIG] = {
47 [SIGHUP] = TARGET_SIGHUP,
48 [SIGINT] = TARGET_SIGINT,
49 [SIGQUIT] = TARGET_SIGQUIT,
50 [SIGILL] = TARGET_SIGILL,
51 [SIGTRAP] = TARGET_SIGTRAP,
52 [SIGABRT] = TARGET_SIGABRT,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS] = TARGET_SIGBUS,
55 [SIGFPE] = TARGET_SIGFPE,
56 [SIGKILL] = TARGET_SIGKILL,
57 [SIGUSR1] = TARGET_SIGUSR1,
58 [SIGSEGV] = TARGET_SIGSEGV,
59 [SIGUSR2] = TARGET_SIGUSR2,
60 [SIGPIPE] = TARGET_SIGPIPE,
61 [SIGALRM] = TARGET_SIGALRM,
62 [SIGTERM] = TARGET_SIGTERM,
64 [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 [SIGCHLD] = TARGET_SIGCHLD,
67 [SIGCONT] = TARGET_SIGCONT,
68 [SIGSTOP] = TARGET_SIGSTOP,
69 [SIGTSTP] = TARGET_SIGTSTP,
70 [SIGTTIN] = TARGET_SIGTTIN,
71 [SIGTTOU] = TARGET_SIGTTOU,
72 [SIGURG] = TARGET_SIGURG,
73 [SIGXCPU] = TARGET_SIGXCPU,
74 [SIGXFSZ] = TARGET_SIGXFSZ,
75 [SIGVTALRM] = TARGET_SIGVTALRM,
76 [SIGPROF] = TARGET_SIGPROF,
77 [SIGWINCH] = TARGET_SIGWINCH,
78 [SIGIO] = TARGET_SIGIO,
79 [SIGPWR] = TARGET_SIGPWR,
80 [SIGSYS] = TARGET_SIGSYS,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN] = __SIGRTMAX,
87 [__SIGRTMAX] = __SIGRTMIN,
89 static uint8_t target_to_host_signal_table[_NSIG];
91 static inline int on_sig_stack(unsigned long sp)
93 return (sp - target_sigaltstack_used.ss_sp
94 < target_sigaltstack_used.ss_size);
97 static inline int sas_ss_flags(unsigned long sp)
99 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
100 : on_sig_stack(sp) ? SS_ONSTACK : 0);
103 int host_to_target_signal(int sig)
105 if (sig < 0 || sig >= _NSIG)
107 return host_to_target_signal_table[sig];
110 int target_to_host_signal(int sig)
112 if (sig < 0 || sig >= _NSIG)
114 return target_to_host_signal_table[sig];
117 static inline void target_sigemptyset(target_sigset_t *set)
119 memset(set, 0, sizeof(*set));
122 static inline void target_sigaddset(target_sigset_t *set, int signum)
125 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
126 set->sig[signum / TARGET_NSIG_BPW] |= mask;
129 static inline int target_sigismember(const target_sigset_t *set, int signum)
132 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
133 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
136 static void host_to_target_sigset_internal(target_sigset_t *d,
140 target_sigemptyset(d);
141 for (i = 1; i <= TARGET_NSIG; i++) {
142 if (sigismember(s, i)) {
143 target_sigaddset(d, host_to_target_signal(i));
148 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
153 host_to_target_sigset_internal(&d1, s);
154 for(i = 0;i < TARGET_NSIG_WORDS; i++)
155 d->sig[i] = tswapal(d1.sig[i]);
158 static void target_to_host_sigset_internal(sigset_t *d,
159 const target_sigset_t *s)
163 for (i = 1; i <= TARGET_NSIG; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
170 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
175 for(i = 0;i < TARGET_NSIG_WORDS; i++)
176 s1.sig[i] = tswapal(s->sig[i]);
177 target_to_host_sigset_internal(d, &s1);
180 void host_to_target_old_sigset(abi_ulong *old_sigset,
181 const sigset_t *sigset)
184 host_to_target_sigset(&d, sigset);
185 *old_sigset = d.sig[0];
188 void target_to_host_old_sigset(sigset_t *sigset,
189 const abi_ulong *old_sigset)
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS; i++)
197 target_to_host_sigset(sigset, &d);
200 /* siginfo conversion */
202 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
203 const siginfo_t *info)
205 int sig = host_to_target_signal(info->si_signo);
206 tinfo->si_signo = sig;
208 tinfo->si_code = info->si_code;
210 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
211 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
212 /* Should never come here, but who knows. The information for
213 the target is irrelevant. */
214 tinfo->_sifields._sigfault._addr = 0;
215 } else if (sig == TARGET_SIGIO) {
216 tinfo->_sifields._sigpoll._band = info->si_band;
217 tinfo->_sifields._sigpoll._fd = info->si_fd;
218 } else if (sig == TARGET_SIGCHLD) {
219 tinfo->_sifields._sigchld._pid = info->si_pid;
220 tinfo->_sifields._sigchld._uid = info->si_uid;
221 tinfo->_sifields._sigchld._status
222 = host_to_target_waitstatus(info->si_status);
223 tinfo->_sifields._sigchld._utime = info->si_utime;
224 tinfo->_sifields._sigchld._stime = info->si_stime;
225 } else if (sig >= TARGET_SIGRTMIN) {
226 tinfo->_sifields._rt._pid = info->si_pid;
227 tinfo->_sifields._rt._uid = info->si_uid;
228 /* XXX: potential problem if 64 bit */
229 tinfo->_sifields._rt._sigval.sival_ptr
230 = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
234 static void tswap_siginfo(target_siginfo_t *tinfo,
235 const target_siginfo_t *info)
237 int sig = info->si_signo;
238 tinfo->si_signo = tswap32(sig);
239 tinfo->si_errno = tswap32(info->si_errno);
240 tinfo->si_code = tswap32(info->si_code);
242 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
243 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
244 tinfo->_sifields._sigfault._addr
245 = tswapal(info->_sifields._sigfault._addr);
246 } else if (sig == TARGET_SIGIO) {
247 tinfo->_sifields._sigpoll._band
248 = tswap32(info->_sifields._sigpoll._band);
249 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
250 } else if (sig == TARGET_SIGCHLD) {
251 tinfo->_sifields._sigchld._pid
252 = tswap32(info->_sifields._sigchld._pid);
253 tinfo->_sifields._sigchld._uid
254 = tswap32(info->_sifields._sigchld._uid);
255 tinfo->_sifields._sigchld._status
256 = tswap32(info->_sifields._sigchld._status);
257 tinfo->_sifields._sigchld._utime
258 = tswapal(info->_sifields._sigchld._utime);
259 tinfo->_sifields._sigchld._stime
260 = tswapal(info->_sifields._sigchld._stime);
261 } else if (sig >= TARGET_SIGRTMIN) {
262 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
263 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
264 tinfo->_sifields._rt._sigval.sival_ptr
265 = tswapal(info->_sifields._rt._sigval.sival_ptr);
270 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
272 host_to_target_siginfo_noswap(tinfo, info);
273 tswap_siginfo(tinfo, tinfo);
276 /* XXX: we support only POSIX RT signals are used. */
277 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
278 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
280 info->si_signo = tswap32(tinfo->si_signo);
281 info->si_errno = tswap32(tinfo->si_errno);
282 info->si_code = tswap32(tinfo->si_code);
283 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
284 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
285 info->si_value.sival_ptr =
286 (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
289 static int fatal_signal (int sig)
294 case TARGET_SIGWINCH:
295 /* Ignored by default. */
302 /* Job control signals. */
309 /* returns 1 if given signal should dump core if not handled */
310 static int core_dump_signal(int sig)
326 void signal_init(void)
328 struct sigaction act;
329 struct sigaction oact;
333 /* generate signal conversion tables */
334 for(i = 1; i < _NSIG; i++) {
335 if (host_to_target_signal_table[i] == 0)
336 host_to_target_signal_table[i] = i;
338 for(i = 1; i < _NSIG; i++) {
339 j = host_to_target_signal_table[i];
340 target_to_host_signal_table[j] = i;
343 /* set all host signal handlers. ALL signals are blocked during
344 the handlers to serialize them. */
345 memset(sigact_table, 0, sizeof(sigact_table));
347 sigfillset(&act.sa_mask);
348 act.sa_flags = SA_SIGINFO;
349 act.sa_sigaction = host_signal_handler;
350 for(i = 1; i <= TARGET_NSIG; i++) {
351 host_sig = target_to_host_signal(i);
352 sigaction(host_sig, NULL, &oact);
353 if (oact.sa_sigaction == (void *)SIG_IGN) {
354 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
355 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
356 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
358 /* If there's already a handler installed then something has
359 gone horribly wrong, so don't even try to handle that case. */
360 /* Install some handlers for our own use. We need at least
361 SIGSEGV and SIGBUS, to detect exceptions. We can not just
362 trap all signals because it affects syscall interrupt
363 behavior. But do trap all default-fatal signals. */
364 if (fatal_signal (i))
365 sigaction(host_sig, &act, NULL);
369 /* signal queue handling */
371 static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
373 TaskState *ts = env->opaque;
374 struct sigqueue *q = ts->first_free;
377 ts->first_free = q->next;
381 static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
383 TaskState *ts = env->opaque;
384 q->next = ts->first_free;
388 /* abort execution with signal */
389 static void QEMU_NORETURN force_sig(int target_sig)
391 CPUArchState *env = thread_cpu->env_ptr;
392 TaskState *ts = (TaskState *)env->opaque;
393 int host_sig, core_dumped = 0;
394 struct sigaction act;
395 host_sig = target_to_host_signal(target_sig);
396 gdb_signalled(env, target_sig);
398 /* dump core if supported by target binary format */
399 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
402 ((*ts->bprm->core_dump)(target_sig, env) == 0);
405 /* we already dumped the core of target process, we don't want
406 * a coredump of qemu itself */
407 struct rlimit nodump;
408 getrlimit(RLIMIT_CORE, &nodump);
410 setrlimit(RLIMIT_CORE, &nodump);
411 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
412 target_sig, strsignal(host_sig), "core dumped" );
415 /* The proper exit code for dying from an uncaught signal is
416 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
417 * a negative value. To get the proper exit code we need to
418 * actually die from an uncaught signal. Here the default signal
419 * handler is installed, we send ourself a signal and we wait for
421 sigfillset(&act.sa_mask);
422 act.sa_handler = SIG_DFL;
424 sigaction(host_sig, &act, NULL);
426 /* For some reason raise(host_sig) doesn't send the signal when
427 * statically linked on x86-64. */
428 kill(getpid(), host_sig);
430 /* Make sure the signal isn't masked (just reuse the mask inside
432 sigdelset(&act.sa_mask, host_sig);
433 sigsuspend(&act.sa_mask);
439 /* queue a signal so that it will be send to the virtual CPU as soon
441 int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
443 TaskState *ts = env->opaque;
444 struct emulated_sigtable *k;
445 struct sigqueue *q, **pq;
449 #if defined(DEBUG_SIGNAL)
450 fprintf(stderr, "queue_signal: sig=%d\n",
453 k = &ts->sigtab[sig - 1];
454 queue = gdb_queuesig ();
455 handler = sigact_table[sig - 1]._sa_handler;
456 if (!queue && handler == TARGET_SIG_DFL) {
457 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
458 kill(getpid(),SIGSTOP);
461 /* default handler : ignore some signal. The other are fatal */
462 if (sig != TARGET_SIGCHLD &&
463 sig != TARGET_SIGURG &&
464 sig != TARGET_SIGWINCH &&
465 sig != TARGET_SIGCONT) {
468 return 0; /* indicate ignored */
470 } else if (!queue && handler == TARGET_SIG_IGN) {
473 } else if (!queue && handler == TARGET_SIG_ERR) {
477 if (sig < TARGET_SIGRTMIN) {
478 /* if non real time signal, we queue exactly one signal */
488 q = alloc_sigqueue(env);
499 /* signal that a new signal is pending */
500 ts->signal_pending = 1;
501 return 1; /* indicates that the signal was queued */
505 static void host_signal_handler(int host_signum, siginfo_t *info,
508 CPUArchState *env = thread_cpu->env_ptr;
510 target_siginfo_t tinfo;
512 /* the CPU emulator uses some host signals to detect exceptions,
513 we forward to it some signals */
514 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
515 && info->si_code > 0) {
516 if (cpu_signal_handler(host_signum, info, puc))
520 /* get target signal number */
521 sig = host_to_target_signal(host_signum);
522 if (sig < 1 || sig > TARGET_NSIG)
524 #if defined(DEBUG_SIGNAL)
525 fprintf(stderr, "qemu: got signal %d\n", sig);
527 host_to_target_siginfo_noswap(&tinfo, info);
528 if (queue_signal(env, sig, &tinfo) == 1) {
529 /* interrupt the virtual CPU as soon as possible */
530 cpu_exit(thread_cpu);
534 /* do_sigaltstack() returns target values and errnos. */
535 /* compare linux/kernel/signal.c:do_sigaltstack() */
536 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
539 struct target_sigaltstack oss;
541 /* XXX: test errors */
544 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
545 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
546 __put_user(sas_ss_flags(sp), &oss.ss_flags);
551 struct target_sigaltstack *uss;
552 struct target_sigaltstack ss;
554 ret = -TARGET_EFAULT;
555 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
556 || __get_user(ss.ss_sp, &uss->ss_sp)
557 || __get_user(ss.ss_size, &uss->ss_size)
558 || __get_user(ss.ss_flags, &uss->ss_flags))
560 unlock_user_struct(uss, uss_addr, 0);
563 if (on_sig_stack(sp))
566 ret = -TARGET_EINVAL;
567 if (ss.ss_flags != TARGET_SS_DISABLE
568 && ss.ss_flags != TARGET_SS_ONSTACK
572 if (ss.ss_flags == TARGET_SS_DISABLE) {
576 ret = -TARGET_ENOMEM;
577 if (ss.ss_size < MINSIGSTKSZ)
581 target_sigaltstack_used.ss_sp = ss.ss_sp;
582 target_sigaltstack_used.ss_size = ss.ss_size;
586 ret = -TARGET_EFAULT;
587 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
596 /* do_sigaction() return host values and errnos */
597 int do_sigaction(int sig, const struct target_sigaction *act,
598 struct target_sigaction *oact)
600 struct target_sigaction *k;
601 struct sigaction act1;
605 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
607 k = &sigact_table[sig - 1];
608 #if defined(DEBUG_SIGNAL)
609 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
613 __put_user(k->_sa_handler, &oact->_sa_handler);
614 __put_user(k->sa_flags, &oact->sa_flags);
615 #if !defined(TARGET_MIPS)
616 __put_user(k->sa_restorer, &oact->sa_restorer);
619 oact->sa_mask = k->sa_mask;
622 /* FIXME: This is not threadsafe. */
623 __get_user(k->_sa_handler, &act->_sa_handler);
624 __get_user(k->sa_flags, &act->sa_flags);
625 #if !defined(TARGET_MIPS)
626 __get_user(k->sa_restorer, &act->sa_restorer);
628 /* To be swapped in target_to_host_sigset. */
629 k->sa_mask = act->sa_mask;
631 /* we update the host linux signal state */
632 host_sig = target_to_host_signal(sig);
633 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
634 sigfillset(&act1.sa_mask);
635 act1.sa_flags = SA_SIGINFO;
636 if (k->sa_flags & TARGET_SA_RESTART)
637 act1.sa_flags |= SA_RESTART;
638 /* NOTE: it is important to update the host kernel signal
639 ignore state to avoid getting unexpected interrupted
641 if (k->_sa_handler == TARGET_SIG_IGN) {
642 act1.sa_sigaction = (void *)SIG_IGN;
643 } else if (k->_sa_handler == TARGET_SIG_DFL) {
644 if (fatal_signal (sig))
645 act1.sa_sigaction = host_signal_handler;
647 act1.sa_sigaction = (void *)SIG_DFL;
649 act1.sa_sigaction = host_signal_handler;
651 ret = sigaction(host_sig, &act1, NULL);
657 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
658 const target_siginfo_t *info)
660 tswap_siginfo(tinfo, info);
664 static inline int current_exec_domain_sig(int sig)
666 return /* current->exec_domain && current->exec_domain->signal_invmap
667 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
670 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
672 /* from the Linux kernel */
674 struct target_fpreg {
675 uint16_t significand[4];
679 struct target_fpxreg {
680 uint16_t significand[4];
685 struct target_xmmreg {
686 abi_ulong element[4];
689 struct target_fpstate {
690 /* Regular FPU environment */
698 struct target_fpreg _st[8];
700 uint16_t magic; /* 0xffff = regular FPU data only */
702 /* FXSR FPU environment */
703 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
706 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
707 struct target_xmmreg _xmm[8];
708 abi_ulong padding[56];
711 #define X86_FXSR_MAGIC 0x0000
713 struct target_sigcontext {
731 abi_ulong esp_at_signal;
733 abi_ulong fpstate; /* pointer */
738 struct target_ucontext {
741 target_stack_t tuc_stack;
742 struct target_sigcontext tuc_mcontext;
743 target_sigset_t tuc_sigmask; /* mask last for extensibility */
750 struct target_sigcontext sc;
751 struct target_fpstate fpstate;
752 abi_ulong extramask[TARGET_NSIG_WORDS-1];
762 struct target_siginfo info;
763 struct target_ucontext uc;
764 struct target_fpstate fpstate;
769 * Set up a signal frame.
772 /* XXX: save x87 state */
774 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
775 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
780 /* already locked in setup_frame() */
781 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
782 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
783 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
784 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
785 err |= __put_user(env->regs[R_EDI], &sc->edi);
786 err |= __put_user(env->regs[R_ESI], &sc->esi);
787 err |= __put_user(env->regs[R_EBP], &sc->ebp);
788 err |= __put_user(env->regs[R_ESP], &sc->esp);
789 err |= __put_user(env->regs[R_EBX], &sc->ebx);
790 err |= __put_user(env->regs[R_EDX], &sc->edx);
791 err |= __put_user(env->regs[R_ECX], &sc->ecx);
792 err |= __put_user(env->regs[R_EAX], &sc->eax);
793 err |= __put_user(env->exception_index, &sc->trapno);
794 err |= __put_user(env->error_code, &sc->err);
795 err |= __put_user(env->eip, &sc->eip);
796 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
797 err |= __put_user(env->eflags, &sc->eflags);
798 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
799 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
801 cpu_x86_fsave(env, fpstate_addr, 1);
802 fpstate->status = fpstate->sw;
804 err |= __put_user(magic, &fpstate->magic);
805 err |= __put_user(fpstate_addr, &sc->fpstate);
807 /* non-iBCS2 extensions.. */
808 err |= __put_user(mask, &sc->oldmask);
809 err |= __put_user(env->cr[2], &sc->cr2);
814 * Determine which stack to use..
817 static inline abi_ulong
818 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
822 /* Default to using normal stack */
823 esp = env->regs[R_ESP];
824 /* This is the X/Open sanctioned signal stack switching. */
825 if (ka->sa_flags & TARGET_SA_ONSTACK) {
826 if (sas_ss_flags(esp) == 0)
827 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
830 /* This is the legacy signal stack switching. */
832 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
833 !(ka->sa_flags & TARGET_SA_RESTORER) &&
835 esp = (unsigned long) ka->sa_restorer;
837 return (esp - frame_size) & -8ul;
840 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
841 static void setup_frame(int sig, struct target_sigaction *ka,
842 target_sigset_t *set, CPUX86State *env)
844 abi_ulong frame_addr;
845 struct sigframe *frame;
848 frame_addr = get_sigframe(ka, env, sizeof(*frame));
850 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
853 err |= __put_user(current_exec_domain_sig(sig),
858 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
859 frame_addr + offsetof(struct sigframe, fpstate));
863 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
864 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
868 /* Set up to return from userspace. If provided, use a stub
869 already in userspace. */
870 if (ka->sa_flags & TARGET_SA_RESTORER) {
871 err |= __put_user(ka->sa_restorer, &frame->pretcode);
874 abi_ulong retcode_addr;
875 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
876 err |= __put_user(retcode_addr, &frame->pretcode);
877 /* This is popl %eax ; movl $,%eax ; int $0x80 */
879 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
880 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
882 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
888 /* Set up registers for signal handler */
889 env->regs[R_ESP] = frame_addr;
890 env->eip = ka->_sa_handler;
892 cpu_x86_load_seg(env, R_DS, __USER_DS);
893 cpu_x86_load_seg(env, R_ES, __USER_DS);
894 cpu_x86_load_seg(env, R_SS, __USER_DS);
895 cpu_x86_load_seg(env, R_CS, __USER_CS);
896 env->eflags &= ~TF_MASK;
898 unlock_user_struct(frame, frame_addr, 1);
903 unlock_user_struct(frame, frame_addr, 1);
904 if (sig == TARGET_SIGSEGV)
905 ka->_sa_handler = TARGET_SIG_DFL;
906 force_sig(TARGET_SIGSEGV /* , current */);
909 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
910 static void setup_rt_frame(int sig, struct target_sigaction *ka,
911 target_siginfo_t *info,
912 target_sigset_t *set, CPUX86State *env)
914 abi_ulong frame_addr, addr;
915 struct rt_sigframe *frame;
918 frame_addr = get_sigframe(ka, env, sizeof(*frame));
920 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
923 err |= __put_user(current_exec_domain_sig(sig),
925 addr = frame_addr + offsetof(struct rt_sigframe, info);
926 err |= __put_user(addr, &frame->pinfo);
927 addr = frame_addr + offsetof(struct rt_sigframe, uc);
928 err |= __put_user(addr, &frame->puc);
929 err |= copy_siginfo_to_user(&frame->info, info);
933 /* Create the ucontext. */
934 err |= __put_user(0, &frame->uc.tuc_flags);
935 err |= __put_user(0, &frame->uc.tuc_link);
936 err |= __put_user(target_sigaltstack_used.ss_sp,
937 &frame->uc.tuc_stack.ss_sp);
938 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
939 &frame->uc.tuc_stack.ss_flags);
940 err |= __put_user(target_sigaltstack_used.ss_size,
941 &frame->uc.tuc_stack.ss_size);
942 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
944 frame_addr + offsetof(struct rt_sigframe, fpstate));
945 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
946 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
950 /* Set up to return from userspace. If provided, use a stub
951 already in userspace. */
952 if (ka->sa_flags & TARGET_SA_RESTORER) {
953 err |= __put_user(ka->sa_restorer, &frame->pretcode);
956 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
957 err |= __put_user(addr, &frame->pretcode);
958 /* This is movl $,%eax ; int $0x80 */
959 err |= __put_user(0xb8, (char *)(frame->retcode+0));
960 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
962 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
968 /* Set up registers for signal handler */
969 env->regs[R_ESP] = frame_addr;
970 env->eip = ka->_sa_handler;
972 cpu_x86_load_seg(env, R_DS, __USER_DS);
973 cpu_x86_load_seg(env, R_ES, __USER_DS);
974 cpu_x86_load_seg(env, R_SS, __USER_DS);
975 cpu_x86_load_seg(env, R_CS, __USER_CS);
976 env->eflags &= ~TF_MASK;
978 unlock_user_struct(frame, frame_addr, 1);
983 unlock_user_struct(frame, frame_addr, 1);
984 if (sig == TARGET_SIGSEGV)
985 ka->_sa_handler = TARGET_SIG_DFL;
986 force_sig(TARGET_SIGSEGV /* , current */);
990 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
992 unsigned int err = 0;
993 abi_ulong fpstate_addr;
994 unsigned int tmpflags;
996 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
997 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
998 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
999 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
1001 env->regs[R_EDI] = tswapl(sc->edi);
1002 env->regs[R_ESI] = tswapl(sc->esi);
1003 env->regs[R_EBP] = tswapl(sc->ebp);
1004 env->regs[R_ESP] = tswapl(sc->esp);
1005 env->regs[R_EBX] = tswapl(sc->ebx);
1006 env->regs[R_EDX] = tswapl(sc->edx);
1007 env->regs[R_ECX] = tswapl(sc->ecx);
1008 env->eip = tswapl(sc->eip);
1010 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
1011 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
1013 tmpflags = tswapl(sc->eflags);
1014 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1015 // regs->orig_eax = -1; /* disable syscall checks */
1017 fpstate_addr = tswapl(sc->fpstate);
1018 if (fpstate_addr != 0) {
1019 if (!access_ok(VERIFY_READ, fpstate_addr,
1020 sizeof(struct target_fpstate)))
1022 cpu_x86_frstor(env, fpstate_addr, 1);
1025 *peax = tswapl(sc->eax);
1031 long do_sigreturn(CPUX86State *env)
1033 struct sigframe *frame;
1034 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1035 target_sigset_t target_set;
1039 #if defined(DEBUG_SIGNAL)
1040 fprintf(stderr, "do_sigreturn\n");
1042 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1044 /* set blocked signals */
1045 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1047 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1048 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1052 target_to_host_sigset_internal(&set, &target_set);
1053 sigprocmask(SIG_SETMASK, &set, NULL);
1055 /* restore registers */
1056 if (restore_sigcontext(env, &frame->sc, &eax))
1058 unlock_user_struct(frame, frame_addr, 0);
1062 unlock_user_struct(frame, frame_addr, 0);
1063 force_sig(TARGET_SIGSEGV);
1067 long do_rt_sigreturn(CPUX86State *env)
1069 abi_ulong frame_addr;
1070 struct rt_sigframe *frame;
1074 frame_addr = env->regs[R_ESP] - 4;
1075 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1077 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1078 sigprocmask(SIG_SETMASK, &set, NULL);
1080 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1083 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1084 get_sp_from_cpustate(env)) == -EFAULT)
1087 unlock_user_struct(frame, frame_addr, 0);
1091 unlock_user_struct(frame, frame_addr, 0);
1092 force_sig(TARGET_SIGSEGV);
1096 #elif defined(TARGET_AARCH64)
1098 struct target_sigcontext {
1099 uint64_t fault_address;
1100 /* AArch64 registers */
1105 /* 4K reserved for FP/SIMD state and future expansion */
1106 char __reserved[4096] __attribute__((__aligned__(16)));
1109 struct target_ucontext {
1110 abi_ulong tuc_flags;
1112 target_stack_t tuc_stack;
1113 target_sigset_t tuc_sigmask;
1114 /* glibc uses a 1024-bit sigset_t */
1115 char __unused[1024 / 8 - sizeof(target_sigset_t)];
1116 /* last for future expansion */
1117 struct target_sigcontext tuc_mcontext;
1121 * Header to be used at the beginning of structures extending the user
1122 * context. Such structures must be placed after the rt_sigframe on the stack
1123 * and be 16-byte aligned. The last structure must be a dummy one with the
1124 * magic and size set to 0.
1126 struct target_aarch64_ctx {
1131 #define TARGET_FPSIMD_MAGIC 0x46508001
1133 struct target_fpsimd_context {
1134 struct target_aarch64_ctx head;
1137 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
1141 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1142 * user space as it will change with the addition of new context. User space
1143 * should check the magic/size information.
1145 struct target_aux_context {
1146 struct target_fpsimd_context fpsimd;
1147 /* additional context to be added before "end" */
1148 struct target_aarch64_ctx end;
1151 struct target_rt_sigframe {
1152 struct target_siginfo info;
1153 struct target_ucontext uc;
1159 static int target_setup_sigframe(struct target_rt_sigframe *sf,
1160 CPUARMState *env, target_sigset_t *set)
1163 struct target_aux_context *aux =
1164 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1166 /* set up the stack frame for unwinding */
1167 __put_user(env->xregs[29], &sf->fp);
1168 __put_user(env->xregs[30], &sf->lr);
1170 for (i = 0; i < 31; i++) {
1171 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1173 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1174 __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
1175 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
1177 __put_user(/*current->thread.fault_address*/ 0,
1178 &sf->uc.tuc_mcontext.fault_address);
1180 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
1181 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
1184 for (i = 0; i < 32; i++) {
1185 #ifdef TARGET_WORDS_BIGENDIAN
1186 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1187 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1189 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1190 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1193 __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
1194 __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
1195 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
1196 __put_user(sizeof(struct target_fpsimd_context),
1197 &aux->fpsimd.head.size);
1199 /* set the "end" magic */
1200 __put_user(0, &aux->end.magic);
1201 __put_user(0, &aux->end.size);
1206 static int target_restore_sigframe(CPUARMState *env,
1207 struct target_rt_sigframe *sf)
1211 struct target_aux_context *aux =
1212 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1213 uint32_t magic, size, fpsr, fpcr;
1216 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1217 sigprocmask(SIG_SETMASK, &set, NULL);
1219 for (i = 0; i < 31; i++) {
1220 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1223 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1224 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
1225 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
1226 pstate_write(env, pstate);
1228 __get_user(magic, &aux->fpsimd.head.magic);
1229 __get_user(size, &aux->fpsimd.head.size);
1231 if (magic != TARGET_FPSIMD_MAGIC
1232 || size != sizeof(struct target_fpsimd_context)) {
1236 for (i = 0; i < 32; i++) {
1237 #ifdef TARGET_WORDS_BIGENDIAN
1238 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1239 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1241 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1242 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1245 __get_user(fpsr, &aux->fpsimd.fpsr);
1246 vfp_set_fpsr(env, fpsr);
1247 __get_user(fpcr, &aux->fpsimd.fpcr);
1248 vfp_set_fpcr(env, fpcr);
1253 static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1257 sp = env->xregs[31];
1260 * This is the X/Open sanctioned signal stack switching.
1262 if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
1263 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1266 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1271 static void target_setup_frame(int usig, struct target_sigaction *ka,
1272 target_siginfo_t *info, target_sigset_t *set,
1275 struct target_rt_sigframe *frame;
1276 abi_ulong frame_addr, return_addr;
1278 frame_addr = get_sigframe(ka, env);
1279 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1283 __put_user(0, &frame->uc.tuc_flags);
1284 __put_user(0, &frame->uc.tuc_link);
1286 __put_user(target_sigaltstack_used.ss_sp,
1287 &frame->uc.tuc_stack.ss_sp);
1288 __put_user(sas_ss_flags(env->xregs[31]),
1289 &frame->uc.tuc_stack.ss_flags);
1290 __put_user(target_sigaltstack_used.ss_size,
1291 &frame->uc.tuc_stack.ss_size);
1292 target_setup_sigframe(frame, env, set);
1293 if (ka->sa_flags & TARGET_SA_RESTORER) {
1294 return_addr = ka->sa_restorer;
1296 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1297 __put_user(0xd2801168, &frame->tramp[0]);
1298 __put_user(0xd4000001, &frame->tramp[1]);
1299 return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
1301 env->xregs[0] = usig;
1302 env->xregs[31] = frame_addr;
1303 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
1304 env->pc = ka->_sa_handler;
1305 env->xregs[30] = return_addr;
1307 if (copy_siginfo_to_user(&frame->info, info)) {
1310 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1311 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1314 unlock_user_struct(frame, frame_addr, 1);
1318 unlock_user_struct(frame, frame_addr, 1);
1319 force_sig(TARGET_SIGSEGV);
1322 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1323 target_siginfo_t *info, target_sigset_t *set,
1326 target_setup_frame(sig, ka, info, set, env);
1329 static void setup_frame(int sig, struct target_sigaction *ka,
1330 target_sigset_t *set, CPUARMState *env)
1332 target_setup_frame(sig, ka, 0, set, env);
1335 long do_rt_sigreturn(CPUARMState *env)
1337 struct target_rt_sigframe *frame;
1338 abi_ulong frame_addr = env->xregs[31];
1340 if (frame_addr & 15) {
1344 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1348 if (target_restore_sigframe(env, frame)) {
1352 if (do_sigaltstack(frame_addr +
1353 offsetof(struct target_rt_sigframe, uc.tuc_stack),
1354 0, get_sp_from_cpustate(env)) == -EFAULT) {
1358 unlock_user_struct(frame, frame_addr, 0);
1359 return env->xregs[0];
1362 unlock_user_struct(frame, frame_addr, 0);
1363 force_sig(TARGET_SIGSEGV);
1367 long do_sigreturn(CPUARMState *env)
1369 return do_rt_sigreturn(env);
1372 #elif defined(TARGET_ARM)
1374 struct target_sigcontext {
1376 abi_ulong error_code;
1395 abi_ulong fault_address;
1398 struct target_ucontext_v1 {
1399 abi_ulong tuc_flags;
1401 target_stack_t tuc_stack;
1402 struct target_sigcontext tuc_mcontext;
1403 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1406 struct target_ucontext_v2 {
1407 abi_ulong tuc_flags;
1409 target_stack_t tuc_stack;
1410 struct target_sigcontext tuc_mcontext;
1411 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1412 char __unused[128 - sizeof(target_sigset_t)];
1413 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1416 struct target_user_vfp {
1417 uint64_t fpregs[32];
1421 struct target_user_vfp_exc {
1427 struct target_vfp_sigframe {
1430 struct target_user_vfp ufp;
1431 struct target_user_vfp_exc ufp_exc;
1432 } __attribute__((__aligned__(8)));
1434 struct target_iwmmxt_sigframe {
1438 /* Note that not all the coprocessor control registers are stored here */
1445 } __attribute__((__aligned__(8)));
1447 #define TARGET_VFP_MAGIC 0x56465001
1448 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1452 struct target_sigcontext sc;
1453 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1459 struct target_ucontext_v2 uc;
1463 struct rt_sigframe_v1
1467 struct target_siginfo info;
1468 struct target_ucontext_v1 uc;
1472 struct rt_sigframe_v2
1474 struct target_siginfo info;
1475 struct target_ucontext_v2 uc;
1479 #define TARGET_CONFIG_CPU_32 1
1482 * For ARM syscalls, we encode the syscall number into the instruction.
1484 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1485 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1488 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1489 * need two 16-bit instructions.
1491 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1492 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1494 static const abi_ulong retcodes[4] = {
1495 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1496 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1500 #define __get_user_error(x,p,e) __get_user(x, p)
1502 static inline int valid_user_regs(CPUARMState *regs)
1508 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1509 CPUARMState *env, abi_ulong mask)
1511 __put_user(env->regs[0], &sc->arm_r0);
1512 __put_user(env->regs[1], &sc->arm_r1);
1513 __put_user(env->regs[2], &sc->arm_r2);
1514 __put_user(env->regs[3], &sc->arm_r3);
1515 __put_user(env->regs[4], &sc->arm_r4);
1516 __put_user(env->regs[5], &sc->arm_r5);
1517 __put_user(env->regs[6], &sc->arm_r6);
1518 __put_user(env->regs[7], &sc->arm_r7);
1519 __put_user(env->regs[8], &sc->arm_r8);
1520 __put_user(env->regs[9], &sc->arm_r9);
1521 __put_user(env->regs[10], &sc->arm_r10);
1522 __put_user(env->regs[11], &sc->arm_fp);
1523 __put_user(env->regs[12], &sc->arm_ip);
1524 __put_user(env->regs[13], &sc->arm_sp);
1525 __put_user(env->regs[14], &sc->arm_lr);
1526 __put_user(env->regs[15], &sc->arm_pc);
1527 #ifdef TARGET_CONFIG_CPU_32
1528 __put_user(cpsr_read(env), &sc->arm_cpsr);
1531 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1532 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1533 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1534 __put_user(mask, &sc->oldmask);
1537 static inline abi_ulong
1538 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1540 unsigned long sp = regs->regs[13];
1543 * This is the X/Open sanctioned signal stack switching.
1545 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1546 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1548 * ATPCS B01 mandates 8-byte alignment
1550 return (sp - framesize) & ~7;
1554 setup_return(CPUARMState *env, struct target_sigaction *ka,
1555 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1557 abi_ulong handler = ka->_sa_handler;
1559 int thumb = handler & 1;
1560 uint32_t cpsr = cpsr_read(env);
1569 if (ka->sa_flags & TARGET_SA_RESTORER) {
1570 retcode = ka->sa_restorer;
1572 unsigned int idx = thumb;
1574 if (ka->sa_flags & TARGET_SA_SIGINFO)
1577 if (__put_user(retcodes[idx], rc))
1580 retcode = rc_addr + thumb;
1583 env->regs[0] = usig;
1584 env->regs[13] = frame_addr;
1585 env->regs[14] = retcode;
1586 env->regs[15] = handler & (thumb ? ~1 : ~3);
1587 cpsr_write(env, cpsr, 0xffffffff);
1592 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1595 struct target_vfp_sigframe *vfpframe;
1596 vfpframe = (struct target_vfp_sigframe *)regspace;
1597 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1598 __put_user(sizeof(*vfpframe), &vfpframe->size);
1599 for (i = 0; i < 32; i++) {
1600 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1602 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1603 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1604 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1605 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1606 return (abi_ulong*)(vfpframe+1);
1609 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1613 struct target_iwmmxt_sigframe *iwmmxtframe;
1614 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1615 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1616 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1617 for (i = 0; i < 16; i++) {
1618 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1620 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1621 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1622 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1623 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1624 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1625 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1626 return (abi_ulong*)(iwmmxtframe+1);
1629 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1630 target_sigset_t *set, CPUARMState *env)
1632 struct target_sigaltstack stack;
1634 abi_ulong *regspace;
1636 /* Clear all the bits of the ucontext we don't use. */
1637 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1639 memset(&stack, 0, sizeof(stack));
1640 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1641 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1642 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1643 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1645 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1646 /* Save coprocessor signal frame. */
1647 regspace = uc->tuc_regspace;
1648 if (arm_feature(env, ARM_FEATURE_VFP)) {
1649 regspace = setup_sigframe_v2_vfp(regspace, env);
1651 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1652 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1655 /* Write terminating magic word */
1656 __put_user(0, regspace);
1658 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1659 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1663 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1664 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1665 target_sigset_t *set, CPUARMState *regs)
1667 struct sigframe_v1 *frame;
1668 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1671 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1674 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1676 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1677 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1681 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1682 frame_addr + offsetof(struct sigframe_v1, retcode));
1685 unlock_user_struct(frame, frame_addr, 1);
1688 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1689 target_sigset_t *set, CPUARMState *regs)
1691 struct sigframe_v2 *frame;
1692 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1694 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1697 setup_sigframe_v2(&frame->uc, set, regs);
1699 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1700 frame_addr + offsetof(struct sigframe_v2, retcode));
1702 unlock_user_struct(frame, frame_addr, 1);
1705 static void setup_frame(int usig, struct target_sigaction *ka,
1706 target_sigset_t *set, CPUARMState *regs)
1708 if (get_osversion() >= 0x020612) {
1709 setup_frame_v2(usig, ka, set, regs);
1711 setup_frame_v1(usig, ka, set, regs);
1715 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1716 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1717 target_siginfo_t *info,
1718 target_sigset_t *set, CPUARMState *env)
1720 struct rt_sigframe_v1 *frame;
1721 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1722 struct target_sigaltstack stack;
1724 abi_ulong info_addr, uc_addr;
1726 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1729 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1730 __put_user(info_addr, &frame->pinfo);
1731 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1732 __put_user(uc_addr, &frame->puc);
1733 copy_siginfo_to_user(&frame->info, info);
1735 /* Clear all the bits of the ucontext we don't use. */
1736 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1738 memset(&stack, 0, sizeof(stack));
1739 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1740 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1741 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1742 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1744 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1745 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1746 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1750 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1751 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1753 env->regs[1] = info_addr;
1754 env->regs[2] = uc_addr;
1757 unlock_user_struct(frame, frame_addr, 1);
1760 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1761 target_siginfo_t *info,
1762 target_sigset_t *set, CPUARMState *env)
1764 struct rt_sigframe_v2 *frame;
1765 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1766 abi_ulong info_addr, uc_addr;
1768 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1771 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1772 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1773 copy_siginfo_to_user(&frame->info, info);
1775 setup_sigframe_v2(&frame->uc, set, env);
1777 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1778 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1780 env->regs[1] = info_addr;
1781 env->regs[2] = uc_addr;
1783 unlock_user_struct(frame, frame_addr, 1);
1786 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1787 target_siginfo_t *info,
1788 target_sigset_t *set, CPUARMState *env)
1790 if (get_osversion() >= 0x020612) {
1791 setup_rt_frame_v2(usig, ka, info, set, env);
1793 setup_rt_frame_v1(usig, ka, info, set, env);
1798 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1803 __get_user_error(env->regs[0], &sc->arm_r0, err);
1804 __get_user_error(env->regs[1], &sc->arm_r1, err);
1805 __get_user_error(env->regs[2], &sc->arm_r2, err);
1806 __get_user_error(env->regs[3], &sc->arm_r3, err);
1807 __get_user_error(env->regs[4], &sc->arm_r4, err);
1808 __get_user_error(env->regs[5], &sc->arm_r5, err);
1809 __get_user_error(env->regs[6], &sc->arm_r6, err);
1810 __get_user_error(env->regs[7], &sc->arm_r7, err);
1811 __get_user_error(env->regs[8], &sc->arm_r8, err);
1812 __get_user_error(env->regs[9], &sc->arm_r9, err);
1813 __get_user_error(env->regs[10], &sc->arm_r10, err);
1814 __get_user_error(env->regs[11], &sc->arm_fp, err);
1815 __get_user_error(env->regs[12], &sc->arm_ip, err);
1816 __get_user_error(env->regs[13], &sc->arm_sp, err);
1817 __get_user_error(env->regs[14], &sc->arm_lr, err);
1818 __get_user_error(env->regs[15], &sc->arm_pc, err);
1819 #ifdef TARGET_CONFIG_CPU_32
1820 __get_user_error(cpsr, &sc->arm_cpsr, err);
1821 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1824 err |= !valid_user_regs(env);
1829 static long do_sigreturn_v1(CPUARMState *env)
1831 abi_ulong frame_addr;
1832 struct sigframe_v1 *frame = NULL;
1833 target_sigset_t set;
1838 * Since we stacked the signal on a 64-bit boundary,
1839 * then 'sp' should be word aligned here. If it's
1840 * not, then the user is trying to mess with us.
1842 frame_addr = env->regs[13];
1843 if (frame_addr & 7) {
1847 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1850 if (__get_user(set.sig[0], &frame->sc.oldmask))
1852 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1853 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1857 target_to_host_sigset_internal(&host_set, &set);
1858 sigprocmask(SIG_SETMASK, &host_set, NULL);
1860 if (restore_sigcontext(env, &frame->sc))
1864 /* Send SIGTRAP if we're single-stepping */
1865 if (ptrace_cancel_bpt(current))
1866 send_sig(SIGTRAP, current, 1);
1868 unlock_user_struct(frame, frame_addr, 0);
1869 return env->regs[0];
1872 unlock_user_struct(frame, frame_addr, 0);
1873 force_sig(TARGET_SIGSEGV /* , current */);
1877 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1880 abi_ulong magic, sz;
1881 uint32_t fpscr, fpexc;
1882 struct target_vfp_sigframe *vfpframe;
1883 vfpframe = (struct target_vfp_sigframe *)regspace;
1885 __get_user(magic, &vfpframe->magic);
1886 __get_user(sz, &vfpframe->size);
1887 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1890 for (i = 0; i < 32; i++) {
1891 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1893 __get_user(fpscr, &vfpframe->ufp.fpscr);
1894 vfp_set_fpscr(env, fpscr);
1895 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1896 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1897 * and the exception flag is cleared
1900 fpexc &= ~((1 << 31) | (1 << 28));
1901 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1902 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1903 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1904 return (abi_ulong*)(vfpframe + 1);
1907 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1908 abi_ulong *regspace)
1911 abi_ulong magic, sz;
1912 struct target_iwmmxt_sigframe *iwmmxtframe;
1913 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1915 __get_user(magic, &iwmmxtframe->magic);
1916 __get_user(sz, &iwmmxtframe->size);
1917 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1920 for (i = 0; i < 16; i++) {
1921 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1923 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1924 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1925 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1926 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1927 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1928 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1929 return (abi_ulong*)(iwmmxtframe + 1);
1932 static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1933 struct target_ucontext_v2 *uc)
1936 abi_ulong *regspace;
1938 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1939 sigprocmask(SIG_SETMASK, &host_set, NULL);
1941 if (restore_sigcontext(env, &uc->tuc_mcontext))
1944 /* Restore coprocessor signal frame */
1945 regspace = uc->tuc_regspace;
1946 if (arm_feature(env, ARM_FEATURE_VFP)) {
1947 regspace = restore_sigframe_v2_vfp(env, regspace);
1952 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1953 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1959 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1963 /* Send SIGTRAP if we're single-stepping */
1964 if (ptrace_cancel_bpt(current))
1965 send_sig(SIGTRAP, current, 1);
1971 static long do_sigreturn_v2(CPUARMState *env)
1973 abi_ulong frame_addr;
1974 struct sigframe_v2 *frame = NULL;
1977 * Since we stacked the signal on a 64-bit boundary,
1978 * then 'sp' should be word aligned here. If it's
1979 * not, then the user is trying to mess with us.
1981 frame_addr = env->regs[13];
1982 if (frame_addr & 7) {
1986 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1989 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1992 unlock_user_struct(frame, frame_addr, 0);
1993 return env->regs[0];
1996 unlock_user_struct(frame, frame_addr, 0);
1997 force_sig(TARGET_SIGSEGV /* , current */);
2001 long do_sigreturn(CPUARMState *env)
2003 if (get_osversion() >= 0x020612) {
2004 return do_sigreturn_v2(env);
2006 return do_sigreturn_v1(env);
2010 static long do_rt_sigreturn_v1(CPUARMState *env)
2012 abi_ulong frame_addr;
2013 struct rt_sigframe_v1 *frame = NULL;
2017 * Since we stacked the signal on a 64-bit boundary,
2018 * then 'sp' should be word aligned here. If it's
2019 * not, then the user is trying to mess with us.
2021 frame_addr = env->regs[13];
2022 if (frame_addr & 7) {
2026 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2029 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2030 sigprocmask(SIG_SETMASK, &host_set, NULL);
2032 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2035 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2039 /* Send SIGTRAP if we're single-stepping */
2040 if (ptrace_cancel_bpt(current))
2041 send_sig(SIGTRAP, current, 1);
2043 unlock_user_struct(frame, frame_addr, 0);
2044 return env->regs[0];
2047 unlock_user_struct(frame, frame_addr, 0);
2048 force_sig(TARGET_SIGSEGV /* , current */);
2052 static long do_rt_sigreturn_v2(CPUARMState *env)
2054 abi_ulong frame_addr;
2055 struct rt_sigframe_v2 *frame = NULL;
2058 * Since we stacked the signal on a 64-bit boundary,
2059 * then 'sp' should be word aligned here. If it's
2060 * not, then the user is trying to mess with us.
2062 frame_addr = env->regs[13];
2063 if (frame_addr & 7) {
2067 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2070 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2073 unlock_user_struct(frame, frame_addr, 0);
2074 return env->regs[0];
2077 unlock_user_struct(frame, frame_addr, 0);
2078 force_sig(TARGET_SIGSEGV /* , current */);
2082 long do_rt_sigreturn(CPUARMState *env)
2084 if (get_osversion() >= 0x020612) {
2085 return do_rt_sigreturn_v2(env);
2087 return do_rt_sigreturn_v1(env);
2091 #elif defined(TARGET_SPARC)
2093 #define __SUNOS_MAXWIN 31
2095 /* This is what SunOS does, so shall I. */
2096 struct target_sigcontext {
2097 abi_ulong sigc_onstack; /* state to restore */
2099 abi_ulong sigc_mask; /* sigmask to restore */
2100 abi_ulong sigc_sp; /* stack pointer */
2101 abi_ulong sigc_pc; /* program counter */
2102 abi_ulong sigc_npc; /* next program counter */
2103 abi_ulong sigc_psr; /* for condition codes etc */
2104 abi_ulong sigc_g1; /* User uses these two registers */
2105 abi_ulong sigc_o0; /* within the trampoline code. */
2107 /* Now comes information regarding the users window set
2108 * at the time of the signal.
2110 abi_ulong sigc_oswins; /* outstanding windows */
2112 /* stack ptrs for each regwin buf */
2113 char *sigc_spbuf[__SUNOS_MAXWIN];
2115 /* Windows to restore after signal */
2117 abi_ulong locals[8];
2119 } sigc_wbuf[__SUNOS_MAXWIN];
2121 /* A Sparc stack frame */
2122 struct sparc_stackf {
2123 abi_ulong locals[8];
2125 /* It's simpler to treat fp and callers_pc as elements of ins[]
2126 * since we never need to access them ourselves.
2130 abi_ulong xxargs[1];
2139 abi_ulong u_regs[16]; /* globals and ins */
2145 abi_ulong si_float_regs[32];
2146 unsigned long si_fsr;
2147 unsigned long si_fpqdepth;
2149 unsigned long *insn_addr;
2152 } qemu_siginfo_fpu_t;
2155 struct target_signal_frame {
2156 struct sparc_stackf ss;
2159 abi_ulong insns[2] __attribute__ ((aligned (8)));
2160 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
2161 abi_ulong extra_size; /* Should be 0 */
2162 qemu_siginfo_fpu_t fpu_state;
2164 struct target_rt_signal_frame {
2165 struct sparc_stackf ss;
2170 unsigned int insns[2];
2172 unsigned int extra_size; /* Should be 0 */
2173 qemu_siginfo_fpu_t fpu_state;
2187 #define UREG_FP UREG_I6
2188 #define UREG_SP UREG_O6
2190 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2192 unsigned long framesize)
2196 sp = env->regwptr[UREG_FP];
2198 /* This is the X/Open sanctioned signal stack switching. */
2199 if (sa->sa_flags & TARGET_SA_ONSTACK) {
2200 if (!on_sig_stack(sp)
2201 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2202 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2204 return sp - framesize;
2208 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2212 err |= __put_user(env->psr, &si->si_regs.psr);
2213 err |= __put_user(env->pc, &si->si_regs.pc);
2214 err |= __put_user(env->npc, &si->si_regs.npc);
2215 err |= __put_user(env->y, &si->si_regs.y);
2216 for (i=0; i < 8; i++) {
2217 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
2219 for (i=0; i < 8; i++) {
2220 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2222 err |= __put_user(mask, &si->si_mask);
2228 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2229 CPUSPARCState *env, unsigned long mask)
2233 err |= __put_user(mask, &sc->sigc_mask);
2234 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
2235 err |= __put_user(env->pc, &sc->sigc_pc);
2236 err |= __put_user(env->npc, &sc->sigc_npc);
2237 err |= __put_user(env->psr, &sc->sigc_psr);
2238 err |= __put_user(env->gregs[1], &sc->sigc_g1);
2239 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
2244 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2246 static void setup_frame(int sig, struct target_sigaction *ka,
2247 target_sigset_t *set, CPUSPARCState *env)
2250 struct target_signal_frame *sf;
2251 int sigframe_size, err, i;
2253 /* 1. Make sure everything is clean */
2254 //synchronize_user_stack();
2256 sigframe_size = NF_ALIGNEDSZ;
2257 sf_addr = get_sigframe(ka, env, sigframe_size);
2259 sf = lock_user(VERIFY_WRITE, sf_addr,
2260 sizeof(struct target_signal_frame), 0);
2264 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2266 if (invalid_frame_pointer(sf, sigframe_size))
2267 goto sigill_and_return;
2269 /* 2. Save the current process state */
2270 err = setup___siginfo(&sf->info, env, set->sig[0]);
2271 err |= __put_user(0, &sf->extra_size);
2273 //err |= save_fpu_state(regs, &sf->fpu_state);
2274 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
2276 err |= __put_user(set->sig[0], &sf->info.si_mask);
2277 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2278 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
2281 for (i = 0; i < 8; i++) {
2282 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2284 for (i = 0; i < 8; i++) {
2285 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
2290 /* 3. signal handler back-trampoline and parameters */
2291 env->regwptr[UREG_FP] = sf_addr;
2292 env->regwptr[UREG_I0] = sig;
2293 env->regwptr[UREG_I1] = sf_addr +
2294 offsetof(struct target_signal_frame, info);
2295 env->regwptr[UREG_I2] = sf_addr +
2296 offsetof(struct target_signal_frame, info);
2298 /* 4. signal handler */
2299 env->pc = ka->_sa_handler;
2300 env->npc = (env->pc + 4);
2301 /* 5. return to kernel instructions */
2302 if (ka->sa_restorer)
2303 env->regwptr[UREG_I7] = ka->sa_restorer;
2307 env->regwptr[UREG_I7] = sf_addr +
2308 offsetof(struct target_signal_frame, insns) - 2 * 4;
2310 /* mov __NR_sigreturn, %g1 */
2312 err |= __put_user(val32, &sf->insns[0]);
2316 err |= __put_user(val32, &sf->insns[1]);
2320 /* Flush instruction space. */
2321 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2324 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2328 force_sig(TARGET_SIGILL);
2331 //fprintf(stderr, "force_sig\n");
2332 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2333 force_sig(TARGET_SIGSEGV);
2336 restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2341 if (current->flags & PF_USEDFPU)
2342 regs->psr &= ~PSR_EF;
2344 if (current == last_task_used_math) {
2345 last_task_used_math = 0;
2346 regs->psr &= ~PSR_EF;
2349 current->used_math = 1;
2350 current->flags &= ~PF_USEDFPU;
2353 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2357 /* XXX: incorrect */
2358 err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],
2359 (sizeof(abi_ulong) * 32));
2360 err |= __get_user(env->fsr, &fpu->si_fsr);
2362 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2363 if (current->thread.fpqdepth != 0)
2364 err |= __copy_from_user(¤t->thread.fpqueue[0],
2365 &fpu->si_fpqueue[0],
2366 ((sizeof(unsigned long) +
2367 (sizeof(unsigned long *)))*16));
2373 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2374 target_siginfo_t *info,
2375 target_sigset_t *set, CPUSPARCState *env)
2377 fprintf(stderr, "setup_rt_frame: not implemented\n");
2380 long do_sigreturn(CPUSPARCState *env)
2383 struct target_signal_frame *sf;
2384 uint32_t up_psr, pc, npc;
2385 target_sigset_t set;
2389 sf_addr = env->regwptr[UREG_FP];
2390 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2393 fprintf(stderr, "sigreturn\n");
2394 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2396 //cpu_dump_state(env, stderr, fprintf, 0);
2398 /* 1. Make sure we are not getting garbage from the user */
2403 err = __get_user(pc, &sf->info.si_regs.pc);
2404 err |= __get_user(npc, &sf->info.si_regs.npc);
2409 /* 2. Restore the state */
2410 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2412 /* User can only change condition codes and FPU enabling in %psr. */
2413 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2414 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2418 err |= __get_user(env->y, &sf->info.si_regs.y);
2419 for (i=0; i < 8; i++) {
2420 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2422 for (i=0; i < 8; i++) {
2423 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2426 /* FIXME: implement FPU save/restore:
2427 * __get_user(fpu_save, &sf->fpu_save);
2429 * err |= restore_fpu_state(env, fpu_save);
2432 /* This is pretty much atomic, no amount locking would prevent
2433 * the races which exist anyways.
2435 err |= __get_user(set.sig[0], &sf->info.si_mask);
2436 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2437 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2440 target_to_host_sigset_internal(&host_set, &set);
2441 sigprocmask(SIG_SETMASK, &host_set, NULL);
2445 unlock_user_struct(sf, sf_addr, 0);
2446 return env->regwptr[0];
2449 unlock_user_struct(sf, sf_addr, 0);
2450 force_sig(TARGET_SIGSEGV);
2453 long do_rt_sigreturn(CPUSPARCState *env)
2455 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2456 return -TARGET_ENOSYS;
2459 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2481 typedef abi_ulong target_mc_greg_t;
2482 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2484 struct target_mc_fq {
2485 abi_ulong *mcfq_addr;
2489 struct target_mc_fpu {
2493 //uint128_t qregs[16];
2495 abi_ulong mcfpu_fsr;
2496 abi_ulong mcfpu_fprs;
2497 abi_ulong mcfpu_gsr;
2498 struct target_mc_fq *mcfpu_fq;
2499 unsigned char mcfpu_qcnt;
2500 unsigned char mcfpu_qentsz;
2501 unsigned char mcfpu_enab;
2503 typedef struct target_mc_fpu target_mc_fpu_t;
2506 target_mc_gregset_t mc_gregs;
2507 target_mc_greg_t mc_fp;
2508 target_mc_greg_t mc_i7;
2509 target_mc_fpu_t mc_fpregs;
2510 } target_mcontext_t;
2512 struct target_ucontext {
2513 struct target_ucontext *tuc_link;
2514 abi_ulong tuc_flags;
2515 target_sigset_t tuc_sigmask;
2516 target_mcontext_t tuc_mcontext;
2519 /* A V9 register window */
2520 struct target_reg_window {
2521 abi_ulong locals[8];
2525 #define TARGET_STACK_BIAS 2047
2527 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2528 void sparc64_set_context(CPUSPARCState *env)
2531 struct target_ucontext *ucp;
2532 target_mc_gregset_t *grp;
2533 abi_ulong pc, npc, tstate;
2534 abi_ulong fp, i7, w_addr;
2538 ucp_addr = env->regwptr[UREG_I0];
2539 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2541 grp = &ucp->tuc_mcontext.mc_gregs;
2542 err = __get_user(pc, &((*grp)[MC_PC]));
2543 err |= __get_user(npc, &((*grp)[MC_NPC]));
2544 if (err || ((pc | npc) & 3))
2546 if (env->regwptr[UREG_I1]) {
2547 target_sigset_t target_set;
2550 if (TARGET_NSIG_WORDS == 1) {
2551 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2554 abi_ulong *src, *dst;
2555 src = ucp->tuc_sigmask.sig;
2556 dst = target_set.sig;
2557 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2558 err |= __get_user(*dst, src);
2563 target_to_host_sigset_internal(&set, &target_set);
2564 sigprocmask(SIG_SETMASK, &set, NULL);
2568 err |= __get_user(env->y, &((*grp)[MC_Y]));
2569 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2570 env->asi = (tstate >> 24) & 0xff;
2571 cpu_put_ccr(env, tstate >> 32);
2572 cpu_put_cwp64(env, tstate & 0x1f);
2573 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2574 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2575 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2576 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2577 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2578 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2579 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2580 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2581 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2582 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2583 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2584 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2585 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2586 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2587 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2589 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2590 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2592 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2593 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2596 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2599 /* FIXME this does not match how the kernel handles the FPU in
2600 * its sparc64_set_context implementation. In particular the FPU
2601 * is only restored if fenab is non-zero in:
2602 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2604 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2606 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2607 for (i = 0; i < 64; i++, src++) {
2609 err |= __get_user(env->fpr[i/2].l.lower, src);
2611 err |= __get_user(env->fpr[i/2].l.upper, src);
2615 err |= __get_user(env->fsr,
2616 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2617 err |= __get_user(env->gsr,
2618 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2621 unlock_user_struct(ucp, ucp_addr, 0);
2624 unlock_user_struct(ucp, ucp_addr, 0);
2625 force_sig(TARGET_SIGSEGV);
2628 void sparc64_get_context(CPUSPARCState *env)
2631 struct target_ucontext *ucp;
2632 target_mc_gregset_t *grp;
2633 target_mcontext_t *mcp;
2634 abi_ulong fp, i7, w_addr;
2637 target_sigset_t target_set;
2640 ucp_addr = env->regwptr[UREG_I0];
2641 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2644 mcp = &ucp->tuc_mcontext;
2645 grp = &mcp->mc_gregs;
2647 /* Skip over the trap instruction, first. */
2653 sigprocmask(0, NULL, &set);
2654 host_to_target_sigset_internal(&target_set, &set);
2655 if (TARGET_NSIG_WORDS == 1) {
2656 err |= __put_user(target_set.sig[0],
2657 (abi_ulong *)&ucp->tuc_sigmask);
2659 abi_ulong *src, *dst;
2660 src = target_set.sig;
2661 dst = ucp->tuc_sigmask.sig;
2662 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2663 err |= __put_user(*src, dst);
2669 /* XXX: tstate must be saved properly */
2670 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2671 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2672 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2673 err |= __put_user(env->y, &((*grp)[MC_Y]));
2674 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2675 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2676 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2677 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2678 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2679 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2680 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2681 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2682 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2683 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2684 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2685 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2686 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2687 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2688 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2690 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2692 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2695 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2698 err |= __put_user(fp, &(mcp->mc_fp));
2699 err |= __put_user(i7, &(mcp->mc_i7));
2702 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2703 for (i = 0; i < 64; i++, dst++) {
2705 err |= __put_user(env->fpr[i/2].l.lower, dst);
2707 err |= __put_user(env->fpr[i/2].l.upper, dst);
2711 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2712 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2713 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2717 unlock_user_struct(ucp, ucp_addr, 1);
2720 unlock_user_struct(ucp, ucp_addr, 1);
2721 force_sig(TARGET_SIGSEGV);
2724 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2726 # if defined(TARGET_ABI_MIPSO32)
2727 struct target_sigcontext {
2728 uint32_t sc_regmask; /* Unused */
2731 uint64_t sc_regs[32];
2732 uint64_t sc_fpregs[32];
2733 uint32_t sc_ownedfp; /* Unused */
2734 uint32_t sc_fpc_csr;
2735 uint32_t sc_fpc_eir; /* Unused */
2736 uint32_t sc_used_math;
2737 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2741 target_ulong sc_hi1; /* Was sc_cause */
2742 target_ulong sc_lo1; /* Was sc_badvaddr */
2743 target_ulong sc_hi2; /* Was sc_sigset[4] */
2744 target_ulong sc_lo2;
2745 target_ulong sc_hi3;
2746 target_ulong sc_lo3;
2748 # else /* N32 || N64 */
2749 struct target_sigcontext {
2750 uint64_t sc_regs[32];
2751 uint64_t sc_fpregs[32];
2761 uint32_t sc_fpc_csr;
2762 uint32_t sc_used_math;
2764 uint32_t sc_reserved;
2769 uint32_t sf_ass[4]; /* argument save space for o32 */
2770 uint32_t sf_code[2]; /* signal trampoline */
2771 struct target_sigcontext sf_sc;
2772 target_sigset_t sf_mask;
2775 struct target_ucontext {
2776 target_ulong tuc_flags;
2777 target_ulong tuc_link;
2778 target_stack_t tuc_stack;
2780 struct target_sigcontext tuc_mcontext;
2781 target_sigset_t tuc_sigmask;
2784 struct target_rt_sigframe {
2785 uint32_t rs_ass[4]; /* argument save space for o32 */
2786 uint32_t rs_code[2]; /* signal trampoline */
2787 struct target_siginfo rs_info;
2788 struct target_ucontext rs_uc;
2791 /* Install trampoline to jump back from signal handler */
2792 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2797 * Set up the return code ...
2799 * li v0, __NR__foo_sigreturn
2803 err |= __put_user(0x24020000 + syscall, tramp + 0);
2804 err |= __put_user(0x0000000c , tramp + 1);
2809 setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2814 err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
2815 regs->hflags &= ~MIPS_HFLAG_BMASK;
2817 __put_user(0, &sc->sc_regs[0]);
2818 for (i = 1; i < 32; ++i) {
2819 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2822 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2823 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2825 /* Rather than checking for dsp existence, always copy. The storage
2826 would just be garbage otherwise. */
2827 err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
2828 err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
2829 err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
2830 err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
2831 err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
2832 err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
2834 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2835 err |= __put_user(dsp, &sc->sc_dsp);
2838 err |= __put_user(1, &sc->sc_used_math);
2840 for (i = 0; i < 32; ++i) {
2841 err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2848 restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2853 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2855 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2856 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2858 for (i = 1; i < 32; ++i) {
2859 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2862 err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
2863 err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
2864 err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
2865 err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
2866 err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
2867 err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
2870 err |= __get_user(dsp, &sc->sc_dsp);
2871 cpu_wrdsp(dsp, 0x3ff, regs);
2874 for (i = 0; i < 32; ++i) {
2875 err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2882 * Determine which stack to use..
2884 static inline abi_ulong
2885 get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2889 /* Default to using normal stack */
2890 sp = regs->active_tc.gpr[29];
2893 * FPU emulator may have its own trampoline active just
2894 * above the user stack, 16-bytes before the next lowest
2895 * 16 byte boundary. Try to avoid trashing it.
2899 /* This is the X/Open sanctioned signal stack switching. */
2900 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2901 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2904 return (sp - frame_size) & ~7;
2907 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2909 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2910 env->hflags &= ~MIPS_HFLAG_M16;
2911 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2912 env->active_tc.PC &= ~(target_ulong) 1;
2916 # if defined(TARGET_ABI_MIPSO32)
2917 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2918 static void setup_frame(int sig, struct target_sigaction * ka,
2919 target_sigset_t *set, CPUMIPSState *regs)
2921 struct sigframe *frame;
2922 abi_ulong frame_addr;
2925 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2926 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2929 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2931 if(setup_sigcontext(regs, &frame->sf_sc))
2934 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2935 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2940 * Arguments to signal handler:
2942 * a0 = signal number
2943 * a1 = 0 (should be cause)
2944 * a2 = pointer to struct sigcontext
2946 * $25 and PC point to the signal handler, $29 points to the
2949 regs->active_tc.gpr[ 4] = sig;
2950 regs->active_tc.gpr[ 5] = 0;
2951 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2952 regs->active_tc.gpr[29] = frame_addr;
2953 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2954 /* The original kernel code sets CP0_EPC to the handler
2955 * since it returns to userland using eret
2956 * we cannot do this here, and we must set PC directly */
2957 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2958 mips_set_hflags_isa_mode_from_pc(regs);
2959 unlock_user_struct(frame, frame_addr, 1);
2963 unlock_user_struct(frame, frame_addr, 1);
2964 force_sig(TARGET_SIGSEGV/*, current*/);
2967 long do_sigreturn(CPUMIPSState *regs)
2969 struct sigframe *frame;
2970 abi_ulong frame_addr;
2972 target_sigset_t target_set;
2975 #if defined(DEBUG_SIGNAL)
2976 fprintf(stderr, "do_sigreturn\n");
2978 frame_addr = regs->active_tc.gpr[29];
2979 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2982 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2983 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2987 target_to_host_sigset_internal(&blocked, &target_set);
2988 sigprocmask(SIG_SETMASK, &blocked, NULL);
2990 if (restore_sigcontext(regs, &frame->sf_sc))
2995 * Don't let your children do this ...
2997 __asm__ __volatile__(
3005 regs->active_tc.PC = regs->CP0_EPC;
3006 mips_set_hflags_isa_mode_from_pc(regs);
3007 /* I am not sure this is right, but it seems to work
3008 * maybe a problem with nested signals ? */
3010 return -TARGET_QEMU_ESIGRETURN;
3013 force_sig(TARGET_SIGSEGV/*, current*/);
3018 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3019 target_siginfo_t *info,
3020 target_sigset_t *set, CPUMIPSState *env)
3022 struct target_rt_sigframe *frame;
3023 abi_ulong frame_addr;
3026 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3027 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3030 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3032 copy_siginfo_to_user(&frame->rs_info, info);
3034 __put_user(0, &frame->rs_uc.tuc_flags);
3035 __put_user(0, &frame->rs_uc.tuc_link);
3036 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
3037 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
3038 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3039 &frame->rs_uc.tuc_stack.ss_flags);
3041 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3043 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3044 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3048 * Arguments to signal handler:
3050 * a0 = signal number
3051 * a1 = pointer to siginfo_t
3052 * a2 = pointer to struct ucontext
3054 * $25 and PC point to the signal handler, $29 points to the
3057 env->active_tc.gpr[ 4] = sig;
3058 env->active_tc.gpr[ 5] = frame_addr
3059 + offsetof(struct target_rt_sigframe, rs_info);
3060 env->active_tc.gpr[ 6] = frame_addr
3061 + offsetof(struct target_rt_sigframe, rs_uc);
3062 env->active_tc.gpr[29] = frame_addr;
3063 env->active_tc.gpr[31] = frame_addr
3064 + offsetof(struct target_rt_sigframe, rs_code);
3065 /* The original kernel code sets CP0_EPC to the handler
3066 * since it returns to userland using eret
3067 * we cannot do this here, and we must set PC directly */
3068 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3069 mips_set_hflags_isa_mode_from_pc(env);
3070 unlock_user_struct(frame, frame_addr, 1);
3074 unlock_user_struct(frame, frame_addr, 1);
3075 force_sig(TARGET_SIGSEGV/*, current*/);
3078 long do_rt_sigreturn(CPUMIPSState *env)
3080 struct target_rt_sigframe *frame;
3081 abi_ulong frame_addr;
3084 #if defined(DEBUG_SIGNAL)
3085 fprintf(stderr, "do_rt_sigreturn\n");
3087 frame_addr = env->active_tc.gpr[29];
3088 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3091 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3092 sigprocmask(SIG_SETMASK, &blocked, NULL);
3094 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
3097 if (do_sigaltstack(frame_addr +
3098 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3099 0, get_sp_from_cpustate(env)) == -EFAULT)
3102 env->active_tc.PC = env->CP0_EPC;
3103 mips_set_hflags_isa_mode_from_pc(env);
3104 /* I am not sure this is right, but it seems to work
3105 * maybe a problem with nested signals ? */
3107 return -TARGET_QEMU_ESIGRETURN;
3110 force_sig(TARGET_SIGSEGV/*, current*/);
3114 #elif defined(TARGET_SH4)
3117 * code and data structures from linux kernel:
3118 * include/asm-sh/sigcontext.h
3119 * arch/sh/kernel/signal.c
3122 struct target_sigcontext {
3123 target_ulong oldmask;
3126 target_ulong sc_gregs[16];
3130 target_ulong sc_gbr;
3131 target_ulong sc_mach;
3132 target_ulong sc_macl;
3135 target_ulong sc_fpregs[16];
3136 target_ulong sc_xfpregs[16];
3137 unsigned int sc_fpscr;
3138 unsigned int sc_fpul;
3139 unsigned int sc_ownedfp;
3142 struct target_sigframe
3144 struct target_sigcontext sc;
3145 target_ulong extramask[TARGET_NSIG_WORDS-1];
3146 uint16_t retcode[3];
3150 struct target_ucontext {
3151 target_ulong tuc_flags;
3152 struct target_ucontext *tuc_link;
3153 target_stack_t tuc_stack;
3154 struct target_sigcontext tuc_mcontext;
3155 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3158 struct target_rt_sigframe
3160 struct target_siginfo info;
3161 struct target_ucontext uc;
3162 uint16_t retcode[3];
3166 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3167 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3169 static abi_ulong get_sigframe(struct target_sigaction *ka,
3170 unsigned long sp, size_t frame_size)
3172 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
3173 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3176 return (sp - frame_size) & -8ul;
3179 static int setup_sigcontext(struct target_sigcontext *sc,
3180 CPUSH4State *regs, unsigned long mask)
3185 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
3186 COPY(gregs[0]); COPY(gregs[1]);
3187 COPY(gregs[2]); COPY(gregs[3]);
3188 COPY(gregs[4]); COPY(gregs[5]);
3189 COPY(gregs[6]); COPY(gregs[7]);
3190 COPY(gregs[8]); COPY(gregs[9]);
3191 COPY(gregs[10]); COPY(gregs[11]);
3192 COPY(gregs[12]); COPY(gregs[13]);
3193 COPY(gregs[14]); COPY(gregs[15]);
3194 COPY(gbr); COPY(mach);
3195 COPY(macl); COPY(pr);
3199 for (i=0; i<16; i++) {
3200 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3202 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
3203 err |= __put_user(regs->fpul, &sc->sc_fpul);
3205 /* non-iBCS2 extensions.. */
3206 err |= __put_user(mask, &sc->oldmask);
3211 static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3214 unsigned int err = 0;
3217 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3219 COPY(gregs[2]); COPY(gregs[3]);
3220 COPY(gregs[4]); COPY(gregs[5]);
3221 COPY(gregs[6]); COPY(gregs[7]);
3222 COPY(gregs[8]); COPY(gregs[9]);
3223 COPY(gregs[10]); COPY(gregs[11]);
3224 COPY(gregs[12]); COPY(gregs[13]);
3225 COPY(gregs[14]); COPY(gregs[15]);
3226 COPY(gbr); COPY(mach);
3227 COPY(macl); COPY(pr);
3231 for (i=0; i<16; i++) {
3232 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3234 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3235 err |= __get_user(regs->fpul, &sc->sc_fpul);
3237 regs->tra = -1; /* disable syscall checks */
3238 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3242 static void setup_frame(int sig, struct target_sigaction *ka,
3243 target_sigset_t *set, CPUSH4State *regs)
3245 struct target_sigframe *frame;
3246 abi_ulong frame_addr;
3251 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3252 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3255 signal = current_exec_domain_sig(sig);
3257 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3259 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3260 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3263 /* Set up to return from userspace. If provided, use a stub
3264 already in userspace. */
3265 if (ka->sa_flags & TARGET_SA_RESTORER) {
3266 regs->pr = (unsigned long) ka->sa_restorer;
3268 /* Generate return code (system call to sigreturn) */
3269 err |= __put_user(MOVW(2), &frame->retcode[0]);
3270 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3271 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3272 regs->pr = (unsigned long) frame->retcode;
3278 /* Set up registers for signal handler */
3279 regs->gregs[15] = frame_addr;
3280 regs->gregs[4] = signal; /* Arg for signal handler */
3282 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3283 regs->pc = (unsigned long) ka->_sa_handler;
3285 unlock_user_struct(frame, frame_addr, 1);
3289 unlock_user_struct(frame, frame_addr, 1);
3290 force_sig(TARGET_SIGSEGV);
3293 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3294 target_siginfo_t *info,
3295 target_sigset_t *set, CPUSH4State *regs)
3297 struct target_rt_sigframe *frame;
3298 abi_ulong frame_addr;
3303 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3304 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3307 signal = current_exec_domain_sig(sig);
3309 err |= copy_siginfo_to_user(&frame->info, info);
3311 /* Create the ucontext. */
3312 err |= __put_user(0, &frame->uc.tuc_flags);
3313 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3314 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3315 &frame->uc.tuc_stack.ss_sp);
3316 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3317 &frame->uc.tuc_stack.ss_flags);
3318 err |= __put_user(target_sigaltstack_used.ss_size,
3319 &frame->uc.tuc_stack.ss_size);
3320 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3322 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3323 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3326 /* Set up to return from userspace. If provided, use a stub
3327 already in userspace. */
3328 if (ka->sa_flags & TARGET_SA_RESTORER) {
3329 regs->pr = (unsigned long) ka->sa_restorer;
3331 /* Generate return code (system call to sigreturn) */
3332 err |= __put_user(MOVW(2), &frame->retcode[0]);
3333 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3334 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3335 regs->pr = (unsigned long) frame->retcode;
3341 /* Set up registers for signal handler */
3342 regs->gregs[15] = frame_addr;
3343 regs->gregs[4] = signal; /* Arg for signal handler */
3344 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3345 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3346 regs->pc = (unsigned long) ka->_sa_handler;
3348 unlock_user_struct(frame, frame_addr, 1);
3352 unlock_user_struct(frame, frame_addr, 1);
3353 force_sig(TARGET_SIGSEGV);
3356 long do_sigreturn(CPUSH4State *regs)
3358 struct target_sigframe *frame;
3359 abi_ulong frame_addr;
3361 target_sigset_t target_set;
3366 #if defined(DEBUG_SIGNAL)
3367 fprintf(stderr, "do_sigreturn\n");
3369 frame_addr = regs->gregs[15];
3370 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3373 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3374 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3375 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3381 target_to_host_sigset_internal(&blocked, &target_set);
3382 sigprocmask(SIG_SETMASK, &blocked, NULL);
3384 if (restore_sigcontext(regs, &frame->sc, &r0))
3387 unlock_user_struct(frame, frame_addr, 0);
3391 unlock_user_struct(frame, frame_addr, 0);
3392 force_sig(TARGET_SIGSEGV);
3396 long do_rt_sigreturn(CPUSH4State *regs)
3398 struct target_rt_sigframe *frame;
3399 abi_ulong frame_addr;
3403 #if defined(DEBUG_SIGNAL)
3404 fprintf(stderr, "do_rt_sigreturn\n");
3406 frame_addr = regs->gregs[15];
3407 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3410 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3411 sigprocmask(SIG_SETMASK, &blocked, NULL);
3413 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3416 if (do_sigaltstack(frame_addr +
3417 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3418 0, get_sp_from_cpustate(regs)) == -EFAULT)
3421 unlock_user_struct(frame, frame_addr, 0);
3425 unlock_user_struct(frame, frame_addr, 0);
3426 force_sig(TARGET_SIGSEGV);
3429 #elif defined(TARGET_MICROBLAZE)
3431 struct target_sigcontext {
3432 struct target_pt_regs regs; /* needs to be first */
3436 struct target_stack_t {
3439 unsigned int ss_size;
3442 struct target_ucontext {
3443 abi_ulong tuc_flags;
3445 struct target_stack_t tuc_stack;
3446 struct target_sigcontext tuc_mcontext;
3447 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3450 /* Signal frames. */
3451 struct target_signal_frame {
3452 struct target_ucontext uc;
3453 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3457 struct rt_signal_frame {
3463 static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3465 __put_user(env->regs[0], &sc->regs.r0);
3466 __put_user(env->regs[1], &sc->regs.r1);
3467 __put_user(env->regs[2], &sc->regs.r2);
3468 __put_user(env->regs[3], &sc->regs.r3);
3469 __put_user(env->regs[4], &sc->regs.r4);
3470 __put_user(env->regs[5], &sc->regs.r5);
3471 __put_user(env->regs[6], &sc->regs.r6);
3472 __put_user(env->regs[7], &sc->regs.r7);
3473 __put_user(env->regs[8], &sc->regs.r8);
3474 __put_user(env->regs[9], &sc->regs.r9);
3475 __put_user(env->regs[10], &sc->regs.r10);
3476 __put_user(env->regs[11], &sc->regs.r11);
3477 __put_user(env->regs[12], &sc->regs.r12);
3478 __put_user(env->regs[13], &sc->regs.r13);
3479 __put_user(env->regs[14], &sc->regs.r14);
3480 __put_user(env->regs[15], &sc->regs.r15);
3481 __put_user(env->regs[16], &sc->regs.r16);
3482 __put_user(env->regs[17], &sc->regs.r17);
3483 __put_user(env->regs[18], &sc->regs.r18);
3484 __put_user(env->regs[19], &sc->regs.r19);
3485 __put_user(env->regs[20], &sc->regs.r20);
3486 __put_user(env->regs[21], &sc->regs.r21);
3487 __put_user(env->regs[22], &sc->regs.r22);
3488 __put_user(env->regs[23], &sc->regs.r23);
3489 __put_user(env->regs[24], &sc->regs.r24);
3490 __put_user(env->regs[25], &sc->regs.r25);
3491 __put_user(env->regs[26], &sc->regs.r26);
3492 __put_user(env->regs[27], &sc->regs.r27);
3493 __put_user(env->regs[28], &sc->regs.r28);
3494 __put_user(env->regs[29], &sc->regs.r29);
3495 __put_user(env->regs[30], &sc->regs.r30);
3496 __put_user(env->regs[31], &sc->regs.r31);
3497 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3500 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3502 __get_user(env->regs[0], &sc->regs.r0);
3503 __get_user(env->regs[1], &sc->regs.r1);
3504 __get_user(env->regs[2], &sc->regs.r2);
3505 __get_user(env->regs[3], &sc->regs.r3);
3506 __get_user(env->regs[4], &sc->regs.r4);
3507 __get_user(env->regs[5], &sc->regs.r5);
3508 __get_user(env->regs[6], &sc->regs.r6);
3509 __get_user(env->regs[7], &sc->regs.r7);
3510 __get_user(env->regs[8], &sc->regs.r8);
3511 __get_user(env->regs[9], &sc->regs.r9);
3512 __get_user(env->regs[10], &sc->regs.r10);
3513 __get_user(env->regs[11], &sc->regs.r11);
3514 __get_user(env->regs[12], &sc->regs.r12);
3515 __get_user(env->regs[13], &sc->regs.r13);
3516 __get_user(env->regs[14], &sc->regs.r14);
3517 __get_user(env->regs[15], &sc->regs.r15);
3518 __get_user(env->regs[16], &sc->regs.r16);
3519 __get_user(env->regs[17], &sc->regs.r17);
3520 __get_user(env->regs[18], &sc->regs.r18);
3521 __get_user(env->regs[19], &sc->regs.r19);
3522 __get_user(env->regs[20], &sc->regs.r20);
3523 __get_user(env->regs[21], &sc->regs.r21);
3524 __get_user(env->regs[22], &sc->regs.r22);
3525 __get_user(env->regs[23], &sc->regs.r23);
3526 __get_user(env->regs[24], &sc->regs.r24);
3527 __get_user(env->regs[25], &sc->regs.r25);
3528 __get_user(env->regs[26], &sc->regs.r26);
3529 __get_user(env->regs[27], &sc->regs.r27);
3530 __get_user(env->regs[28], &sc->regs.r28);
3531 __get_user(env->regs[29], &sc->regs.r29);
3532 __get_user(env->regs[30], &sc->regs.r30);
3533 __get_user(env->regs[31], &sc->regs.r31);
3534 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3537 static abi_ulong get_sigframe(struct target_sigaction *ka,
3538 CPUMBState *env, int frame_size)
3540 abi_ulong sp = env->regs[1];
3542 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3543 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3545 return ((sp - frame_size) & -8UL);
3548 static void setup_frame(int sig, struct target_sigaction *ka,
3549 target_sigset_t *set, CPUMBState *env)
3551 struct target_signal_frame *frame;
3552 abi_ulong frame_addr;
3556 frame_addr = get_sigframe(ka, env, sizeof *frame);
3557 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3560 /* Save the mask. */
3561 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3565 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3566 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3570 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3572 /* Set up to return from userspace. If provided, use a stub
3573 already in userspace. */
3574 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3575 if (ka->sa_flags & TARGET_SA_RESTORER) {
3576 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3579 /* Note, these encodings are _big endian_! */
3580 /* addi r12, r0, __NR_sigreturn */
3581 t = 0x31800000UL | TARGET_NR_sigreturn;
3582 err |= __put_user(t, frame->tramp + 0);
3585 err |= __put_user(t, frame->tramp + 1);
3587 /* Return from sighandler will jump to the tramp.
3588 Negative 8 offset because return is rtsd r15, 8 */
3589 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3595 /* Set up registers for signal handler */
3596 env->regs[1] = frame_addr;
3597 /* Signal handler args: */
3598 env->regs[5] = sig; /* Arg 0: signum */
3600 /* arg 1: sigcontext */
3601 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3603 /* Offset of 4 to handle microblaze rtid r14, 0 */
3604 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3606 unlock_user_struct(frame, frame_addr, 1);
3609 unlock_user_struct(frame, frame_addr, 1);
3610 force_sig(TARGET_SIGSEGV);
3613 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3614 target_siginfo_t *info,
3615 target_sigset_t *set, CPUMBState *env)
3617 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3620 long do_sigreturn(CPUMBState *env)
3622 struct target_signal_frame *frame;
3623 abi_ulong frame_addr;
3624 target_sigset_t target_set;
3628 frame_addr = env->regs[R_SP];
3629 /* Make sure the guest isn't playing games. */
3630 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3633 /* Restore blocked signals */
3634 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3636 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3637 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3640 target_to_host_sigset_internal(&set, &target_set);
3641 sigprocmask(SIG_SETMASK, &set, NULL);
3643 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3644 /* We got here through a sigreturn syscall, our path back is via an
3645 rtb insn so setup r14 for that. */
3646 env->regs[14] = env->sregs[SR_PC];
3648 unlock_user_struct(frame, frame_addr, 0);
3649 return env->regs[10];
3651 unlock_user_struct(frame, frame_addr, 0);
3652 force_sig(TARGET_SIGSEGV);
3655 long do_rt_sigreturn(CPUMBState *env)
3657 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3658 return -TARGET_ENOSYS;
3661 #elif defined(TARGET_CRIS)
3663 struct target_sigcontext {
3664 struct target_pt_regs regs; /* needs to be first */
3666 uint32_t usp; /* usp before stacking this gunk on it */
3669 /* Signal frames. */
3670 struct target_signal_frame {
3671 struct target_sigcontext sc;
3672 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3673 uint16_t retcode[4]; /* Trampoline code. */
3676 struct rt_signal_frame {
3681 uint16_t retcode[4]; /* Trampoline code. */
3684 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3686 __put_user(env->regs[0], &sc->regs.r0);
3687 __put_user(env->regs[1], &sc->regs.r1);
3688 __put_user(env->regs[2], &sc->regs.r2);
3689 __put_user(env->regs[3], &sc->regs.r3);
3690 __put_user(env->regs[4], &sc->regs.r4);
3691 __put_user(env->regs[5], &sc->regs.r5);
3692 __put_user(env->regs[6], &sc->regs.r6);
3693 __put_user(env->regs[7], &sc->regs.r7);
3694 __put_user(env->regs[8], &sc->regs.r8);
3695 __put_user(env->regs[9], &sc->regs.r9);
3696 __put_user(env->regs[10], &sc->regs.r10);
3697 __put_user(env->regs[11], &sc->regs.r11);
3698 __put_user(env->regs[12], &sc->regs.r12);
3699 __put_user(env->regs[13], &sc->regs.r13);
3700 __put_user(env->regs[14], &sc->usp);
3701 __put_user(env->regs[15], &sc->regs.acr);
3702 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3703 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3704 __put_user(env->pc, &sc->regs.erp);
3707 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3709 __get_user(env->regs[0], &sc->regs.r0);
3710 __get_user(env->regs[1], &sc->regs.r1);
3711 __get_user(env->regs[2], &sc->regs.r2);
3712 __get_user(env->regs[3], &sc->regs.r3);
3713 __get_user(env->regs[4], &sc->regs.r4);
3714 __get_user(env->regs[5], &sc->regs.r5);
3715 __get_user(env->regs[6], &sc->regs.r6);
3716 __get_user(env->regs[7], &sc->regs.r7);
3717 __get_user(env->regs[8], &sc->regs.r8);
3718 __get_user(env->regs[9], &sc->regs.r9);
3719 __get_user(env->regs[10], &sc->regs.r10);
3720 __get_user(env->regs[11], &sc->regs.r11);
3721 __get_user(env->regs[12], &sc->regs.r12);
3722 __get_user(env->regs[13], &sc->regs.r13);
3723 __get_user(env->regs[14], &sc->usp);
3724 __get_user(env->regs[15], &sc->regs.acr);
3725 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3726 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3727 __get_user(env->pc, &sc->regs.erp);
3730 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3733 /* Align the stack downwards to 4. */
3734 sp = (env->regs[R_SP] & ~3);
3735 return sp - framesize;
3738 static void setup_frame(int sig, struct target_sigaction *ka,
3739 target_sigset_t *set, CPUCRISState *env)
3741 struct target_signal_frame *frame;
3742 abi_ulong frame_addr;
3746 frame_addr = get_sigframe(env, sizeof *frame);
3747 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3751 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3752 * use this trampoline anymore but it sets it up for GDB.
3753 * In QEMU, using the trampoline simplifies things a bit so we use it.
3755 * This is movu.w __NR_sigreturn, r9; break 13;
3757 err |= __put_user(0x9c5f, frame->retcode+0);
3758 err |= __put_user(TARGET_NR_sigreturn,
3759 frame->retcode + 1);
3760 err |= __put_user(0xe93d, frame->retcode + 2);
3762 /* Save the mask. */
3763 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3767 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3768 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3772 setup_sigcontext(&frame->sc, env);
3774 /* Move the stack and setup the arguments for the handler. */
3775 env->regs[R_SP] = frame_addr;
3776 env->regs[10] = sig;
3777 env->pc = (unsigned long) ka->_sa_handler;
3778 /* Link SRP so the guest returns through the trampoline. */
3779 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3781 unlock_user_struct(frame, frame_addr, 1);
3784 unlock_user_struct(frame, frame_addr, 1);
3785 force_sig(TARGET_SIGSEGV);
3788 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3789 target_siginfo_t *info,
3790 target_sigset_t *set, CPUCRISState *env)
3792 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3795 long do_sigreturn(CPUCRISState *env)
3797 struct target_signal_frame *frame;
3798 abi_ulong frame_addr;
3799 target_sigset_t target_set;
3803 frame_addr = env->regs[R_SP];
3804 /* Make sure the guest isn't playing games. */
3805 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3808 /* Restore blocked signals */
3809 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3811 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3812 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3815 target_to_host_sigset_internal(&set, &target_set);
3816 sigprocmask(SIG_SETMASK, &set, NULL);
3818 restore_sigcontext(&frame->sc, env);
3819 unlock_user_struct(frame, frame_addr, 0);
3820 return env->regs[10];
3822 unlock_user_struct(frame, frame_addr, 0);
3823 force_sig(TARGET_SIGSEGV);
3826 long do_rt_sigreturn(CPUCRISState *env)
3828 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3829 return -TARGET_ENOSYS;
3832 #elif defined(TARGET_OPENRISC)
3834 struct target_sigcontext {
3835 struct target_pt_regs regs;
3840 struct target_ucontext {
3841 abi_ulong tuc_flags;
3843 target_stack_t tuc_stack;
3844 struct target_sigcontext tuc_mcontext;
3845 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3848 struct target_rt_sigframe {
3851 struct target_siginfo info;
3852 struct target_sigcontext sc;
3853 struct target_ucontext uc;
3854 unsigned char retcode[16]; /* trampoline code */
3857 /* This is the asm-generic/ucontext.h version */
3859 static int restore_sigcontext(CPUOpenRISCState *regs,
3860 struct target_sigcontext *sc)
3862 unsigned int err = 0;
3863 unsigned long old_usp;
3865 /* Alwys make any pending restarted system call return -EINTR */
3866 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3868 /* restore the regs from &sc->regs (same as sc, since regs is first)
3869 * (sc is already checked for VERIFY_READ since the sigframe was
3870 * checked in sys_sigreturn previously)
3873 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3877 /* make sure the U-flag is set so user-mode cannot fool us */
3881 /* restore the old USP as it was before we stacked the sc etc.
3882 * (we cannot just pop the sigcontext since we aligned the sp and
3883 * stuff after pushing it)
3886 err |= __get_user(old_usp, &sc->usp);
3887 phx_signal("old_usp 0x%lx", old_usp);
3889 __PHX__ REALLY /* ??? */
3891 regs->gpr[1] = old_usp;
3893 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3894 * after this completes, but we don't use that mechanism. maybe we can
3905 /* Set up a signal frame. */
3907 static int setup_sigcontext(struct target_sigcontext *sc,
3908 CPUOpenRISCState *regs,
3912 unsigned long usp = regs->gpr[1];
3914 /* copy the regs. they are first in sc so we can use sc directly */
3916 /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3918 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3919 the signal handler. The frametype will be restored to its previous
3920 value in restore_sigcontext. */
3921 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3923 /* then some other stuff */
3924 err |= __put_user(mask, &sc->oldmask);
3925 err |= __put_user(usp, &sc->usp); return err;
3928 static inline unsigned long align_sigframe(unsigned long sp)
3935 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3936 CPUOpenRISCState *regs,
3939 unsigned long sp = regs->gpr[1];
3940 int onsigstack = on_sig_stack(sp);
3943 /* This is the X/Open sanctioned signal stack switching. */
3944 if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
3945 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3948 sp = align_sigframe(sp - frame_size);
3951 * If we are on the alternate signal stack and would overflow it, don't.
3952 * Return an always-bogus address instead so we will die with SIGSEGV.
3955 if (onsigstack && !likely(on_sig_stack(sp))) {
3962 static void setup_frame(int sig, struct target_sigaction *ka,
3963 target_sigset_t *set, CPUOpenRISCState *env)
3965 qemu_log("Not implement.\n");
3968 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3969 target_siginfo_t *info,
3970 target_sigset_t *set, CPUOpenRISCState *env)
3973 abi_ulong frame_addr;
3974 unsigned long return_ip;
3975 struct target_rt_sigframe *frame;
3976 abi_ulong info_addr, uc_addr;
3978 frame_addr = get_sigframe(ka, env, sizeof *frame);
3980 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3981 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3985 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
3986 err |= __put_user(info_addr, &frame->pinfo);
3987 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
3988 err |= __put_user(uc_addr, &frame->puc);
3990 if (ka->sa_flags & SA_SIGINFO) {
3991 err |= copy_siginfo_to_user(&frame->info, info);
3997 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3998 err |= __put_user(0, &frame->uc.tuc_flags);
3999 err |= __put_user(0, &frame->uc.tuc_link);
4000 err |= __put_user(target_sigaltstack_used.ss_sp,
4001 &frame->uc.tuc_stack.ss_sp);
4002 err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
4003 err |= __put_user(target_sigaltstack_used.ss_size,
4004 &frame->uc.tuc_stack.ss_size);
4005 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4007 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
4013 /* trampoline - the desired return ip is the retcode itself */
4014 return_ip = (unsigned long)&frame->retcode;
4015 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
4016 err |= __put_user(0xa960, (short *)(frame->retcode + 0));
4017 err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
4018 err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
4019 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
4025 /* TODO what is the current->exec_domain stuff and invmap ? */
4027 /* Set up registers for signal handler */
4028 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
4029 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
4030 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
4031 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
4032 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
4034 /* actually move the usp to reflect the stacked frame */
4035 env->gpr[1] = (unsigned long)frame;
4040 unlock_user_struct(frame, frame_addr, 1);
4041 if (sig == TARGET_SIGSEGV) {
4042 ka->_sa_handler = TARGET_SIG_DFL;
4044 force_sig(TARGET_SIGSEGV);
4047 long do_sigreturn(CPUOpenRISCState *env)
4050 qemu_log("do_sigreturn: not implemented\n");
4051 return -TARGET_ENOSYS;
4054 long do_rt_sigreturn(CPUOpenRISCState *env)
4056 qemu_log("do_rt_sigreturn: not implemented\n");
4057 return -TARGET_ENOSYS;
4059 /* TARGET_OPENRISC */
4061 #elif defined(TARGET_S390X)
4063 #define __NUM_GPRS 16
4064 #define __NUM_FPRS 16
4065 #define __NUM_ACRS 16
4067 #define S390_SYSCALL_SIZE 2
4068 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4070 #define _SIGCONTEXT_NSIG 64
4071 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4072 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4073 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4074 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4075 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4079 target_ulong gprs[__NUM_GPRS];
4080 unsigned int acrs[__NUM_ACRS];
4081 } target_s390_regs_common;
4085 double fprs[__NUM_FPRS];
4086 } target_s390_fp_regs;
4089 target_s390_regs_common regs;
4090 target_s390_fp_regs fpregs;
4093 struct target_sigcontext {
4094 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4095 target_sigregs *sregs;
4099 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4100 struct target_sigcontext sc;
4101 target_sigregs sregs;
4103 uint8_t retcode[S390_SYSCALL_SIZE];
4106 struct target_ucontext {
4107 target_ulong tuc_flags;
4108 struct target_ucontext *tuc_link;
4109 target_stack_t tuc_stack;
4110 target_sigregs tuc_mcontext;
4111 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4115 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4116 uint8_t retcode[S390_SYSCALL_SIZE];
4117 struct target_siginfo info;
4118 struct target_ucontext uc;
4121 static inline abi_ulong
4122 get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4126 /* Default to using normal stack */
4129 /* This is the X/Open sanctioned signal stack switching. */
4130 if (ka->sa_flags & TARGET_SA_ONSTACK) {
4131 if (!sas_ss_flags(sp)) {
4132 sp = target_sigaltstack_used.ss_sp +
4133 target_sigaltstack_used.ss_size;
4137 /* This is the legacy signal stack switching. */
4138 else if (/* FIXME !user_mode(regs) */ 0 &&
4139 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4141 sp = (abi_ulong) ka->sa_restorer;
4144 return (sp - frame_size) & -8ul;
4147 static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4150 //save_access_regs(current->thread.acrs); FIXME
4152 /* Copy a 'clean' PSW mask to the user to avoid leaking
4153 information about whether PER is currently on. */
4154 __put_user(env->psw.mask, &sregs->regs.psw.mask);
4155 __put_user(env->psw.addr, &sregs->regs.psw.addr);
4156 for (i = 0; i < 16; i++) {
4157 __put_user(env->regs[i], &sregs->regs.gprs[i]);
4159 for (i = 0; i < 16; i++) {
4160 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
4163 * We have to store the fp registers to current->thread.fp_regs
4164 * to merge them with the emulated registers.
4166 //save_fp_regs(¤t->thread.fp_regs); FIXME
4167 for (i = 0; i < 16; i++) {
4168 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4172 static void setup_frame(int sig, struct target_sigaction *ka,
4173 target_sigset_t *set, CPUS390XState *env)
4176 abi_ulong frame_addr;
4178 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4179 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4180 (unsigned long long)frame_addr);
4181 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4185 qemu_log("%s: 1\n", __FUNCTION__);
4186 if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
4190 save_sigregs(env, &frame->sregs);
4192 __put_user((abi_ulong)(unsigned long)&frame->sregs,
4193 (abi_ulong *)&frame->sc.sregs);
4195 /* Set up to return from userspace. If provided, use a stub
4196 already in userspace. */
4197 if (ka->sa_flags & TARGET_SA_RESTORER) {
4198 env->regs[14] = (unsigned long)
4199 ka->sa_restorer | PSW_ADDR_AMODE;
4201 env->regs[14] = (unsigned long)
4202 frame->retcode | PSW_ADDR_AMODE;
4203 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
4204 (uint16_t *)(frame->retcode)))
4208 /* Set up backchain. */
4209 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4213 /* Set up registers for signal handler */
4214 env->regs[15] = frame_addr;
4215 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4217 env->regs[2] = sig; //map_signal(sig);
4218 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
4220 /* We forgot to include these in the sigcontext.
4221 To avoid breaking binary compatibility, they are passed as args. */
4222 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4223 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4225 /* Place signal number on stack to allow backtrace from handler. */
4226 if (__put_user(env->regs[2], (int *) &frame->signo)) {
4229 unlock_user_struct(frame, frame_addr, 1);
4233 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4234 unlock_user_struct(frame, frame_addr, 1);
4235 force_sig(TARGET_SIGSEGV);
4238 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4239 target_siginfo_t *info,
4240 target_sigset_t *set, CPUS390XState *env)
4244 abi_ulong frame_addr;
4246 frame_addr = get_sigframe(ka, env, sizeof *frame);
4247 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4248 (unsigned long long)frame_addr);
4249 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4253 qemu_log("%s: 1\n", __FUNCTION__);
4254 if (copy_siginfo_to_user(&frame->info, info)) {
4258 /* Create the ucontext. */
4259 __put_user(0, &frame->uc.tuc_flags);
4260 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
4261 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
4262 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
4263 &frame->uc.tuc_stack.ss_flags);
4264 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
4265 save_sigregs(env, &frame->uc.tuc_mcontext);
4266 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
4267 __put_user((abi_ulong)set->sig[i],
4268 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
4271 /* Set up to return from userspace. If provided, use a stub
4272 already in userspace. */
4273 if (ka->sa_flags & TARGET_SA_RESTORER) {
4274 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4276 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4277 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
4278 (uint16_t *)(frame->retcode))) {
4283 /* Set up backchain. */
4284 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4288 /* Set up registers for signal handler */
4289 env->regs[15] = frame_addr;
4290 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4292 env->regs[2] = sig; //map_signal(sig);
4293 env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
4294 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
4298 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4299 unlock_user_struct(frame, frame_addr, 1);
4300 force_sig(TARGET_SIGSEGV);
4304 restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4309 for (i = 0; i < 16; i++) {
4310 err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
4313 err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
4314 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4315 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4316 (unsigned long long)env->psw.addr);
4317 err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
4318 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4320 for (i = 0; i < 16; i++) {
4321 err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
4323 for (i = 0; i < 16; i++) {
4324 err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4330 long do_sigreturn(CPUS390XState *env)
4333 abi_ulong frame_addr = env->regs[15];
4334 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4335 (unsigned long long)frame_addr);
4336 target_sigset_t target_set;
4339 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4342 if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
4346 target_to_host_sigset_internal(&set, &target_set);
4347 sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4349 if (restore_sigregs(env, &frame->sregs)) {
4353 unlock_user_struct(frame, frame_addr, 0);
4354 return env->regs[2];
4357 unlock_user_struct(frame, frame_addr, 0);
4358 force_sig(TARGET_SIGSEGV);
4362 long do_rt_sigreturn(CPUS390XState *env)
4365 abi_ulong frame_addr = env->regs[15];
4366 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4367 (unsigned long long)frame_addr);
4370 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4373 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4375 sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4377 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4381 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4382 get_sp_from_cpustate(env)) == -EFAULT) {
4385 unlock_user_struct(frame, frame_addr, 0);
4386 return env->regs[2];
4389 unlock_user_struct(frame, frame_addr, 0);
4390 force_sig(TARGET_SIGSEGV);
4394 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4396 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4397 the signal handling is different enough that we haven't implemented
4398 support for PPC64 yet. Hence the restriction above.
4400 There are various #if'd blocks for code for TARGET_PPC64. These
4401 blocks should go away so that we can successfully run 32-bit and
4402 64-bit binaries on a QEMU configured for PPC64. */
4404 /* Size of dummy stack frame allocated when calling signal handler.
4405 See arch/powerpc/include/asm/ptrace.h. */
4406 #if defined(TARGET_PPC64)
4407 #define SIGNAL_FRAMESIZE 128
4409 #define SIGNAL_FRAMESIZE 64
4412 /* See arch/powerpc/include/asm/sigcontext.h. */
4413 struct target_sigcontext {
4414 target_ulong _unused[4];
4416 #if defined(TARGET_PPC64)
4419 target_ulong handler;
4420 target_ulong oldmask;
4421 target_ulong regs; /* struct pt_regs __user * */
4422 /* TODO: PPC64 includes extra bits here. */
4425 /* Indices for target_mcontext.mc_gregs, below.
4426 See arch/powerpc/include/asm/ptrace.h for details. */
4462 TARGET_PT_ORIG_R3 = 34,
4467 /* Yes, there are two registers with #39. One is 64-bit only. */
4469 TARGET_PT_SOFTE = 39,
4470 TARGET_PT_TRAP = 40,
4472 TARGET_PT_DSISR = 42,
4473 TARGET_PT_RESULT = 43,
4474 TARGET_PT_REGS_COUNT = 44
4477 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4478 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4479 struct target_mcontext {
4480 target_ulong mc_gregs[48];
4481 /* Includes fpscr. */
4482 uint64_t mc_fregs[33];
4483 target_ulong mc_pad[2];
4484 /* We need to handle Altivec and SPE at the same time, which no
4485 kernel needs to do. Fortunately, the kernel defines this bit to
4486 be Altivec-register-large all the time, rather than trying to
4487 twiddle it based on the specific platform. */
4489 /* SPE vector registers. One extra for SPEFSCR. */
4491 /* Altivec vector registers. The packing of VSCR and VRSAVE
4492 varies depending on whether we're PPC64 or not: PPC64 splits
4493 them apart; PPC32 stuffs them together. */
4494 #if defined(TARGET_PPC64)
4495 #define QEMU_NVRREG 34
4497 #define QEMU_NVRREG 33
4499 ppc_avr_t altivec[QEMU_NVRREG];
4501 } mc_vregs __attribute__((__aligned__(16)));
4504 struct target_ucontext {
4505 target_ulong tuc_flags;
4506 target_ulong tuc_link; /* struct ucontext __user * */
4507 struct target_sigaltstack tuc_stack;
4508 #if !defined(TARGET_PPC64)
4510 target_ulong tuc_regs; /* struct mcontext __user *
4511 points to uc_mcontext field */
4513 target_sigset_t tuc_sigmask;
4514 #if defined(TARGET_PPC64)
4515 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4516 struct target_sigcontext tuc_mcontext;
4518 int32_t tuc_maskext[30];
4519 int32_t tuc_pad2[3];
4520 struct target_mcontext tuc_mcontext;
4524 /* See arch/powerpc/kernel/signal_32.c. */
4525 struct target_sigframe {
4526 struct target_sigcontext sctx;
4527 struct target_mcontext mctx;
4531 struct target_rt_sigframe {
4532 struct target_siginfo info;
4533 struct target_ucontext uc;
4537 /* We use the mc_pad field for the signal return trampoline. */
4538 #define tramp mc_pad
4540 /* See arch/powerpc/kernel/signal.c. */
4541 static target_ulong get_sigframe(struct target_sigaction *ka,
4545 target_ulong oldsp, newsp;
4547 oldsp = env->gpr[1];
4549 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4550 (sas_ss_flags(oldsp) == 0)) {
4551 oldsp = (target_sigaltstack_used.ss_sp
4552 + target_sigaltstack_used.ss_size);
4555 newsp = (oldsp - frame_size) & ~0xFUL;
4560 static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4563 target_ulong msr = env->msr;
4565 target_ulong ccr = 0;
4567 /* In general, the kernel attempts to be intelligent about what it
4568 needs to save for Altivec/FP/SPE registers. We don't care that
4569 much, so we just go ahead and save everything. */
4571 /* Save general registers. */
4572 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4573 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
4577 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4578 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4579 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4580 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4583 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4584 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4586 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4589 /* Save Altivec registers if necessary. */
4590 if (env->insns_flags & PPC_ALTIVEC) {
4591 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4592 ppc_avr_t *avr = &env->avr[i];
4593 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4595 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4596 __put_user(avr->u64[1], &vreg->u64[1])) {
4600 /* Set MSR_VR in the saved MSR value to indicate that
4601 frame->mc_vregs contains valid data. */
4603 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4604 &frame->mc_vregs.altivec[32].u32[3]))
4608 /* Save floating point registers. */
4609 if (env->insns_flags & PPC_FLOAT) {
4610 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4611 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
4615 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
4619 /* Save SPE registers. The kernel only saves the high half. */
4620 if (env->insns_flags & PPC_SPE) {
4621 #if defined(TARGET_PPC64)
4622 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4623 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
4628 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4629 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4634 /* Set MSR_SPE in the saved MSR value to indicate that
4635 frame->mc_vregs contains valid data. */
4637 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4642 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4645 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4647 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4648 __put_user(0x44000002UL, &frame->tramp[1])) {
4656 static int restore_user_regs(CPUPPCState *env,
4657 struct target_mcontext *frame, int sig)
4659 target_ulong save_r2 = 0;
4666 save_r2 = env->gpr[2];
4669 /* Restore general registers. */
4670 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4671 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
4675 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4676 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4677 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4678 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4680 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4683 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4684 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4688 env->gpr[2] = save_r2;
4691 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4694 /* If doing signal return, restore the previous little-endian mode. */
4696 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4698 /* Restore Altivec registers if necessary. */
4699 if (env->insns_flags & PPC_ALTIVEC) {
4700 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4701 ppc_avr_t *avr = &env->avr[i];
4702 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4704 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4705 __get_user(avr->u64[1], &vreg->u64[1])) {
4709 /* Set MSR_VEC in the saved MSR value to indicate that
4710 frame->mc_vregs contains valid data. */
4711 if (__get_user(env->spr[SPR_VRSAVE],
4712 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
4716 /* Restore floating point registers. */
4717 if (env->insns_flags & PPC_FLOAT) {
4719 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4720 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4724 if (__get_user(fpscr, &frame->mc_fregs[32]))
4726 env->fpscr = (uint32_t) fpscr;
4729 /* Save SPE registers. The kernel only saves the high half. */
4730 if (env->insns_flags & PPC_SPE) {
4731 #if defined(TARGET_PPC64)
4732 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4735 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4738 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4741 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4742 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4747 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4754 static void setup_frame(int sig, struct target_sigaction *ka,
4755 target_sigset_t *set, CPUPPCState *env)
4757 struct target_sigframe *frame;
4758 struct target_sigcontext *sc;
4759 target_ulong frame_addr, newsp;
4763 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4764 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4768 signal = current_exec_domain_sig(sig);
4770 err |= __put_user(ka->_sa_handler, &sc->handler);
4771 err |= __put_user(set->sig[0], &sc->oldmask);
4772 #if defined(TARGET_PPC64)
4773 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4775 err |= __put_user(set->sig[1], &sc->_unused[3]);
4777 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4778 err |= __put_user(sig, &sc->signal);
4780 /* Save user regs. */
4781 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4783 /* The kernel checks for the presence of a VDSO here. We don't
4784 emulate a vdso, so use a sigreturn system call. */
4785 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4787 /* Turn off all fp exceptions. */
4790 /* Create a stack frame for the caller of the handler. */
4791 newsp = frame_addr - SIGNAL_FRAMESIZE;
4792 err |= put_user(env->gpr[1], newsp, target_ulong);
4797 /* Set up registers for signal handler. */
4798 env->gpr[1] = newsp;
4799 env->gpr[3] = signal;
4800 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
4801 env->nip = (target_ulong) ka->_sa_handler;
4802 /* Signal handlers are entered in big-endian mode. */
4803 env->msr &= ~MSR_LE;
4805 unlock_user_struct(frame, frame_addr, 1);
4809 unlock_user_struct(frame, frame_addr, 1);
4810 qemu_log("segfaulting from setup_frame\n");
4811 force_sig(TARGET_SIGSEGV);
4814 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4815 target_siginfo_t *info,
4816 target_sigset_t *set, CPUPPCState *env)
4818 struct target_rt_sigframe *rt_sf;
4819 struct target_mcontext *frame;
4820 target_ulong rt_sf_addr, newsp = 0;
4824 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4825 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4828 signal = current_exec_domain_sig(sig);
4830 err |= copy_siginfo_to_user(&rt_sf->info, info);
4832 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4833 err |= __put_user(0, &rt_sf->uc.tuc_link);
4834 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4835 &rt_sf->uc.tuc_stack.ss_sp);
4836 err |= __put_user(sas_ss_flags(env->gpr[1]),
4837 &rt_sf->uc.tuc_stack.ss_flags);
4838 err |= __put_user(target_sigaltstack_used.ss_size,
4839 &rt_sf->uc.tuc_stack.ss_size);
4840 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4841 &rt_sf->uc.tuc_regs);
4842 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4843 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4846 frame = &rt_sf->uc.tuc_mcontext;
4847 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4849 /* The kernel checks for the presence of a VDSO here. We don't
4850 emulate a vdso, so use a sigreturn system call. */
4851 env->lr = (target_ulong) h2g(frame->tramp);
4853 /* Turn off all fp exceptions. */
4856 /* Create a stack frame for the caller of the handler. */
4857 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4858 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4863 /* Set up registers for signal handler. */
4864 env->gpr[1] = newsp;
4865 env->gpr[3] = (target_ulong) signal;
4866 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4867 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4868 env->gpr[6] = (target_ulong) h2g(rt_sf);
4869 env->nip = (target_ulong) ka->_sa_handler;
4870 /* Signal handlers are entered in big-endian mode. */
4871 env->msr &= ~MSR_LE;
4873 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4877 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4878 qemu_log("segfaulting from setup_rt_frame\n");
4879 force_sig(TARGET_SIGSEGV);
4883 long do_sigreturn(CPUPPCState *env)
4885 struct target_sigcontext *sc = NULL;
4886 struct target_mcontext *sr = NULL;
4887 target_ulong sr_addr = 0, sc_addr;
4889 target_sigset_t set;
4891 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4892 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4895 #if defined(TARGET_PPC64)
4896 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4898 if(__get_user(set.sig[0], &sc->oldmask) ||
4899 __get_user(set.sig[1], &sc->_unused[3]))
4902 target_to_host_sigset_internal(&blocked, &set);
4903 sigprocmask(SIG_SETMASK, &blocked, NULL);
4905 if (__get_user(sr_addr, &sc->regs))
4907 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4909 if (restore_user_regs(env, sr, 1))
4912 unlock_user_struct(sr, sr_addr, 1);
4913 unlock_user_struct(sc, sc_addr, 1);
4914 return -TARGET_QEMU_ESIGRETURN;
4917 unlock_user_struct(sr, sr_addr, 1);
4918 unlock_user_struct(sc, sc_addr, 1);
4919 qemu_log("segfaulting from do_sigreturn\n");
4920 force_sig(TARGET_SIGSEGV);
4924 /* See arch/powerpc/kernel/signal_32.c. */
4925 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4927 struct target_mcontext *mcp;
4928 target_ulong mcp_addr;
4930 target_sigset_t set;
4932 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4936 #if defined(TARGET_PPC64)
4937 fprintf (stderr, "do_setcontext: not implemented\n");
4940 if (__get_user(mcp_addr, &ucp->tuc_regs))
4943 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4946 target_to_host_sigset_internal(&blocked, &set);
4947 sigprocmask(SIG_SETMASK, &blocked, NULL);
4948 if (restore_user_regs(env, mcp, sig))
4951 unlock_user_struct(mcp, mcp_addr, 1);
4955 unlock_user_struct(mcp, mcp_addr, 1);
4960 long do_rt_sigreturn(CPUPPCState *env)
4962 struct target_rt_sigframe *rt_sf = NULL;
4963 target_ulong rt_sf_addr;
4965 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4966 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4969 if (do_setcontext(&rt_sf->uc, env, 1))
4972 do_sigaltstack(rt_sf_addr
4973 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4976 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4977 return -TARGET_QEMU_ESIGRETURN;
4980 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4981 qemu_log("segfaulting from do_rt_sigreturn\n");
4982 force_sig(TARGET_SIGSEGV);
4986 #elif defined(TARGET_M68K)
4988 struct target_sigcontext {
4995 unsigned short sc_sr;
4999 struct target_sigframe
5006 abi_ulong extramask[TARGET_NSIG_WORDS-1];
5007 struct target_sigcontext sc;
5010 typedef int target_greg_t;
5011 #define TARGET_NGREG 18
5012 typedef target_greg_t target_gregset_t[TARGET_NGREG];
5014 typedef struct target_fpregset {
5017 } target_fpregset_t;
5019 struct target_mcontext {
5021 target_gregset_t gregs;
5022 target_fpregset_t fpregs;
5025 #define TARGET_MCONTEXT_VERSION 2
5027 struct target_ucontext {
5028 abi_ulong tuc_flags;
5030 target_stack_t tuc_stack;
5031 struct target_mcontext tuc_mcontext;
5032 abi_long tuc_filler[80];
5033 target_sigset_t tuc_sigmask;
5036 struct target_rt_sigframe
5043 struct target_siginfo info;
5044 struct target_ucontext uc;
5048 setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
5053 err |= __put_user(mask, &sc->sc_mask);
5054 err |= __put_user(env->aregs[7], &sc->sc_usp);
5055 err |= __put_user(env->dregs[0], &sc->sc_d0);
5056 err |= __put_user(env->dregs[1], &sc->sc_d1);
5057 err |= __put_user(env->aregs[0], &sc->sc_a0);
5058 err |= __put_user(env->aregs[1], &sc->sc_a1);
5059 err |= __put_user(env->sr, &sc->sc_sr);
5060 err |= __put_user(env->pc, &sc->sc_pc);
5066 restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
5071 err |= __get_user(env->aregs[7], &sc->sc_usp);
5072 err |= __get_user(env->dregs[1], &sc->sc_d1);
5073 err |= __get_user(env->aregs[0], &sc->sc_a0);
5074 err |= __get_user(env->aregs[1], &sc->sc_a1);
5075 err |= __get_user(env->pc, &sc->sc_pc);
5076 err |= __get_user(temp, &sc->sc_sr);
5077 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5079 *pd0 = tswapl(sc->sc_d0);
5085 * Determine which stack to use..
5087 static inline abi_ulong
5088 get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5093 sp = regs->aregs[7];
5095 /* This is the X/Open sanctioned signal stack switching. */
5096 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
5097 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5100 return ((sp - frame_size) & -8UL);
5103 static void setup_frame(int sig, struct target_sigaction *ka,
5104 target_sigset_t *set, CPUM68KState *env)
5106 struct target_sigframe *frame;
5107 abi_ulong frame_addr;
5108 abi_ulong retcode_addr;
5113 frame_addr = get_sigframe(ka, env, sizeof *frame);
5114 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5117 err |= __put_user(sig, &frame->sig);
5119 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
5120 err |= __put_user(sc_addr, &frame->psc);
5122 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
5126 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5127 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
5131 /* Set up to return from userspace. */
5133 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5134 err |= __put_user(retcode_addr, &frame->pretcode);
5136 /* moveq #,d0; trap #0 */
5138 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5139 (long *)(frame->retcode));
5144 /* Set up to return from userspace */
5146 env->aregs[7] = frame_addr;
5147 env->pc = ka->_sa_handler;
5149 unlock_user_struct(frame, frame_addr, 1);
5153 unlock_user_struct(frame, frame_addr, 1);
5154 force_sig(TARGET_SIGSEGV);
5157 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5160 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5163 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
5164 err |= __put_user(env->dregs[0], &gregs[0]);
5165 err |= __put_user(env->dregs[1], &gregs[1]);
5166 err |= __put_user(env->dregs[2], &gregs[2]);
5167 err |= __put_user(env->dregs[3], &gregs[3]);
5168 err |= __put_user(env->dregs[4], &gregs[4]);
5169 err |= __put_user(env->dregs[5], &gregs[5]);
5170 err |= __put_user(env->dregs[6], &gregs[6]);
5171 err |= __put_user(env->dregs[7], &gregs[7]);
5172 err |= __put_user(env->aregs[0], &gregs[8]);
5173 err |= __put_user(env->aregs[1], &gregs[9]);
5174 err |= __put_user(env->aregs[2], &gregs[10]);
5175 err |= __put_user(env->aregs[3], &gregs[11]);
5176 err |= __put_user(env->aregs[4], &gregs[12]);
5177 err |= __put_user(env->aregs[5], &gregs[13]);
5178 err |= __put_user(env->aregs[6], &gregs[14]);
5179 err |= __put_user(env->aregs[7], &gregs[15]);
5180 err |= __put_user(env->pc, &gregs[16]);
5181 err |= __put_user(env->sr, &gregs[17]);
5186 static inline int target_rt_restore_ucontext(CPUM68KState *env,
5187 struct target_ucontext *uc,
5192 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5194 err = __get_user(temp, &uc->tuc_mcontext.version);
5195 if (temp != TARGET_MCONTEXT_VERSION)
5198 /* restore passed registers */
5199 err |= __get_user(env->dregs[0], &gregs[0]);
5200 err |= __get_user(env->dregs[1], &gregs[1]);
5201 err |= __get_user(env->dregs[2], &gregs[2]);
5202 err |= __get_user(env->dregs[3], &gregs[3]);
5203 err |= __get_user(env->dregs[4], &gregs[4]);
5204 err |= __get_user(env->dregs[5], &gregs[5]);
5205 err |= __get_user(env->dregs[6], &gregs[6]);
5206 err |= __get_user(env->dregs[7], &gregs[7]);
5207 err |= __get_user(env->aregs[0], &gregs[8]);
5208 err |= __get_user(env->aregs[1], &gregs[9]);
5209 err |= __get_user(env->aregs[2], &gregs[10]);
5210 err |= __get_user(env->aregs[3], &gregs[11]);
5211 err |= __get_user(env->aregs[4], &gregs[12]);
5212 err |= __get_user(env->aregs[5], &gregs[13]);
5213 err |= __get_user(env->aregs[6], &gregs[14]);
5214 err |= __get_user(env->aregs[7], &gregs[15]);
5215 err |= __get_user(env->pc, &gregs[16]);
5216 err |= __get_user(temp, &gregs[17]);
5217 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5219 *pd0 = env->dregs[0];
5226 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5227 target_siginfo_t *info,
5228 target_sigset_t *set, CPUM68KState *env)
5230 struct target_rt_sigframe *frame;
5231 abi_ulong frame_addr;
5232 abi_ulong retcode_addr;
5233 abi_ulong info_addr;
5238 frame_addr = get_sigframe(ka, env, sizeof *frame);
5239 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5242 err |= __put_user(sig, &frame->sig);
5244 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5245 err |= __put_user(info_addr, &frame->pinfo);
5247 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5248 err |= __put_user(uc_addr, &frame->puc);
5250 err |= copy_siginfo_to_user(&frame->info, info);
5252 /* Create the ucontext */
5254 err |= __put_user(0, &frame->uc.tuc_flags);
5255 err |= __put_user(0, &frame->uc.tuc_link);
5256 err |= __put_user(target_sigaltstack_used.ss_sp,
5257 &frame->uc.tuc_stack.ss_sp);
5258 err |= __put_user(sas_ss_flags(env->aregs[7]),
5259 &frame->uc.tuc_stack.ss_flags);
5260 err |= __put_user(target_sigaltstack_used.ss_size,
5261 &frame->uc.tuc_stack.ss_size);
5262 err |= target_rt_setup_ucontext(&frame->uc, env);
5267 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5268 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
5272 /* Set up to return from userspace. */
5274 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5275 err |= __put_user(retcode_addr, &frame->pretcode);
5277 /* moveq #,d0; notb d0; trap #0 */
5279 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
5280 (long *)(frame->retcode + 0));
5281 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
5286 /* Set up to return from userspace */
5288 env->aregs[7] = frame_addr;
5289 env->pc = ka->_sa_handler;
5291 unlock_user_struct(frame, frame_addr, 1);
5295 unlock_user_struct(frame, frame_addr, 1);
5296 force_sig(TARGET_SIGSEGV);
5299 long do_sigreturn(CPUM68KState *env)
5301 struct target_sigframe *frame;
5302 abi_ulong frame_addr = env->aregs[7] - 4;
5303 target_sigset_t target_set;
5307 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5310 /* set blocked signals */
5312 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
5315 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5316 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
5320 target_to_host_sigset_internal(&set, &target_set);
5321 sigprocmask(SIG_SETMASK, &set, NULL);
5323 /* restore registers */
5325 if (restore_sigcontext(env, &frame->sc, &d0))
5328 unlock_user_struct(frame, frame_addr, 0);
5332 unlock_user_struct(frame, frame_addr, 0);
5333 force_sig(TARGET_SIGSEGV);
5337 long do_rt_sigreturn(CPUM68KState *env)
5339 struct target_rt_sigframe *frame;
5340 abi_ulong frame_addr = env->aregs[7] - 4;
5341 target_sigset_t target_set;
5345 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5348 target_to_host_sigset_internal(&set, &target_set);
5349 sigprocmask(SIG_SETMASK, &set, NULL);
5351 /* restore registers */
5353 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5356 if (do_sigaltstack(frame_addr +
5357 offsetof(struct target_rt_sigframe, uc.tuc_stack),
5358 0, get_sp_from_cpustate(env)) == -EFAULT)
5361 unlock_user_struct(frame, frame_addr, 0);
5365 unlock_user_struct(frame, frame_addr, 0);
5366 force_sig(TARGET_SIGSEGV);
5370 #elif defined(TARGET_ALPHA)
5372 struct target_sigcontext {
5373 abi_long sc_onstack;
5377 abi_long sc_regs[32];
5378 abi_long sc_ownedfp;
5379 abi_long sc_fpregs[32];
5381 abi_ulong sc_fp_control;
5382 abi_ulong sc_reserved1;
5383 abi_ulong sc_reserved2;
5386 abi_ulong sc_traparg_a0;
5387 abi_ulong sc_traparg_a1;
5388 abi_ulong sc_traparg_a2;
5389 abi_ulong sc_fp_trap_pc;
5390 abi_ulong sc_fp_trigger_sum;
5391 abi_ulong sc_fp_trigger_inst;
5394 struct target_ucontext {
5395 abi_ulong tuc_flags;
5397 abi_ulong tuc_osf_sigmask;
5398 target_stack_t tuc_stack;
5399 struct target_sigcontext tuc_mcontext;
5400 target_sigset_t tuc_sigmask;
5403 struct target_sigframe {
5404 struct target_sigcontext sc;
5405 unsigned int retcode[3];
5408 struct target_rt_sigframe {
5409 target_siginfo_t info;
5410 struct target_ucontext uc;
5411 unsigned int retcode[3];
5414 #define INSN_MOV_R30_R16 0x47fe0410
5415 #define INSN_LDI_R0 0x201f0000
5416 #define INSN_CALLSYS 0x00000083
5418 static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5419 abi_ulong frame_addr, target_sigset_t *set)
5423 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
5424 err |= __put_user(set->sig[0], &sc->sc_mask);
5425 err |= __put_user(env->pc, &sc->sc_pc);
5426 err |= __put_user(8, &sc->sc_ps);
5428 for (i = 0; i < 31; ++i) {
5429 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
5431 err |= __put_user(0, &sc->sc_regs[31]);
5433 for (i = 0; i < 31; ++i) {
5434 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
5436 err |= __put_user(0, &sc->sc_fpregs[31]);
5437 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5439 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5440 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5441 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5446 static int restore_sigcontext(CPUAlphaState *env,
5447 struct target_sigcontext *sc)
5452 err |= __get_user(env->pc, &sc->sc_pc);
5454 for (i = 0; i < 31; ++i) {
5455 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5457 for (i = 0; i < 31; ++i) {
5458 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5461 err |= __get_user(fpcr, &sc->sc_fpcr);
5462 cpu_alpha_store_fpcr(env, fpcr);
5467 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5469 unsigned long framesize)
5471 abi_ulong sp = env->ir[IR_SP];
5473 /* This is the X/Open sanctioned signal stack switching. */
5474 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5475 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5477 return (sp - framesize) & -32;
5480 static void setup_frame(int sig, struct target_sigaction *ka,
5481 target_sigset_t *set, CPUAlphaState *env)
5483 abi_ulong frame_addr, r26;
5484 struct target_sigframe *frame;
5487 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5488 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5492 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5494 if (ka->sa_restorer) {
5495 r26 = ka->sa_restorer;
5497 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5498 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5499 &frame->retcode[1]);
5500 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5505 unlock_user_struct(frame, frame_addr, 1);
5509 if (sig == TARGET_SIGSEGV) {
5510 ka->_sa_handler = TARGET_SIG_DFL;
5512 force_sig(TARGET_SIGSEGV);
5515 env->ir[IR_RA] = r26;
5516 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5517 env->ir[IR_A0] = sig;
5519 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5520 env->ir[IR_SP] = frame_addr;
5523 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5524 target_siginfo_t *info,
5525 target_sigset_t *set, CPUAlphaState *env)
5527 abi_ulong frame_addr, r26;
5528 struct target_rt_sigframe *frame;
5531 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5532 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5536 err |= copy_siginfo_to_user(&frame->info, info);
5538 err |= __put_user(0, &frame->uc.tuc_flags);
5539 err |= __put_user(0, &frame->uc.tuc_link);
5540 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5541 err |= __put_user(target_sigaltstack_used.ss_sp,
5542 &frame->uc.tuc_stack.ss_sp);
5543 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
5544 &frame->uc.tuc_stack.ss_flags);
5545 err |= __put_user(target_sigaltstack_used.ss_size,
5546 &frame->uc.tuc_stack.ss_size);
5547 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5548 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5549 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5552 if (ka->sa_restorer) {
5553 r26 = ka->sa_restorer;
5555 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5556 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5557 &frame->retcode[1]);
5558 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5565 if (sig == TARGET_SIGSEGV) {
5566 ka->_sa_handler = TARGET_SIG_DFL;
5568 force_sig(TARGET_SIGSEGV);
5571 env->ir[IR_RA] = r26;
5572 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5573 env->ir[IR_A0] = sig;
5574 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5575 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5576 env->ir[IR_SP] = frame_addr;
5579 long do_sigreturn(CPUAlphaState *env)
5581 struct target_sigcontext *sc;
5582 abi_ulong sc_addr = env->ir[IR_A0];
5583 target_sigset_t target_set;
5586 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5590 target_sigemptyset(&target_set);
5591 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5595 target_to_host_sigset_internal(&set, &target_set);
5596 sigprocmask(SIG_SETMASK, &set, NULL);
5598 if (restore_sigcontext(env, sc)) {
5601 unlock_user_struct(sc, sc_addr, 0);
5602 return env->ir[IR_V0];
5605 unlock_user_struct(sc, sc_addr, 0);
5606 force_sig(TARGET_SIGSEGV);
5609 long do_rt_sigreturn(CPUAlphaState *env)
5611 abi_ulong frame_addr = env->ir[IR_A0];
5612 struct target_rt_sigframe *frame;
5615 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5618 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5619 sigprocmask(SIG_SETMASK, &set, NULL);
5621 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5624 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5626 0, env->ir[IR_SP]) == -EFAULT) {
5630 unlock_user_struct(frame, frame_addr, 0);
5631 return env->ir[IR_V0];
5635 unlock_user_struct(frame, frame_addr, 0);
5636 force_sig(TARGET_SIGSEGV);
5641 static void setup_frame(int sig, struct target_sigaction *ka,
5642 target_sigset_t *set, CPUArchState *env)
5644 fprintf(stderr, "setup_frame: not implemented\n");
5647 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5648 target_siginfo_t *info,
5649 target_sigset_t *set, CPUArchState *env)
5651 fprintf(stderr, "setup_rt_frame: not implemented\n");
5654 long do_sigreturn(CPUArchState *env)
5656 fprintf(stderr, "do_sigreturn: not implemented\n");
5657 return -TARGET_ENOSYS;
5660 long do_rt_sigreturn(CPUArchState *env)
5662 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5663 return -TARGET_ENOSYS;
5668 void process_pending_signals(CPUArchState *cpu_env)
5670 CPUState *cpu = ENV_GET_CPU(cpu_env);
5673 sigset_t set, old_set;
5674 target_sigset_t target_old_set;
5675 struct emulated_sigtable *k;
5676 struct target_sigaction *sa;
5678 TaskState *ts = cpu_env->opaque;
5680 if (!ts->signal_pending)
5683 /* FIXME: This is not threadsafe. */
5685 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5690 /* if no signal is pending, just return */
5691 ts->signal_pending = 0;
5696 fprintf(stderr, "qemu: process signal %d\n", sig);
5698 /* dequeue signal */
5704 sig = gdb_handlesig(cpu, sig);
5707 handler = TARGET_SIG_IGN;
5709 sa = &sigact_table[sig - 1];
5710 handler = sa->_sa_handler;
5713 if (handler == TARGET_SIG_DFL) {
5714 /* default handler : ignore some signal. The other are job control or fatal */
5715 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5716 kill(getpid(),SIGSTOP);
5717 } else if (sig != TARGET_SIGCHLD &&
5718 sig != TARGET_SIGURG &&
5719 sig != TARGET_SIGWINCH &&
5720 sig != TARGET_SIGCONT) {
5723 } else if (handler == TARGET_SIG_IGN) {
5725 } else if (handler == TARGET_SIG_ERR) {
5728 /* compute the blocked signals during the handler execution */
5729 target_to_host_sigset(&set, &sa->sa_mask);
5730 /* SA_NODEFER indicates that the current signal should not be
5731 blocked during the handler */
5732 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5733 sigaddset(&set, target_to_host_signal(sig));
5735 /* block signals in the handler using Linux */
5736 sigprocmask(SIG_BLOCK, &set, &old_set);
5737 /* save the previous blocked signal state to restore it at the
5738 end of the signal execution (see do_sigreturn) */
5739 host_to_target_sigset_internal(&target_old_set, &old_set);
5741 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5742 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5744 CPUX86State *env = cpu_env;
5745 if (env->eflags & VM_MASK)
5746 save_v86_state(env);
5749 /* prepare the stack frame of the virtual CPU */
5750 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5751 /* These targets do not have traditional signals. */
5752 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5754 if (sa->sa_flags & TARGET_SA_SIGINFO)
5755 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5757 setup_frame(sig, sa, &target_old_set, cpu_env);
5759 if (sa->sa_flags & TARGET_SA_RESETHAND)
5760 sa->_sa_handler = TARGET_SIG_DFL;
5763 free_sigqueue(cpu_env, q);