s390x/kvm: Rework SIGP INITIAL CPU RESET handler
[qemu/ar7.git] / linux-user / signal.c
blob04638e2ead79722b9f5030effdf20ba26e64a1d1
1 /*
2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include <sys/ucontext.h>
27 #include <sys/resource.h>
29 #include "qemu.h"
30 #include "qemu-common.h"
31 #include "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used = {
36 .ss_sp = 0,
37 .ss_size = 0,
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,
44 void *puc);
46 static uint8_t host_to_target_signal_table[_NSIG] = {
47 [SIGHUP] = TARGET_SIGHUP,
48 [SIGINT] = TARGET_SIGINT,
49 [SIGQUIT] = TARGET_SIGQUIT,
50 [SIGILL] = TARGET_SIGILL,
51 [SIGTRAP] = TARGET_SIGTRAP,
52 [SIGABRT] = TARGET_SIGABRT,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS] = TARGET_SIGBUS,
55 [SIGFPE] = TARGET_SIGFPE,
56 [SIGKILL] = TARGET_SIGKILL,
57 [SIGUSR1] = TARGET_SIGUSR1,
58 [SIGSEGV] = TARGET_SIGSEGV,
59 [SIGUSR2] = TARGET_SIGUSR2,
60 [SIGPIPE] = TARGET_SIGPIPE,
61 [SIGALRM] = TARGET_SIGALRM,
62 [SIGTERM] = TARGET_SIGTERM,
63 #ifdef SIGSTKFLT
64 [SIGSTKFLT] = TARGET_SIGSTKFLT,
65 #endif
66 [SIGCHLD] = TARGET_SIGCHLD,
67 [SIGCONT] = TARGET_SIGCONT,
68 [SIGSTOP] = TARGET_SIGSTOP,
69 [SIGTSTP] = TARGET_SIGTSTP,
70 [SIGTTIN] = TARGET_SIGTTIN,
71 [SIGTTOU] = TARGET_SIGTTOU,
72 [SIGURG] = TARGET_SIGURG,
73 [SIGXCPU] = TARGET_SIGXCPU,
74 [SIGXFSZ] = TARGET_SIGXFSZ,
75 [SIGVTALRM] = TARGET_SIGVTALRM,
76 [SIGPROF] = TARGET_SIGPROF,
77 [SIGWINCH] = TARGET_SIGWINCH,
78 [SIGIO] = TARGET_SIGIO,
79 [SIGPWR] = TARGET_SIGPWR,
80 [SIGSYS] = TARGET_SIGSYS,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN] = __SIGRTMAX,
87 [__SIGRTMAX] = __SIGRTMIN,
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)
106 return sig;
107 return host_to_target_signal_table[sig];
110 int target_to_host_signal(int sig)
112 if (sig < 0 || sig >= _NSIG)
113 return sig;
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)
124 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)
131 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,
137 const sigset_t *s)
139 int i;
140 target_sigemptyset(d);
141 for (i = 1; i <= TARGET_NSIG; i++) {
142 if (sigismember(s, i)) {
143 target_sigaddset(d, host_to_target_signal(i));
148 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
150 target_sigset_t d1;
151 int i;
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)
161 int i;
162 sigemptyset(d);
163 for (i = 1; i <= TARGET_NSIG; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
170 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
172 target_sigset_t s1;
173 int i;
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)
183 target_sigset_t d;
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)
191 target_sigset_t d;
192 int i;
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS; i++)
196 d.sig[i] = 0;
197 target_to_host_sigset(sigset, &d);
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;
207 tinfo->si_errno = 0;
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)
291 switch (sig) {
292 case TARGET_SIGCHLD:
293 case TARGET_SIGURG:
294 case TARGET_SIGWINCH:
295 /* Ignored by default. */
296 return 0;
297 case TARGET_SIGCONT:
298 case TARGET_SIGSTOP:
299 case TARGET_SIGTSTP:
300 case TARGET_SIGTTIN:
301 case TARGET_SIGTTOU:
302 /* Job control signals. */
303 return 0;
304 default:
305 return 1;
309 /* returns 1 if given signal should dump core if not handled */
310 static int core_dump_signal(int sig)
312 switch (sig) {
313 case TARGET_SIGABRT:
314 case TARGET_SIGFPE:
315 case TARGET_SIGILL:
316 case TARGET_SIGQUIT:
317 case TARGET_SIGSEGV:
318 case TARGET_SIGTRAP:
319 case TARGET_SIGBUS:
320 return (1);
321 default:
322 return (0);
326 void signal_init(void)
328 struct sigaction act;
329 struct sigaction oact;
330 int i, j;
331 int host_sig;
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;
375 if (!q)
376 return NULL;
377 ts->first_free = q->next;
378 return q;
381 static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
383 TaskState *ts = env->opaque;
384 q->next = ts->first_free;
385 ts->first_free = q;
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)) {
400 stop_all_tasks();
401 core_dumped =
402 ((*ts->bprm->core_dump)(target_sig, env) == 0);
404 if (core_dumped) {
405 /* we already dumped the core of target process, we don't want
406 * a coredump of qemu itself */
407 struct rlimit nodump;
408 getrlimit(RLIMIT_CORE, &nodump);
409 nodump.rlim_cur=0;
410 setrlimit(RLIMIT_CORE, &nodump);
411 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
412 target_sig, strsignal(host_sig), "core dumped" );
415 /* The proper exit code for dying from an uncaught signal is
416 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
417 * a negative value. To get the proper exit code we need to
418 * actually die from an uncaught signal. Here the default signal
419 * handler is installed, we send ourself a signal and we wait for
420 * it to arrive. */
421 sigfillset(&act.sa_mask);
422 act.sa_handler = SIG_DFL;
423 act.sa_flags = 0;
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
431 of act) */
432 sigdelset(&act.sa_mask, host_sig);
433 sigsuspend(&act.sa_mask);
435 /* unreachable */
436 abort();
439 /* queue a signal so that it will be send to the virtual CPU as soon
440 as possible */
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;
446 abi_ulong handler;
447 int queue;
449 #if defined(DEBUG_SIGNAL)
450 fprintf(stderr, "queue_signal: sig=%d\n",
451 sig);
452 #endif
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);
459 return 0;
460 } else
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) {
466 force_sig(sig);
467 } else {
468 return 0; /* indicate ignored */
470 } else if (!queue && handler == TARGET_SIG_IGN) {
471 /* ignore signal */
472 return 0;
473 } else if (!queue && handler == TARGET_SIG_ERR) {
474 force_sig(sig);
475 } else {
476 pq = &k->first;
477 if (sig < TARGET_SIGRTMIN) {
478 /* if non real time signal, we queue exactly one signal */
479 if (!k->pending)
480 q = &k->info;
481 else
482 return 0;
483 } else {
484 if (!k->pending) {
485 /* first signal */
486 q = &k->info;
487 } else {
488 q = alloc_sigqueue(env);
489 if (!q)
490 return -EAGAIN;
491 while (*pq != NULL)
492 pq = &(*pq)->next;
495 *pq = q;
496 q->info = *info;
497 q->next = NULL;
498 k->pending = 1;
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,
506 void *puc)
508 CPUArchState *env = thread_cpu->env_ptr;
509 int sig;
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))
517 return;
520 /* get target signal number */
521 sig = host_to_target_signal(host_signum);
522 if (sig < 1 || sig > TARGET_NSIG)
523 return;
524 #if defined(DEBUG_SIGNAL)
525 fprintf(stderr, "qemu: got signal %d\n", sig);
526 #endif
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)
538 int ret;
539 struct target_sigaltstack oss;
541 /* XXX: test errors */
542 if(uoss_addr)
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);
549 if(uss_addr)
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))
559 goto out;
560 unlock_user_struct(uss, uss_addr, 0);
562 ret = -TARGET_EPERM;
563 if (on_sig_stack(sp))
564 goto out;
566 ret = -TARGET_EINVAL;
567 if (ss.ss_flags != TARGET_SS_DISABLE
568 && ss.ss_flags != TARGET_SS_ONSTACK
569 && ss.ss_flags != 0)
570 goto out;
572 if (ss.ss_flags == TARGET_SS_DISABLE) {
573 ss.ss_size = 0;
574 ss.ss_sp = 0;
575 } else {
576 ret = -TARGET_ENOMEM;
577 if (ss.ss_size < MINSIGSTKSZ)
578 goto out;
581 target_sigaltstack_used.ss_sp = ss.ss_sp;
582 target_sigaltstack_used.ss_size = ss.ss_size;
585 if (uoss_addr) {
586 ret = -TARGET_EFAULT;
587 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
588 goto out;
591 ret = 0;
592 out:
593 return ret;
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;
602 int host_sig;
603 int ret = 0;
605 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
606 return -EINVAL;
607 k = &sigact_table[sig - 1];
608 #if defined(DEBUG_SIGNAL)
609 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
610 sig, act, oact);
611 #endif
612 if (oact) {
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);
617 #endif
618 /* Not swapped. */
619 oact->sa_mask = k->sa_mask;
621 if (act) {
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);
627 #endif
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
640 syscalls */
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;
646 else
647 act1.sa_sigaction = (void *)SIG_DFL;
648 } else {
649 act1.sa_sigaction = host_signal_handler;
651 ret = sigaction(host_sig, &act1, NULL);
654 return ret;
657 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
658 const target_siginfo_t *info)
660 tswap_siginfo(tinfo, info);
661 return 0;
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];
676 uint16_t exponent;
679 struct target_fpxreg {
680 uint16_t significand[4];
681 uint16_t exponent;
682 uint16_t padding[3];
685 struct target_xmmreg {
686 abi_ulong element[4];
689 struct target_fpstate {
690 /* Regular FPU environment */
691 abi_ulong cw;
692 abi_ulong sw;
693 abi_ulong tag;
694 abi_ulong ipoff;
695 abi_ulong cssel;
696 abi_ulong dataoff;
697 abi_ulong datasel;
698 struct target_fpreg _st[8];
699 uint16_t status;
700 uint16_t magic; /* 0xffff = regular FPU data only */
702 /* FXSR FPU environment */
703 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
704 abi_ulong mxcsr;
705 abi_ulong reserved;
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 {
714 uint16_t gs, __gsh;
715 uint16_t fs, __fsh;
716 uint16_t es, __esh;
717 uint16_t ds, __dsh;
718 abi_ulong edi;
719 abi_ulong esi;
720 abi_ulong ebp;
721 abi_ulong esp;
722 abi_ulong ebx;
723 abi_ulong edx;
724 abi_ulong ecx;
725 abi_ulong eax;
726 abi_ulong trapno;
727 abi_ulong err;
728 abi_ulong eip;
729 uint16_t cs, __csh;
730 abi_ulong eflags;
731 abi_ulong esp_at_signal;
732 uint16_t ss, __ssh;
733 abi_ulong fpstate; /* pointer */
734 abi_ulong oldmask;
735 abi_ulong cr2;
738 struct target_ucontext {
739 abi_ulong tuc_flags;
740 abi_ulong tuc_link;
741 target_stack_t tuc_stack;
742 struct target_sigcontext tuc_mcontext;
743 target_sigset_t tuc_sigmask; /* mask last for extensibility */
746 struct sigframe
748 abi_ulong pretcode;
749 int sig;
750 struct target_sigcontext sc;
751 struct target_fpstate fpstate;
752 abi_ulong extramask[TARGET_NSIG_WORDS-1];
753 char retcode[8];
756 struct rt_sigframe
758 abi_ulong pretcode;
759 int sig;
760 abi_ulong pinfo;
761 abi_ulong puc;
762 struct target_siginfo info;
763 struct target_ucontext uc;
764 struct target_fpstate fpstate;
765 char retcode[8];
769 * Set up a signal frame.
772 /* XXX: save x87 state */
773 static int
774 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
775 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
777 int err = 0;
778 uint16_t magic;
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;
803 magic = 0xffff;
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);
810 return err;
814 * Determine which stack to use..
817 static inline abi_ulong
818 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
820 unsigned long esp;
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. */
831 else
832 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
833 !(ka->sa_flags & TARGET_SA_RESTORER) &&
834 ka->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;
846 int i, err = 0;
848 frame_addr = get_sigframe(ka, env, sizeof(*frame));
850 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
851 goto give_sigsegv;
853 err |= __put_user(current_exec_domain_sig(sig),
854 &frame->sig);
855 if (err)
856 goto give_sigsegv;
858 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
859 frame_addr + offsetof(struct sigframe, fpstate));
860 if (err)
861 goto give_sigsegv;
863 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
864 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
865 goto give_sigsegv;
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);
872 } else {
873 uint16_t val16;
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 */
878 val16 = 0xb858;
879 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
880 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
881 val16 = 0x80cd;
882 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
885 if (err)
886 goto give_sigsegv;
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);
900 return;
902 give_sigsegv:
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;
916 int i, err = 0;
918 frame_addr = get_sigframe(ka, env, sizeof(*frame));
920 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
921 goto give_sigsegv;
923 err |= __put_user(current_exec_domain_sig(sig),
924 &frame->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);
930 if (err)
931 goto give_sigsegv;
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,
943 env, set->sig[0],
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]))
947 goto give_sigsegv;
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);
954 } else {
955 uint16_t val16;
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));
961 val16 = 0x80cd;
962 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
965 if (err)
966 goto give_sigsegv;
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);
980 return;
982 give_sigsegv:
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 */);
989 static int
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)))
1021 goto badframe;
1022 cpu_x86_frstor(env, fpstate_addr, 1);
1025 *peax = tswapl(sc->eax);
1026 return err;
1027 badframe:
1028 return 1;
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;
1036 sigset_t set;
1037 int eax, i;
1039 #if defined(DEBUG_SIGNAL)
1040 fprintf(stderr, "do_sigreturn\n");
1041 #endif
1042 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1043 goto badframe;
1044 /* set blocked signals */
1045 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1046 goto badframe;
1047 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1048 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1049 goto badframe;
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))
1057 goto badframe;
1058 unlock_user_struct(frame, frame_addr, 0);
1059 return eax;
1061 badframe:
1062 unlock_user_struct(frame, frame_addr, 0);
1063 force_sig(TARGET_SIGSEGV);
1064 return 0;
1067 long do_rt_sigreturn(CPUX86State *env)
1069 abi_ulong frame_addr;
1070 struct rt_sigframe *frame;
1071 sigset_t set;
1072 int eax;
1074 frame_addr = env->regs[R_ESP] - 4;
1075 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1076 goto badframe;
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))
1081 goto badframe;
1083 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1084 get_sp_from_cpustate(env)) == -EFAULT)
1085 goto badframe;
1087 unlock_user_struct(frame, frame_addr, 0);
1088 return eax;
1090 badframe:
1091 unlock_user_struct(frame, frame_addr, 0);
1092 force_sig(TARGET_SIGSEGV);
1093 return 0;
1096 #elif defined(TARGET_AARCH64)
1098 struct target_sigcontext {
1099 uint64_t fault_address;
1100 /* AArch64 registers */
1101 uint64_t regs[31];
1102 uint64_t sp;
1103 uint64_t pc;
1104 uint64_t pstate;
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;
1111 abi_ulong tuc_link;
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 {
1127 uint32_t magic;
1128 uint32_t size;
1131 #define TARGET_FPSIMD_MAGIC 0x46508001
1133 struct target_fpsimd_context {
1134 struct target_aarch64_ctx head;
1135 uint32_t fpsr;
1136 uint32_t fpcr;
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;
1154 uint64_t fp;
1155 uint64_t lr;
1156 uint32_t tramp[2];
1159 static int target_setup_sigframe(struct target_rt_sigframe *sf,
1160 CPUARMState *env, target_sigset_t *set)
1162 int i;
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]);
1188 #else
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]);
1191 #endif
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);
1203 return 0;
1206 static int target_restore_sigframe(CPUARMState *env,
1207 struct target_rt_sigframe *sf)
1209 sigset_t set;
1210 int i;
1211 struct target_aux_context *aux =
1212 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1213 uint32_t magic, size, fpsr, fpcr;
1214 uint64_t pstate;
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)) {
1233 return 1;
1236 for (i = 0; i < 32 * 2; i++) {
1237 __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]);
1239 __get_user(fpsr, &aux->fpsimd.fpsr);
1240 vfp_set_fpsr(env, fpsr);
1241 __get_user(fpcr, &aux->fpsimd.fpcr);
1242 vfp_set_fpcr(env, fpcr);
1244 return 0;
1247 static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1249 abi_ulong sp;
1251 sp = env->xregs[31];
1254 * This is the X/Open sanctioned signal stack switching.
1256 if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
1257 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1260 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1262 return sp;
1265 static void target_setup_frame(int usig, struct target_sigaction *ka,
1266 target_siginfo_t *info, target_sigset_t *set,
1267 CPUARMState *env)
1269 struct target_rt_sigframe *frame;
1270 abi_ulong frame_addr;
1272 frame_addr = get_sigframe(ka, env);
1273 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1274 goto give_sigsegv;
1277 __put_user(0, &frame->uc.tuc_flags);
1278 __put_user(0, &frame->uc.tuc_link);
1280 __put_user(target_sigaltstack_used.ss_sp,
1281 &frame->uc.tuc_stack.ss_sp);
1282 __put_user(sas_ss_flags(env->xregs[31]),
1283 &frame->uc.tuc_stack.ss_flags);
1284 __put_user(target_sigaltstack_used.ss_size,
1285 &frame->uc.tuc_stack.ss_size);
1286 target_setup_sigframe(frame, env, set);
1287 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1288 __put_user(0xd2801168, &frame->tramp[0]);
1289 __put_user(0xd4000001, &frame->tramp[1]);
1290 env->xregs[0] = usig;
1291 env->xregs[31] = frame_addr;
1292 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
1293 env->pc = ka->_sa_handler;
1294 env->xregs[30] = env->xregs[31] +
1295 offsetof(struct target_rt_sigframe, tramp);
1296 if (info) {
1297 if (copy_siginfo_to_user(&frame->info, info)) {
1298 goto give_sigsegv;
1300 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1301 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1304 unlock_user_struct(frame, frame_addr, 1);
1305 return;
1307 give_sigsegv:
1308 unlock_user_struct(frame, frame_addr, 1);
1309 force_sig(TARGET_SIGSEGV);
1312 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1313 target_siginfo_t *info, target_sigset_t *set,
1314 CPUARMState *env)
1316 target_setup_frame(sig, ka, info, set, env);
1319 static void setup_frame(int sig, struct target_sigaction *ka,
1320 target_sigset_t *set, CPUARMState *env)
1322 target_setup_frame(sig, ka, 0, set, env);
1325 long do_rt_sigreturn(CPUARMState *env)
1327 struct target_rt_sigframe *frame;
1328 abi_ulong frame_addr = env->xregs[31];
1330 if (frame_addr & 15) {
1331 goto badframe;
1334 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1335 goto badframe;
1338 if (target_restore_sigframe(env, frame)) {
1339 goto badframe;
1342 if (do_sigaltstack(frame_addr +
1343 offsetof(struct target_rt_sigframe, uc.tuc_stack),
1344 0, get_sp_from_cpustate(env)) == -EFAULT) {
1345 goto badframe;
1348 unlock_user_struct(frame, frame_addr, 0);
1349 return env->xregs[0];
1351 badframe:
1352 unlock_user_struct(frame, frame_addr, 0);
1353 force_sig(TARGET_SIGSEGV);
1354 return 0;
1357 long do_sigreturn(CPUARMState *env)
1359 return do_rt_sigreturn(env);
1362 #elif defined(TARGET_ARM)
1364 struct target_sigcontext {
1365 abi_ulong trap_no;
1366 abi_ulong error_code;
1367 abi_ulong oldmask;
1368 abi_ulong arm_r0;
1369 abi_ulong arm_r1;
1370 abi_ulong arm_r2;
1371 abi_ulong arm_r3;
1372 abi_ulong arm_r4;
1373 abi_ulong arm_r5;
1374 abi_ulong arm_r6;
1375 abi_ulong arm_r7;
1376 abi_ulong arm_r8;
1377 abi_ulong arm_r9;
1378 abi_ulong arm_r10;
1379 abi_ulong arm_fp;
1380 abi_ulong arm_ip;
1381 abi_ulong arm_sp;
1382 abi_ulong arm_lr;
1383 abi_ulong arm_pc;
1384 abi_ulong arm_cpsr;
1385 abi_ulong fault_address;
1388 struct target_ucontext_v1 {
1389 abi_ulong tuc_flags;
1390 abi_ulong tuc_link;
1391 target_stack_t tuc_stack;
1392 struct target_sigcontext tuc_mcontext;
1393 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1396 struct target_ucontext_v2 {
1397 abi_ulong tuc_flags;
1398 abi_ulong tuc_link;
1399 target_stack_t tuc_stack;
1400 struct target_sigcontext tuc_mcontext;
1401 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1402 char __unused[128 - sizeof(target_sigset_t)];
1403 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1406 struct target_user_vfp {
1407 uint64_t fpregs[32];
1408 abi_ulong fpscr;
1411 struct target_user_vfp_exc {
1412 abi_ulong fpexc;
1413 abi_ulong fpinst;
1414 abi_ulong fpinst2;
1417 struct target_vfp_sigframe {
1418 abi_ulong magic;
1419 abi_ulong size;
1420 struct target_user_vfp ufp;
1421 struct target_user_vfp_exc ufp_exc;
1422 } __attribute__((__aligned__(8)));
1424 struct target_iwmmxt_sigframe {
1425 abi_ulong magic;
1426 abi_ulong size;
1427 uint64_t regs[16];
1428 /* Note that not all the coprocessor control registers are stored here */
1429 uint32_t wcssf;
1430 uint32_t wcasf;
1431 uint32_t wcgr0;
1432 uint32_t wcgr1;
1433 uint32_t wcgr2;
1434 uint32_t wcgr3;
1435 } __attribute__((__aligned__(8)));
1437 #define TARGET_VFP_MAGIC 0x56465001
1438 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1440 struct sigframe_v1
1442 struct target_sigcontext sc;
1443 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1444 abi_ulong retcode;
1447 struct sigframe_v2
1449 struct target_ucontext_v2 uc;
1450 abi_ulong retcode;
1453 struct rt_sigframe_v1
1455 abi_ulong pinfo;
1456 abi_ulong puc;
1457 struct target_siginfo info;
1458 struct target_ucontext_v1 uc;
1459 abi_ulong retcode;
1462 struct rt_sigframe_v2
1464 struct target_siginfo info;
1465 struct target_ucontext_v2 uc;
1466 abi_ulong retcode;
1469 #define TARGET_CONFIG_CPU_32 1
1472 * For ARM syscalls, we encode the syscall number into the instruction.
1474 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1475 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1478 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1479 * need two 16-bit instructions.
1481 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1482 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1484 static const abi_ulong retcodes[4] = {
1485 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1486 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1490 #define __get_user_error(x,p,e) __get_user(x, p)
1492 static inline int valid_user_regs(CPUARMState *regs)
1494 return 1;
1497 static void
1498 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1499 CPUARMState *env, abi_ulong mask)
1501 __put_user(env->regs[0], &sc->arm_r0);
1502 __put_user(env->regs[1], &sc->arm_r1);
1503 __put_user(env->regs[2], &sc->arm_r2);
1504 __put_user(env->regs[3], &sc->arm_r3);
1505 __put_user(env->regs[4], &sc->arm_r4);
1506 __put_user(env->regs[5], &sc->arm_r5);
1507 __put_user(env->regs[6], &sc->arm_r6);
1508 __put_user(env->regs[7], &sc->arm_r7);
1509 __put_user(env->regs[8], &sc->arm_r8);
1510 __put_user(env->regs[9], &sc->arm_r9);
1511 __put_user(env->regs[10], &sc->arm_r10);
1512 __put_user(env->regs[11], &sc->arm_fp);
1513 __put_user(env->regs[12], &sc->arm_ip);
1514 __put_user(env->regs[13], &sc->arm_sp);
1515 __put_user(env->regs[14], &sc->arm_lr);
1516 __put_user(env->regs[15], &sc->arm_pc);
1517 #ifdef TARGET_CONFIG_CPU_32
1518 __put_user(cpsr_read(env), &sc->arm_cpsr);
1519 #endif
1521 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1522 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1523 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1524 __put_user(mask, &sc->oldmask);
1527 static inline abi_ulong
1528 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1530 unsigned long sp = regs->regs[13];
1533 * This is the X/Open sanctioned signal stack switching.
1535 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1536 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1538 * ATPCS B01 mandates 8-byte alignment
1540 return (sp - framesize) & ~7;
1543 static int
1544 setup_return(CPUARMState *env, struct target_sigaction *ka,
1545 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1547 abi_ulong handler = ka->_sa_handler;
1548 abi_ulong retcode;
1549 int thumb = handler & 1;
1550 uint32_t cpsr = cpsr_read(env);
1552 cpsr &= ~CPSR_IT;
1553 if (thumb) {
1554 cpsr |= CPSR_T;
1555 } else {
1556 cpsr &= ~CPSR_T;
1559 if (ka->sa_flags & TARGET_SA_RESTORER) {
1560 retcode = ka->sa_restorer;
1561 } else {
1562 unsigned int idx = thumb;
1564 if (ka->sa_flags & TARGET_SA_SIGINFO)
1565 idx += 2;
1567 if (__put_user(retcodes[idx], rc))
1568 return 1;
1570 retcode = rc_addr + thumb;
1573 env->regs[0] = usig;
1574 env->regs[13] = frame_addr;
1575 env->regs[14] = retcode;
1576 env->regs[15] = handler & (thumb ? ~1 : ~3);
1577 cpsr_write(env, cpsr, 0xffffffff);
1579 return 0;
1582 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1584 int i;
1585 struct target_vfp_sigframe *vfpframe;
1586 vfpframe = (struct target_vfp_sigframe *)regspace;
1587 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1588 __put_user(sizeof(*vfpframe), &vfpframe->size);
1589 for (i = 0; i < 32; i++) {
1590 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1592 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1593 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1594 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1595 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1596 return (abi_ulong*)(vfpframe+1);
1599 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1600 CPUARMState *env)
1602 int i;
1603 struct target_iwmmxt_sigframe *iwmmxtframe;
1604 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1605 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1606 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1607 for (i = 0; i < 16; i++) {
1608 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1610 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1611 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1612 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1613 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1614 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1615 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1616 return (abi_ulong*)(iwmmxtframe+1);
1619 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1620 target_sigset_t *set, CPUARMState *env)
1622 struct target_sigaltstack stack;
1623 int i;
1624 abi_ulong *regspace;
1626 /* Clear all the bits of the ucontext we don't use. */
1627 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1629 memset(&stack, 0, sizeof(stack));
1630 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1631 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1632 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1633 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1635 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1636 /* Save coprocessor signal frame. */
1637 regspace = uc->tuc_regspace;
1638 if (arm_feature(env, ARM_FEATURE_VFP)) {
1639 regspace = setup_sigframe_v2_vfp(regspace, env);
1641 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1642 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1645 /* Write terminating magic word */
1646 __put_user(0, regspace);
1648 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1649 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1653 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1654 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1655 target_sigset_t *set, CPUARMState *regs)
1657 struct sigframe_v1 *frame;
1658 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1659 int i;
1661 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1662 return;
1664 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1666 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1667 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1668 goto end;
1671 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1672 frame_addr + offsetof(struct sigframe_v1, retcode));
1674 end:
1675 unlock_user_struct(frame, frame_addr, 1);
1678 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1679 target_sigset_t *set, CPUARMState *regs)
1681 struct sigframe_v2 *frame;
1682 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1684 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1685 return;
1687 setup_sigframe_v2(&frame->uc, set, regs);
1689 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1690 frame_addr + offsetof(struct sigframe_v2, retcode));
1692 unlock_user_struct(frame, frame_addr, 1);
1695 static void setup_frame(int usig, struct target_sigaction *ka,
1696 target_sigset_t *set, CPUARMState *regs)
1698 if (get_osversion() >= 0x020612) {
1699 setup_frame_v2(usig, ka, set, regs);
1700 } else {
1701 setup_frame_v1(usig, ka, set, regs);
1705 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1706 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1707 target_siginfo_t *info,
1708 target_sigset_t *set, CPUARMState *env)
1710 struct rt_sigframe_v1 *frame;
1711 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1712 struct target_sigaltstack stack;
1713 int i;
1714 abi_ulong info_addr, uc_addr;
1716 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1717 return /* 1 */;
1719 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1720 __put_user(info_addr, &frame->pinfo);
1721 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1722 __put_user(uc_addr, &frame->puc);
1723 copy_siginfo_to_user(&frame->info, info);
1725 /* Clear all the bits of the ucontext we don't use. */
1726 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1728 memset(&stack, 0, sizeof(stack));
1729 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1730 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1731 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1732 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1734 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1735 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1736 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1737 goto end;
1740 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1741 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1743 env->regs[1] = info_addr;
1744 env->regs[2] = uc_addr;
1746 end:
1747 unlock_user_struct(frame, frame_addr, 1);
1750 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1751 target_siginfo_t *info,
1752 target_sigset_t *set, CPUARMState *env)
1754 struct rt_sigframe_v2 *frame;
1755 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1756 abi_ulong info_addr, uc_addr;
1758 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1759 return /* 1 */;
1761 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1762 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1763 copy_siginfo_to_user(&frame->info, info);
1765 setup_sigframe_v2(&frame->uc, set, env);
1767 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1768 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1770 env->regs[1] = info_addr;
1771 env->regs[2] = uc_addr;
1773 unlock_user_struct(frame, frame_addr, 1);
1776 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1777 target_siginfo_t *info,
1778 target_sigset_t *set, CPUARMState *env)
1780 if (get_osversion() >= 0x020612) {
1781 setup_rt_frame_v2(usig, ka, info, set, env);
1782 } else {
1783 setup_rt_frame_v1(usig, ka, info, set, env);
1787 static int
1788 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1790 int err = 0;
1791 uint32_t cpsr;
1793 __get_user_error(env->regs[0], &sc->arm_r0, err);
1794 __get_user_error(env->regs[1], &sc->arm_r1, err);
1795 __get_user_error(env->regs[2], &sc->arm_r2, err);
1796 __get_user_error(env->regs[3], &sc->arm_r3, err);
1797 __get_user_error(env->regs[4], &sc->arm_r4, err);
1798 __get_user_error(env->regs[5], &sc->arm_r5, err);
1799 __get_user_error(env->regs[6], &sc->arm_r6, err);
1800 __get_user_error(env->regs[7], &sc->arm_r7, err);
1801 __get_user_error(env->regs[8], &sc->arm_r8, err);
1802 __get_user_error(env->regs[9], &sc->arm_r9, err);
1803 __get_user_error(env->regs[10], &sc->arm_r10, err);
1804 __get_user_error(env->regs[11], &sc->arm_fp, err);
1805 __get_user_error(env->regs[12], &sc->arm_ip, err);
1806 __get_user_error(env->regs[13], &sc->arm_sp, err);
1807 __get_user_error(env->regs[14], &sc->arm_lr, err);
1808 __get_user_error(env->regs[15], &sc->arm_pc, err);
1809 #ifdef TARGET_CONFIG_CPU_32
1810 __get_user_error(cpsr, &sc->arm_cpsr, err);
1811 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1812 #endif
1814 err |= !valid_user_regs(env);
1816 return err;
1819 static long do_sigreturn_v1(CPUARMState *env)
1821 abi_ulong frame_addr;
1822 struct sigframe_v1 *frame = NULL;
1823 target_sigset_t set;
1824 sigset_t host_set;
1825 int i;
1828 * Since we stacked the signal on a 64-bit boundary,
1829 * then 'sp' should be word aligned here. If it's
1830 * not, then the user is trying to mess with us.
1832 frame_addr = env->regs[13];
1833 if (frame_addr & 7) {
1834 goto badframe;
1837 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1838 goto badframe;
1840 if (__get_user(set.sig[0], &frame->sc.oldmask))
1841 goto badframe;
1842 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1843 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1844 goto badframe;
1847 target_to_host_sigset_internal(&host_set, &set);
1848 sigprocmask(SIG_SETMASK, &host_set, NULL);
1850 if (restore_sigcontext(env, &frame->sc))
1851 goto badframe;
1853 #if 0
1854 /* Send SIGTRAP if we're single-stepping */
1855 if (ptrace_cancel_bpt(current))
1856 send_sig(SIGTRAP, current, 1);
1857 #endif
1858 unlock_user_struct(frame, frame_addr, 0);
1859 return env->regs[0];
1861 badframe:
1862 unlock_user_struct(frame, frame_addr, 0);
1863 force_sig(TARGET_SIGSEGV /* , current */);
1864 return 0;
1867 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1869 int i;
1870 abi_ulong magic, sz;
1871 uint32_t fpscr, fpexc;
1872 struct target_vfp_sigframe *vfpframe;
1873 vfpframe = (struct target_vfp_sigframe *)regspace;
1875 __get_user(magic, &vfpframe->magic);
1876 __get_user(sz, &vfpframe->size);
1877 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1878 return 0;
1880 for (i = 0; i < 32; i++) {
1881 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1883 __get_user(fpscr, &vfpframe->ufp.fpscr);
1884 vfp_set_fpscr(env, fpscr);
1885 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1886 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1887 * and the exception flag is cleared
1889 fpexc |= (1 << 30);
1890 fpexc &= ~((1 << 31) | (1 << 28));
1891 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1892 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1893 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1894 return (abi_ulong*)(vfpframe + 1);
1897 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1898 abi_ulong *regspace)
1900 int i;
1901 abi_ulong magic, sz;
1902 struct target_iwmmxt_sigframe *iwmmxtframe;
1903 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1905 __get_user(magic, &iwmmxtframe->magic);
1906 __get_user(sz, &iwmmxtframe->size);
1907 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1908 return 0;
1910 for (i = 0; i < 16; i++) {
1911 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1913 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1914 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1915 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1916 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1917 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1918 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1919 return (abi_ulong*)(iwmmxtframe + 1);
1922 static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1923 struct target_ucontext_v2 *uc)
1925 sigset_t host_set;
1926 abi_ulong *regspace;
1928 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1929 sigprocmask(SIG_SETMASK, &host_set, NULL);
1931 if (restore_sigcontext(env, &uc->tuc_mcontext))
1932 return 1;
1934 /* Restore coprocessor signal frame */
1935 regspace = uc->tuc_regspace;
1936 if (arm_feature(env, ARM_FEATURE_VFP)) {
1937 regspace = restore_sigframe_v2_vfp(env, regspace);
1938 if (!regspace) {
1939 return 1;
1942 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1943 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1944 if (!regspace) {
1945 return 1;
1949 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1950 return 1;
1952 #if 0
1953 /* Send SIGTRAP if we're single-stepping */
1954 if (ptrace_cancel_bpt(current))
1955 send_sig(SIGTRAP, current, 1);
1956 #endif
1958 return 0;
1961 static long do_sigreturn_v2(CPUARMState *env)
1963 abi_ulong frame_addr;
1964 struct sigframe_v2 *frame = NULL;
1967 * Since we stacked the signal on a 64-bit boundary,
1968 * then 'sp' should be word aligned here. If it's
1969 * not, then the user is trying to mess with us.
1971 frame_addr = env->regs[13];
1972 if (frame_addr & 7) {
1973 goto badframe;
1976 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1977 goto badframe;
1979 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1980 goto badframe;
1982 unlock_user_struct(frame, frame_addr, 0);
1983 return env->regs[0];
1985 badframe:
1986 unlock_user_struct(frame, frame_addr, 0);
1987 force_sig(TARGET_SIGSEGV /* , current */);
1988 return 0;
1991 long do_sigreturn(CPUARMState *env)
1993 if (get_osversion() >= 0x020612) {
1994 return do_sigreturn_v2(env);
1995 } else {
1996 return do_sigreturn_v1(env);
2000 static long do_rt_sigreturn_v1(CPUARMState *env)
2002 abi_ulong frame_addr;
2003 struct rt_sigframe_v1 *frame = NULL;
2004 sigset_t host_set;
2007 * Since we stacked the signal on a 64-bit boundary,
2008 * then 'sp' should be word aligned here. If it's
2009 * not, then the user is trying to mess with us.
2011 frame_addr = env->regs[13];
2012 if (frame_addr & 7) {
2013 goto badframe;
2016 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2017 goto badframe;
2019 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2020 sigprocmask(SIG_SETMASK, &host_set, NULL);
2022 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2023 goto badframe;
2025 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2026 goto badframe;
2028 #if 0
2029 /* Send SIGTRAP if we're single-stepping */
2030 if (ptrace_cancel_bpt(current))
2031 send_sig(SIGTRAP, current, 1);
2032 #endif
2033 unlock_user_struct(frame, frame_addr, 0);
2034 return env->regs[0];
2036 badframe:
2037 unlock_user_struct(frame, frame_addr, 0);
2038 force_sig(TARGET_SIGSEGV /* , current */);
2039 return 0;
2042 static long do_rt_sigreturn_v2(CPUARMState *env)
2044 abi_ulong frame_addr;
2045 struct rt_sigframe_v2 *frame = NULL;
2048 * Since we stacked the signal on a 64-bit boundary,
2049 * then 'sp' should be word aligned here. If it's
2050 * not, then the user is trying to mess with us.
2052 frame_addr = env->regs[13];
2053 if (frame_addr & 7) {
2054 goto badframe;
2057 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2058 goto badframe;
2060 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2061 goto badframe;
2063 unlock_user_struct(frame, frame_addr, 0);
2064 return env->regs[0];
2066 badframe:
2067 unlock_user_struct(frame, frame_addr, 0);
2068 force_sig(TARGET_SIGSEGV /* , current */);
2069 return 0;
2072 long do_rt_sigreturn(CPUARMState *env)
2074 if (get_osversion() >= 0x020612) {
2075 return do_rt_sigreturn_v2(env);
2076 } else {
2077 return do_rt_sigreturn_v1(env);
2081 #elif defined(TARGET_SPARC)
2083 #define __SUNOS_MAXWIN 31
2085 /* This is what SunOS does, so shall I. */
2086 struct target_sigcontext {
2087 abi_ulong sigc_onstack; /* state to restore */
2089 abi_ulong sigc_mask; /* sigmask to restore */
2090 abi_ulong sigc_sp; /* stack pointer */
2091 abi_ulong sigc_pc; /* program counter */
2092 abi_ulong sigc_npc; /* next program counter */
2093 abi_ulong sigc_psr; /* for condition codes etc */
2094 abi_ulong sigc_g1; /* User uses these two registers */
2095 abi_ulong sigc_o0; /* within the trampoline code. */
2097 /* Now comes information regarding the users window set
2098 * at the time of the signal.
2100 abi_ulong sigc_oswins; /* outstanding windows */
2102 /* stack ptrs for each regwin buf */
2103 char *sigc_spbuf[__SUNOS_MAXWIN];
2105 /* Windows to restore after signal */
2106 struct {
2107 abi_ulong locals[8];
2108 abi_ulong ins[8];
2109 } sigc_wbuf[__SUNOS_MAXWIN];
2111 /* A Sparc stack frame */
2112 struct sparc_stackf {
2113 abi_ulong locals[8];
2114 abi_ulong ins[8];
2115 /* It's simpler to treat fp and callers_pc as elements of ins[]
2116 * since we never need to access them ourselves.
2118 char *structptr;
2119 abi_ulong xargs[6];
2120 abi_ulong xxargs[1];
2123 typedef struct {
2124 struct {
2125 abi_ulong psr;
2126 abi_ulong pc;
2127 abi_ulong npc;
2128 abi_ulong y;
2129 abi_ulong u_regs[16]; /* globals and ins */
2130 } si_regs;
2131 int si_mask;
2132 } __siginfo_t;
2134 typedef struct {
2135 abi_ulong si_float_regs[32];
2136 unsigned long si_fsr;
2137 unsigned long si_fpqdepth;
2138 struct {
2139 unsigned long *insn_addr;
2140 unsigned long insn;
2141 } si_fpqueue [16];
2142 } qemu_siginfo_fpu_t;
2145 struct target_signal_frame {
2146 struct sparc_stackf ss;
2147 __siginfo_t info;
2148 abi_ulong fpu_save;
2149 abi_ulong insns[2] __attribute__ ((aligned (8)));
2150 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
2151 abi_ulong extra_size; /* Should be 0 */
2152 qemu_siginfo_fpu_t fpu_state;
2154 struct target_rt_signal_frame {
2155 struct sparc_stackf ss;
2156 siginfo_t info;
2157 abi_ulong regs[20];
2158 sigset_t mask;
2159 abi_ulong fpu_save;
2160 unsigned int insns[2];
2161 stack_t stack;
2162 unsigned int extra_size; /* Should be 0 */
2163 qemu_siginfo_fpu_t fpu_state;
2166 #define UREG_O0 16
2167 #define UREG_O6 22
2168 #define UREG_I0 0
2169 #define UREG_I1 1
2170 #define UREG_I2 2
2171 #define UREG_I3 3
2172 #define UREG_I4 4
2173 #define UREG_I5 5
2174 #define UREG_I6 6
2175 #define UREG_I7 7
2176 #define UREG_L0 8
2177 #define UREG_FP UREG_I6
2178 #define UREG_SP UREG_O6
2180 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2181 CPUSPARCState *env,
2182 unsigned long framesize)
2184 abi_ulong sp;
2186 sp = env->regwptr[UREG_FP];
2188 /* This is the X/Open sanctioned signal stack switching. */
2189 if (sa->sa_flags & TARGET_SA_ONSTACK) {
2190 if (!on_sig_stack(sp)
2191 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2192 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2194 return sp - framesize;
2197 static int
2198 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2200 int err = 0, i;
2202 err |= __put_user(env->psr, &si->si_regs.psr);
2203 err |= __put_user(env->pc, &si->si_regs.pc);
2204 err |= __put_user(env->npc, &si->si_regs.npc);
2205 err |= __put_user(env->y, &si->si_regs.y);
2206 for (i=0; i < 8; i++) {
2207 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
2209 for (i=0; i < 8; i++) {
2210 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2212 err |= __put_user(mask, &si->si_mask);
2213 return err;
2216 #if 0
2217 static int
2218 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2219 CPUSPARCState *env, unsigned long mask)
2221 int err = 0;
2223 err |= __put_user(mask, &sc->sigc_mask);
2224 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
2225 err |= __put_user(env->pc, &sc->sigc_pc);
2226 err |= __put_user(env->npc, &sc->sigc_npc);
2227 err |= __put_user(env->psr, &sc->sigc_psr);
2228 err |= __put_user(env->gregs[1], &sc->sigc_g1);
2229 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
2231 return err;
2233 #endif
2234 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2236 static void setup_frame(int sig, struct target_sigaction *ka,
2237 target_sigset_t *set, CPUSPARCState *env)
2239 abi_ulong sf_addr;
2240 struct target_signal_frame *sf;
2241 int sigframe_size, err, i;
2243 /* 1. Make sure everything is clean */
2244 //synchronize_user_stack();
2246 sigframe_size = NF_ALIGNEDSZ;
2247 sf_addr = get_sigframe(ka, env, sigframe_size);
2249 sf = lock_user(VERIFY_WRITE, sf_addr,
2250 sizeof(struct target_signal_frame), 0);
2251 if (!sf)
2252 goto sigsegv;
2254 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2255 #if 0
2256 if (invalid_frame_pointer(sf, sigframe_size))
2257 goto sigill_and_return;
2258 #endif
2259 /* 2. Save the current process state */
2260 err = setup___siginfo(&sf->info, env, set->sig[0]);
2261 err |= __put_user(0, &sf->extra_size);
2263 //err |= save_fpu_state(regs, &sf->fpu_state);
2264 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
2266 err |= __put_user(set->sig[0], &sf->info.si_mask);
2267 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2268 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
2271 for (i = 0; i < 8; i++) {
2272 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2274 for (i = 0; i < 8; i++) {
2275 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
2277 if (err)
2278 goto sigsegv;
2280 /* 3. signal handler back-trampoline and parameters */
2281 env->regwptr[UREG_FP] = sf_addr;
2282 env->regwptr[UREG_I0] = sig;
2283 env->regwptr[UREG_I1] = sf_addr +
2284 offsetof(struct target_signal_frame, info);
2285 env->regwptr[UREG_I2] = sf_addr +
2286 offsetof(struct target_signal_frame, info);
2288 /* 4. signal handler */
2289 env->pc = ka->_sa_handler;
2290 env->npc = (env->pc + 4);
2291 /* 5. return to kernel instructions */
2292 if (ka->sa_restorer)
2293 env->regwptr[UREG_I7] = ka->sa_restorer;
2294 else {
2295 uint32_t val32;
2297 env->regwptr[UREG_I7] = sf_addr +
2298 offsetof(struct target_signal_frame, insns) - 2 * 4;
2300 /* mov __NR_sigreturn, %g1 */
2301 val32 = 0x821020d8;
2302 err |= __put_user(val32, &sf->insns[0]);
2304 /* t 0x10 */
2305 val32 = 0x91d02010;
2306 err |= __put_user(val32, &sf->insns[1]);
2307 if (err)
2308 goto sigsegv;
2310 /* Flush instruction space. */
2311 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2312 // tb_flush(env);
2314 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2315 return;
2316 #if 0
2317 sigill_and_return:
2318 force_sig(TARGET_SIGILL);
2319 #endif
2320 sigsegv:
2321 //fprintf(stderr, "force_sig\n");
2322 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2323 force_sig(TARGET_SIGSEGV);
2325 static inline int
2326 restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2328 int err;
2329 #if 0
2330 #ifdef CONFIG_SMP
2331 if (current->flags & PF_USEDFPU)
2332 regs->psr &= ~PSR_EF;
2333 #else
2334 if (current == last_task_used_math) {
2335 last_task_used_math = 0;
2336 regs->psr &= ~PSR_EF;
2338 #endif
2339 current->used_math = 1;
2340 current->flags &= ~PF_USEDFPU;
2341 #endif
2342 #if 0
2343 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2344 return -EFAULT;
2345 #endif
2347 /* XXX: incorrect */
2348 err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],
2349 (sizeof(abi_ulong) * 32));
2350 err |= __get_user(env->fsr, &fpu->si_fsr);
2351 #if 0
2352 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2353 if (current->thread.fpqdepth != 0)
2354 err |= __copy_from_user(&current->thread.fpqueue[0],
2355 &fpu->si_fpqueue[0],
2356 ((sizeof(unsigned long) +
2357 (sizeof(unsigned long *)))*16));
2358 #endif
2359 return err;
2363 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2364 target_siginfo_t *info,
2365 target_sigset_t *set, CPUSPARCState *env)
2367 fprintf(stderr, "setup_rt_frame: not implemented\n");
2370 long do_sigreturn(CPUSPARCState *env)
2372 abi_ulong sf_addr;
2373 struct target_signal_frame *sf;
2374 uint32_t up_psr, pc, npc;
2375 target_sigset_t set;
2376 sigset_t host_set;
2377 int err, i;
2379 sf_addr = env->regwptr[UREG_FP];
2380 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2381 goto segv_and_exit;
2382 #if 0
2383 fprintf(stderr, "sigreturn\n");
2384 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2385 #endif
2386 //cpu_dump_state(env, stderr, fprintf, 0);
2388 /* 1. Make sure we are not getting garbage from the user */
2390 if (sf_addr & 3)
2391 goto segv_and_exit;
2393 err = __get_user(pc, &sf->info.si_regs.pc);
2394 err |= __get_user(npc, &sf->info.si_regs.npc);
2396 if ((pc | npc) & 3)
2397 goto segv_and_exit;
2399 /* 2. Restore the state */
2400 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2402 /* User can only change condition codes and FPU enabling in %psr. */
2403 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2404 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2406 env->pc = pc;
2407 env->npc = npc;
2408 err |= __get_user(env->y, &sf->info.si_regs.y);
2409 for (i=0; i < 8; i++) {
2410 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2412 for (i=0; i < 8; i++) {
2413 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2416 /* FIXME: implement FPU save/restore:
2417 * __get_user(fpu_save, &sf->fpu_save);
2418 * if (fpu_save)
2419 * err |= restore_fpu_state(env, fpu_save);
2422 /* This is pretty much atomic, no amount locking would prevent
2423 * the races which exist anyways.
2425 err |= __get_user(set.sig[0], &sf->info.si_mask);
2426 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2427 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2430 target_to_host_sigset_internal(&host_set, &set);
2431 sigprocmask(SIG_SETMASK, &host_set, NULL);
2433 if (err)
2434 goto segv_and_exit;
2435 unlock_user_struct(sf, sf_addr, 0);
2436 return env->regwptr[0];
2438 segv_and_exit:
2439 unlock_user_struct(sf, sf_addr, 0);
2440 force_sig(TARGET_SIGSEGV);
2443 long do_rt_sigreturn(CPUSPARCState *env)
2445 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2446 return -TARGET_ENOSYS;
2449 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2450 #define MC_TSTATE 0
2451 #define MC_PC 1
2452 #define MC_NPC 2
2453 #define MC_Y 3
2454 #define MC_G1 4
2455 #define MC_G2 5
2456 #define MC_G3 6
2457 #define MC_G4 7
2458 #define MC_G5 8
2459 #define MC_G6 9
2460 #define MC_G7 10
2461 #define MC_O0 11
2462 #define MC_O1 12
2463 #define MC_O2 13
2464 #define MC_O3 14
2465 #define MC_O4 15
2466 #define MC_O5 16
2467 #define MC_O6 17
2468 #define MC_O7 18
2469 #define MC_NGREG 19
2471 typedef abi_ulong target_mc_greg_t;
2472 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2474 struct target_mc_fq {
2475 abi_ulong *mcfq_addr;
2476 uint32_t mcfq_insn;
2479 struct target_mc_fpu {
2480 union {
2481 uint32_t sregs[32];
2482 uint64_t dregs[32];
2483 //uint128_t qregs[16];
2484 } mcfpu_fregs;
2485 abi_ulong mcfpu_fsr;
2486 abi_ulong mcfpu_fprs;
2487 abi_ulong mcfpu_gsr;
2488 struct target_mc_fq *mcfpu_fq;
2489 unsigned char mcfpu_qcnt;
2490 unsigned char mcfpu_qentsz;
2491 unsigned char mcfpu_enab;
2493 typedef struct target_mc_fpu target_mc_fpu_t;
2495 typedef struct {
2496 target_mc_gregset_t mc_gregs;
2497 target_mc_greg_t mc_fp;
2498 target_mc_greg_t mc_i7;
2499 target_mc_fpu_t mc_fpregs;
2500 } target_mcontext_t;
2502 struct target_ucontext {
2503 struct target_ucontext *tuc_link;
2504 abi_ulong tuc_flags;
2505 target_sigset_t tuc_sigmask;
2506 target_mcontext_t tuc_mcontext;
2509 /* A V9 register window */
2510 struct target_reg_window {
2511 abi_ulong locals[8];
2512 abi_ulong ins[8];
2515 #define TARGET_STACK_BIAS 2047
2517 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2518 void sparc64_set_context(CPUSPARCState *env)
2520 abi_ulong ucp_addr;
2521 struct target_ucontext *ucp;
2522 target_mc_gregset_t *grp;
2523 abi_ulong pc, npc, tstate;
2524 abi_ulong fp, i7, w_addr;
2525 int err;
2526 unsigned int i;
2528 ucp_addr = env->regwptr[UREG_I0];
2529 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2530 goto do_sigsegv;
2531 grp = &ucp->tuc_mcontext.mc_gregs;
2532 err = __get_user(pc, &((*grp)[MC_PC]));
2533 err |= __get_user(npc, &((*grp)[MC_NPC]));
2534 if (err || ((pc | npc) & 3))
2535 goto do_sigsegv;
2536 if (env->regwptr[UREG_I1]) {
2537 target_sigset_t target_set;
2538 sigset_t set;
2540 if (TARGET_NSIG_WORDS == 1) {
2541 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2542 goto do_sigsegv;
2543 } else {
2544 abi_ulong *src, *dst;
2545 src = ucp->tuc_sigmask.sig;
2546 dst = target_set.sig;
2547 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2548 err |= __get_user(*dst, src);
2550 if (err)
2551 goto do_sigsegv;
2553 target_to_host_sigset_internal(&set, &target_set);
2554 sigprocmask(SIG_SETMASK, &set, NULL);
2556 env->pc = pc;
2557 env->npc = npc;
2558 err |= __get_user(env->y, &((*grp)[MC_Y]));
2559 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2560 env->asi = (tstate >> 24) & 0xff;
2561 cpu_put_ccr(env, tstate >> 32);
2562 cpu_put_cwp64(env, tstate & 0x1f);
2563 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2564 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2565 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2566 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2567 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2568 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2569 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2570 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2571 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2572 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2573 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2574 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2575 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2576 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2577 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2579 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2580 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2582 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2583 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2584 abi_ulong) != 0)
2585 goto do_sigsegv;
2586 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2587 abi_ulong) != 0)
2588 goto do_sigsegv;
2589 /* FIXME this does not match how the kernel handles the FPU in
2590 * its sparc64_set_context implementation. In particular the FPU
2591 * is only restored if fenab is non-zero in:
2592 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2594 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2596 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2597 for (i = 0; i < 64; i++, src++) {
2598 if (i & 1) {
2599 err |= __get_user(env->fpr[i/2].l.lower, src);
2600 } else {
2601 err |= __get_user(env->fpr[i/2].l.upper, src);
2605 err |= __get_user(env->fsr,
2606 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2607 err |= __get_user(env->gsr,
2608 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2609 if (err)
2610 goto do_sigsegv;
2611 unlock_user_struct(ucp, ucp_addr, 0);
2612 return;
2613 do_sigsegv:
2614 unlock_user_struct(ucp, ucp_addr, 0);
2615 force_sig(TARGET_SIGSEGV);
2618 void sparc64_get_context(CPUSPARCState *env)
2620 abi_ulong ucp_addr;
2621 struct target_ucontext *ucp;
2622 target_mc_gregset_t *grp;
2623 target_mcontext_t *mcp;
2624 abi_ulong fp, i7, w_addr;
2625 int err;
2626 unsigned int i;
2627 target_sigset_t target_set;
2628 sigset_t set;
2630 ucp_addr = env->regwptr[UREG_I0];
2631 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2632 goto do_sigsegv;
2634 mcp = &ucp->tuc_mcontext;
2635 grp = &mcp->mc_gregs;
2637 /* Skip over the trap instruction, first. */
2638 env->pc = env->npc;
2639 env->npc += 4;
2641 err = 0;
2643 sigprocmask(0, NULL, &set);
2644 host_to_target_sigset_internal(&target_set, &set);
2645 if (TARGET_NSIG_WORDS == 1) {
2646 err |= __put_user(target_set.sig[0],
2647 (abi_ulong *)&ucp->tuc_sigmask);
2648 } else {
2649 abi_ulong *src, *dst;
2650 src = target_set.sig;
2651 dst = ucp->tuc_sigmask.sig;
2652 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2653 err |= __put_user(*src, dst);
2655 if (err)
2656 goto do_sigsegv;
2659 /* XXX: tstate must be saved properly */
2660 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2661 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2662 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2663 err |= __put_user(env->y, &((*grp)[MC_Y]));
2664 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2665 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2666 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2667 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2668 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2669 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2670 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2671 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2672 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2673 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2674 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2675 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2676 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2677 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2678 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2680 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2681 fp = i7 = 0;
2682 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2683 abi_ulong) != 0)
2684 goto do_sigsegv;
2685 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2686 abi_ulong) != 0)
2687 goto do_sigsegv;
2688 err |= __put_user(fp, &(mcp->mc_fp));
2689 err |= __put_user(i7, &(mcp->mc_i7));
2692 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2693 for (i = 0; i < 64; i++, dst++) {
2694 if (i & 1) {
2695 err |= __put_user(env->fpr[i/2].l.lower, dst);
2696 } else {
2697 err |= __put_user(env->fpr[i/2].l.upper, dst);
2701 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2702 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2703 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2705 if (err)
2706 goto do_sigsegv;
2707 unlock_user_struct(ucp, ucp_addr, 1);
2708 return;
2709 do_sigsegv:
2710 unlock_user_struct(ucp, ucp_addr, 1);
2711 force_sig(TARGET_SIGSEGV);
2713 #endif
2714 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2716 # if defined(TARGET_ABI_MIPSO32)
2717 struct target_sigcontext {
2718 uint32_t sc_regmask; /* Unused */
2719 uint32_t sc_status;
2720 uint64_t sc_pc;
2721 uint64_t sc_regs[32];
2722 uint64_t sc_fpregs[32];
2723 uint32_t sc_ownedfp; /* Unused */
2724 uint32_t sc_fpc_csr;
2725 uint32_t sc_fpc_eir; /* Unused */
2726 uint32_t sc_used_math;
2727 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2728 uint32_t pad0;
2729 uint64_t sc_mdhi;
2730 uint64_t sc_mdlo;
2731 target_ulong sc_hi1; /* Was sc_cause */
2732 target_ulong sc_lo1; /* Was sc_badvaddr */
2733 target_ulong sc_hi2; /* Was sc_sigset[4] */
2734 target_ulong sc_lo2;
2735 target_ulong sc_hi3;
2736 target_ulong sc_lo3;
2738 # else /* N32 || N64 */
2739 struct target_sigcontext {
2740 uint64_t sc_regs[32];
2741 uint64_t sc_fpregs[32];
2742 uint64_t sc_mdhi;
2743 uint64_t sc_hi1;
2744 uint64_t sc_hi2;
2745 uint64_t sc_hi3;
2746 uint64_t sc_mdlo;
2747 uint64_t sc_lo1;
2748 uint64_t sc_lo2;
2749 uint64_t sc_lo3;
2750 uint64_t sc_pc;
2751 uint32_t sc_fpc_csr;
2752 uint32_t sc_used_math;
2753 uint32_t sc_dsp;
2754 uint32_t sc_reserved;
2756 # endif /* O32 */
2758 struct sigframe {
2759 uint32_t sf_ass[4]; /* argument save space for o32 */
2760 uint32_t sf_code[2]; /* signal trampoline */
2761 struct target_sigcontext sf_sc;
2762 target_sigset_t sf_mask;
2765 struct target_ucontext {
2766 target_ulong tuc_flags;
2767 target_ulong tuc_link;
2768 target_stack_t tuc_stack;
2769 target_ulong pad0;
2770 struct target_sigcontext tuc_mcontext;
2771 target_sigset_t tuc_sigmask;
2774 struct target_rt_sigframe {
2775 uint32_t rs_ass[4]; /* argument save space for o32 */
2776 uint32_t rs_code[2]; /* signal trampoline */
2777 struct target_siginfo rs_info;
2778 struct target_ucontext rs_uc;
2781 /* Install trampoline to jump back from signal handler */
2782 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2784 int err = 0;
2787 * Set up the return code ...
2789 * li v0, __NR__foo_sigreturn
2790 * syscall
2793 err |= __put_user(0x24020000 + syscall, tramp + 0);
2794 err |= __put_user(0x0000000c , tramp + 1);
2795 return err;
2798 static inline int
2799 setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2801 int err = 0;
2802 int i;
2804 err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
2805 regs->hflags &= ~MIPS_HFLAG_BMASK;
2807 __put_user(0, &sc->sc_regs[0]);
2808 for (i = 1; i < 32; ++i) {
2809 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2812 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2813 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2815 /* Rather than checking for dsp existence, always copy. The storage
2816 would just be garbage otherwise. */
2817 err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
2818 err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
2819 err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
2820 err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
2821 err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
2822 err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
2824 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2825 err |= __put_user(dsp, &sc->sc_dsp);
2828 err |= __put_user(1, &sc->sc_used_math);
2830 for (i = 0; i < 32; ++i) {
2831 err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2834 return err;
2837 static inline int
2838 restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2840 int err = 0;
2841 int i;
2843 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2845 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2846 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2848 for (i = 1; i < 32; ++i) {
2849 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2852 err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
2853 err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
2854 err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
2855 err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
2856 err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
2857 err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
2859 uint32_t dsp;
2860 err |= __get_user(dsp, &sc->sc_dsp);
2861 cpu_wrdsp(dsp, 0x3ff, regs);
2864 for (i = 0; i < 32; ++i) {
2865 err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2868 return err;
2872 * Determine which stack to use..
2874 static inline abi_ulong
2875 get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2877 unsigned long sp;
2879 /* Default to using normal stack */
2880 sp = regs->active_tc.gpr[29];
2883 * FPU emulator may have its own trampoline active just
2884 * above the user stack, 16-bytes before the next lowest
2885 * 16 byte boundary. Try to avoid trashing it.
2887 sp -= 32;
2889 /* This is the X/Open sanctioned signal stack switching. */
2890 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2891 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2894 return (sp - frame_size) & ~7;
2897 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2899 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2900 env->hflags &= ~MIPS_HFLAG_M16;
2901 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2902 env->active_tc.PC &= ~(target_ulong) 1;
2906 # if defined(TARGET_ABI_MIPSO32)
2907 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2908 static void setup_frame(int sig, struct target_sigaction * ka,
2909 target_sigset_t *set, CPUMIPSState *regs)
2911 struct sigframe *frame;
2912 abi_ulong frame_addr;
2913 int i;
2915 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2916 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2917 goto give_sigsegv;
2919 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2921 if(setup_sigcontext(regs, &frame->sf_sc))
2922 goto give_sigsegv;
2924 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2925 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2926 goto give_sigsegv;
2930 * Arguments to signal handler:
2932 * a0 = signal number
2933 * a1 = 0 (should be cause)
2934 * a2 = pointer to struct sigcontext
2936 * $25 and PC point to the signal handler, $29 points to the
2937 * struct sigframe.
2939 regs->active_tc.gpr[ 4] = sig;
2940 regs->active_tc.gpr[ 5] = 0;
2941 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2942 regs->active_tc.gpr[29] = frame_addr;
2943 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2944 /* The original kernel code sets CP0_EPC to the handler
2945 * since it returns to userland using eret
2946 * we cannot do this here, and we must set PC directly */
2947 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2948 mips_set_hflags_isa_mode_from_pc(regs);
2949 unlock_user_struct(frame, frame_addr, 1);
2950 return;
2952 give_sigsegv:
2953 unlock_user_struct(frame, frame_addr, 1);
2954 force_sig(TARGET_SIGSEGV/*, current*/);
2957 long do_sigreturn(CPUMIPSState *regs)
2959 struct sigframe *frame;
2960 abi_ulong frame_addr;
2961 sigset_t blocked;
2962 target_sigset_t target_set;
2963 int i;
2965 #if defined(DEBUG_SIGNAL)
2966 fprintf(stderr, "do_sigreturn\n");
2967 #endif
2968 frame_addr = regs->active_tc.gpr[29];
2969 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2970 goto badframe;
2972 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2973 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2974 goto badframe;
2977 target_to_host_sigset_internal(&blocked, &target_set);
2978 sigprocmask(SIG_SETMASK, &blocked, NULL);
2980 if (restore_sigcontext(regs, &frame->sf_sc))
2981 goto badframe;
2983 #if 0
2985 * Don't let your children do this ...
2987 __asm__ __volatile__(
2988 "move\t$29, %0\n\t"
2989 "j\tsyscall_exit"
2990 :/* no outputs */
2991 :"r" (&regs));
2992 /* Unreached */
2993 #endif
2995 regs->active_tc.PC = regs->CP0_EPC;
2996 mips_set_hflags_isa_mode_from_pc(regs);
2997 /* I am not sure this is right, but it seems to work
2998 * maybe a problem with nested signals ? */
2999 regs->CP0_EPC = 0;
3000 return -TARGET_QEMU_ESIGRETURN;
3002 badframe:
3003 force_sig(TARGET_SIGSEGV/*, current*/);
3004 return 0;
3006 # endif /* O32 */
3008 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3009 target_siginfo_t *info,
3010 target_sigset_t *set, CPUMIPSState *env)
3012 struct target_rt_sigframe *frame;
3013 abi_ulong frame_addr;
3014 int i;
3016 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3017 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3018 goto give_sigsegv;
3020 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3022 copy_siginfo_to_user(&frame->rs_info, info);
3024 __put_user(0, &frame->rs_uc.tuc_flags);
3025 __put_user(0, &frame->rs_uc.tuc_link);
3026 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
3027 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
3028 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3029 &frame->rs_uc.tuc_stack.ss_flags);
3031 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3033 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3034 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3038 * Arguments to signal handler:
3040 * a0 = signal number
3041 * a1 = pointer to siginfo_t
3042 * a2 = pointer to struct ucontext
3044 * $25 and PC point to the signal handler, $29 points to the
3045 * struct sigframe.
3047 env->active_tc.gpr[ 4] = sig;
3048 env->active_tc.gpr[ 5] = frame_addr
3049 + offsetof(struct target_rt_sigframe, rs_info);
3050 env->active_tc.gpr[ 6] = frame_addr
3051 + offsetof(struct target_rt_sigframe, rs_uc);
3052 env->active_tc.gpr[29] = frame_addr;
3053 env->active_tc.gpr[31] = frame_addr
3054 + offsetof(struct target_rt_sigframe, rs_code);
3055 /* The original kernel code sets CP0_EPC to the handler
3056 * since it returns to userland using eret
3057 * we cannot do this here, and we must set PC directly */
3058 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3059 mips_set_hflags_isa_mode_from_pc(env);
3060 unlock_user_struct(frame, frame_addr, 1);
3061 return;
3063 give_sigsegv:
3064 unlock_user_struct(frame, frame_addr, 1);
3065 force_sig(TARGET_SIGSEGV/*, current*/);
3068 long do_rt_sigreturn(CPUMIPSState *env)
3070 struct target_rt_sigframe *frame;
3071 abi_ulong frame_addr;
3072 sigset_t blocked;
3074 #if defined(DEBUG_SIGNAL)
3075 fprintf(stderr, "do_rt_sigreturn\n");
3076 #endif
3077 frame_addr = env->active_tc.gpr[29];
3078 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3079 goto badframe;
3081 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3082 sigprocmask(SIG_SETMASK, &blocked, NULL);
3084 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
3085 goto badframe;
3087 if (do_sigaltstack(frame_addr +
3088 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3089 0, get_sp_from_cpustate(env)) == -EFAULT)
3090 goto badframe;
3092 env->active_tc.PC = env->CP0_EPC;
3093 mips_set_hflags_isa_mode_from_pc(env);
3094 /* I am not sure this is right, but it seems to work
3095 * maybe a problem with nested signals ? */
3096 env->CP0_EPC = 0;
3097 return -TARGET_QEMU_ESIGRETURN;
3099 badframe:
3100 force_sig(TARGET_SIGSEGV/*, current*/);
3101 return 0;
3104 #elif defined(TARGET_SH4)
3107 * code and data structures from linux kernel:
3108 * include/asm-sh/sigcontext.h
3109 * arch/sh/kernel/signal.c
3112 struct target_sigcontext {
3113 target_ulong oldmask;
3115 /* CPU registers */
3116 target_ulong sc_gregs[16];
3117 target_ulong sc_pc;
3118 target_ulong sc_pr;
3119 target_ulong sc_sr;
3120 target_ulong sc_gbr;
3121 target_ulong sc_mach;
3122 target_ulong sc_macl;
3124 /* FPU registers */
3125 target_ulong sc_fpregs[16];
3126 target_ulong sc_xfpregs[16];
3127 unsigned int sc_fpscr;
3128 unsigned int sc_fpul;
3129 unsigned int sc_ownedfp;
3132 struct target_sigframe
3134 struct target_sigcontext sc;
3135 target_ulong extramask[TARGET_NSIG_WORDS-1];
3136 uint16_t retcode[3];
3140 struct target_ucontext {
3141 target_ulong tuc_flags;
3142 struct target_ucontext *tuc_link;
3143 target_stack_t tuc_stack;
3144 struct target_sigcontext tuc_mcontext;
3145 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3148 struct target_rt_sigframe
3150 struct target_siginfo info;
3151 struct target_ucontext uc;
3152 uint16_t retcode[3];
3156 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3157 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3159 static abi_ulong get_sigframe(struct target_sigaction *ka,
3160 unsigned long sp, size_t frame_size)
3162 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
3163 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3166 return (sp - frame_size) & -8ul;
3169 static int setup_sigcontext(struct target_sigcontext *sc,
3170 CPUSH4State *regs, unsigned long mask)
3172 int err = 0;
3173 int i;
3175 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
3176 COPY(gregs[0]); COPY(gregs[1]);
3177 COPY(gregs[2]); COPY(gregs[3]);
3178 COPY(gregs[4]); COPY(gregs[5]);
3179 COPY(gregs[6]); COPY(gregs[7]);
3180 COPY(gregs[8]); COPY(gregs[9]);
3181 COPY(gregs[10]); COPY(gregs[11]);
3182 COPY(gregs[12]); COPY(gregs[13]);
3183 COPY(gregs[14]); COPY(gregs[15]);
3184 COPY(gbr); COPY(mach);
3185 COPY(macl); COPY(pr);
3186 COPY(sr); COPY(pc);
3187 #undef COPY
3189 for (i=0; i<16; i++) {
3190 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3192 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
3193 err |= __put_user(regs->fpul, &sc->sc_fpul);
3195 /* non-iBCS2 extensions.. */
3196 err |= __put_user(mask, &sc->oldmask);
3198 return err;
3201 static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3202 target_ulong *r0_p)
3204 unsigned int err = 0;
3205 int i;
3207 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3208 COPY(gregs[1]);
3209 COPY(gregs[2]); COPY(gregs[3]);
3210 COPY(gregs[4]); COPY(gregs[5]);
3211 COPY(gregs[6]); COPY(gregs[7]);
3212 COPY(gregs[8]); COPY(gregs[9]);
3213 COPY(gregs[10]); COPY(gregs[11]);
3214 COPY(gregs[12]); COPY(gregs[13]);
3215 COPY(gregs[14]); COPY(gregs[15]);
3216 COPY(gbr); COPY(mach);
3217 COPY(macl); COPY(pr);
3218 COPY(sr); COPY(pc);
3219 #undef COPY
3221 for (i=0; i<16; i++) {
3222 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3224 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3225 err |= __get_user(regs->fpul, &sc->sc_fpul);
3227 regs->tra = -1; /* disable syscall checks */
3228 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3229 return err;
3232 static void setup_frame(int sig, struct target_sigaction *ka,
3233 target_sigset_t *set, CPUSH4State *regs)
3235 struct target_sigframe *frame;
3236 abi_ulong frame_addr;
3237 int i;
3238 int err = 0;
3239 int signal;
3241 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3242 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3243 goto give_sigsegv;
3245 signal = current_exec_domain_sig(sig);
3247 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3249 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3250 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3253 /* Set up to return from userspace. If provided, use a stub
3254 already in userspace. */
3255 if (ka->sa_flags & TARGET_SA_RESTORER) {
3256 regs->pr = (unsigned long) ka->sa_restorer;
3257 } else {
3258 /* Generate return code (system call to sigreturn) */
3259 err |= __put_user(MOVW(2), &frame->retcode[0]);
3260 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3261 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3262 regs->pr = (unsigned long) frame->retcode;
3265 if (err)
3266 goto give_sigsegv;
3268 /* Set up registers for signal handler */
3269 regs->gregs[15] = frame_addr;
3270 regs->gregs[4] = signal; /* Arg for signal handler */
3271 regs->gregs[5] = 0;
3272 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3273 regs->pc = (unsigned long) ka->_sa_handler;
3275 unlock_user_struct(frame, frame_addr, 1);
3276 return;
3278 give_sigsegv:
3279 unlock_user_struct(frame, frame_addr, 1);
3280 force_sig(TARGET_SIGSEGV);
3283 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3284 target_siginfo_t *info,
3285 target_sigset_t *set, CPUSH4State *regs)
3287 struct target_rt_sigframe *frame;
3288 abi_ulong frame_addr;
3289 int i;
3290 int err = 0;
3291 int signal;
3293 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3294 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3295 goto give_sigsegv;
3297 signal = current_exec_domain_sig(sig);
3299 err |= copy_siginfo_to_user(&frame->info, info);
3301 /* Create the ucontext. */
3302 err |= __put_user(0, &frame->uc.tuc_flags);
3303 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3304 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3305 &frame->uc.tuc_stack.ss_sp);
3306 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3307 &frame->uc.tuc_stack.ss_flags);
3308 err |= __put_user(target_sigaltstack_used.ss_size,
3309 &frame->uc.tuc_stack.ss_size);
3310 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3311 regs, set->sig[0]);
3312 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3313 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3316 /* Set up to return from userspace. If provided, use a stub
3317 already in userspace. */
3318 if (ka->sa_flags & TARGET_SA_RESTORER) {
3319 regs->pr = (unsigned long) ka->sa_restorer;
3320 } else {
3321 /* Generate return code (system call to sigreturn) */
3322 err |= __put_user(MOVW(2), &frame->retcode[0]);
3323 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3324 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3325 regs->pr = (unsigned long) frame->retcode;
3328 if (err)
3329 goto give_sigsegv;
3331 /* Set up registers for signal handler */
3332 regs->gregs[15] = frame_addr;
3333 regs->gregs[4] = signal; /* Arg for signal handler */
3334 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3335 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3336 regs->pc = (unsigned long) ka->_sa_handler;
3338 unlock_user_struct(frame, frame_addr, 1);
3339 return;
3341 give_sigsegv:
3342 unlock_user_struct(frame, frame_addr, 1);
3343 force_sig(TARGET_SIGSEGV);
3346 long do_sigreturn(CPUSH4State *regs)
3348 struct target_sigframe *frame;
3349 abi_ulong frame_addr;
3350 sigset_t blocked;
3351 target_sigset_t target_set;
3352 target_ulong r0;
3353 int i;
3354 int err = 0;
3356 #if defined(DEBUG_SIGNAL)
3357 fprintf(stderr, "do_sigreturn\n");
3358 #endif
3359 frame_addr = regs->gregs[15];
3360 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3361 goto badframe;
3363 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3364 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3365 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3368 if (err)
3369 goto badframe;
3371 target_to_host_sigset_internal(&blocked, &target_set);
3372 sigprocmask(SIG_SETMASK, &blocked, NULL);
3374 if (restore_sigcontext(regs, &frame->sc, &r0))
3375 goto badframe;
3377 unlock_user_struct(frame, frame_addr, 0);
3378 return r0;
3380 badframe:
3381 unlock_user_struct(frame, frame_addr, 0);
3382 force_sig(TARGET_SIGSEGV);
3383 return 0;
3386 long do_rt_sigreturn(CPUSH4State *regs)
3388 struct target_rt_sigframe *frame;
3389 abi_ulong frame_addr;
3390 sigset_t blocked;
3391 target_ulong r0;
3393 #if defined(DEBUG_SIGNAL)
3394 fprintf(stderr, "do_rt_sigreturn\n");
3395 #endif
3396 frame_addr = regs->gregs[15];
3397 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3398 goto badframe;
3400 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3401 sigprocmask(SIG_SETMASK, &blocked, NULL);
3403 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3404 goto badframe;
3406 if (do_sigaltstack(frame_addr +
3407 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3408 0, get_sp_from_cpustate(regs)) == -EFAULT)
3409 goto badframe;
3411 unlock_user_struct(frame, frame_addr, 0);
3412 return r0;
3414 badframe:
3415 unlock_user_struct(frame, frame_addr, 0);
3416 force_sig(TARGET_SIGSEGV);
3417 return 0;
3419 #elif defined(TARGET_MICROBLAZE)
3421 struct target_sigcontext {
3422 struct target_pt_regs regs; /* needs to be first */
3423 uint32_t oldmask;
3426 struct target_stack_t {
3427 abi_ulong ss_sp;
3428 int ss_flags;
3429 unsigned int ss_size;
3432 struct target_ucontext {
3433 abi_ulong tuc_flags;
3434 abi_ulong tuc_link;
3435 struct target_stack_t tuc_stack;
3436 struct target_sigcontext tuc_mcontext;
3437 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3440 /* Signal frames. */
3441 struct target_signal_frame {
3442 struct target_ucontext uc;
3443 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3444 uint32_t tramp[2];
3447 struct rt_signal_frame {
3448 siginfo_t info;
3449 struct ucontext uc;
3450 uint32_t tramp[2];
3453 static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3455 __put_user(env->regs[0], &sc->regs.r0);
3456 __put_user(env->regs[1], &sc->regs.r1);
3457 __put_user(env->regs[2], &sc->regs.r2);
3458 __put_user(env->regs[3], &sc->regs.r3);
3459 __put_user(env->regs[4], &sc->regs.r4);
3460 __put_user(env->regs[5], &sc->regs.r5);
3461 __put_user(env->regs[6], &sc->regs.r6);
3462 __put_user(env->regs[7], &sc->regs.r7);
3463 __put_user(env->regs[8], &sc->regs.r8);
3464 __put_user(env->regs[9], &sc->regs.r9);
3465 __put_user(env->regs[10], &sc->regs.r10);
3466 __put_user(env->regs[11], &sc->regs.r11);
3467 __put_user(env->regs[12], &sc->regs.r12);
3468 __put_user(env->regs[13], &sc->regs.r13);
3469 __put_user(env->regs[14], &sc->regs.r14);
3470 __put_user(env->regs[15], &sc->regs.r15);
3471 __put_user(env->regs[16], &sc->regs.r16);
3472 __put_user(env->regs[17], &sc->regs.r17);
3473 __put_user(env->regs[18], &sc->regs.r18);
3474 __put_user(env->regs[19], &sc->regs.r19);
3475 __put_user(env->regs[20], &sc->regs.r20);
3476 __put_user(env->regs[21], &sc->regs.r21);
3477 __put_user(env->regs[22], &sc->regs.r22);
3478 __put_user(env->regs[23], &sc->regs.r23);
3479 __put_user(env->regs[24], &sc->regs.r24);
3480 __put_user(env->regs[25], &sc->regs.r25);
3481 __put_user(env->regs[26], &sc->regs.r26);
3482 __put_user(env->regs[27], &sc->regs.r27);
3483 __put_user(env->regs[28], &sc->regs.r28);
3484 __put_user(env->regs[29], &sc->regs.r29);
3485 __put_user(env->regs[30], &sc->regs.r30);
3486 __put_user(env->regs[31], &sc->regs.r31);
3487 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3490 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3492 __get_user(env->regs[0], &sc->regs.r0);
3493 __get_user(env->regs[1], &sc->regs.r1);
3494 __get_user(env->regs[2], &sc->regs.r2);
3495 __get_user(env->regs[3], &sc->regs.r3);
3496 __get_user(env->regs[4], &sc->regs.r4);
3497 __get_user(env->regs[5], &sc->regs.r5);
3498 __get_user(env->regs[6], &sc->regs.r6);
3499 __get_user(env->regs[7], &sc->regs.r7);
3500 __get_user(env->regs[8], &sc->regs.r8);
3501 __get_user(env->regs[9], &sc->regs.r9);
3502 __get_user(env->regs[10], &sc->regs.r10);
3503 __get_user(env->regs[11], &sc->regs.r11);
3504 __get_user(env->regs[12], &sc->regs.r12);
3505 __get_user(env->regs[13], &sc->regs.r13);
3506 __get_user(env->regs[14], &sc->regs.r14);
3507 __get_user(env->regs[15], &sc->regs.r15);
3508 __get_user(env->regs[16], &sc->regs.r16);
3509 __get_user(env->regs[17], &sc->regs.r17);
3510 __get_user(env->regs[18], &sc->regs.r18);
3511 __get_user(env->regs[19], &sc->regs.r19);
3512 __get_user(env->regs[20], &sc->regs.r20);
3513 __get_user(env->regs[21], &sc->regs.r21);
3514 __get_user(env->regs[22], &sc->regs.r22);
3515 __get_user(env->regs[23], &sc->regs.r23);
3516 __get_user(env->regs[24], &sc->regs.r24);
3517 __get_user(env->regs[25], &sc->regs.r25);
3518 __get_user(env->regs[26], &sc->regs.r26);
3519 __get_user(env->regs[27], &sc->regs.r27);
3520 __get_user(env->regs[28], &sc->regs.r28);
3521 __get_user(env->regs[29], &sc->regs.r29);
3522 __get_user(env->regs[30], &sc->regs.r30);
3523 __get_user(env->regs[31], &sc->regs.r31);
3524 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3527 static abi_ulong get_sigframe(struct target_sigaction *ka,
3528 CPUMBState *env, int frame_size)
3530 abi_ulong sp = env->regs[1];
3532 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3533 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3535 return ((sp - frame_size) & -8UL);
3538 static void setup_frame(int sig, struct target_sigaction *ka,
3539 target_sigset_t *set, CPUMBState *env)
3541 struct target_signal_frame *frame;
3542 abi_ulong frame_addr;
3543 int err = 0;
3544 int i;
3546 frame_addr = get_sigframe(ka, env, sizeof *frame);
3547 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3548 goto badframe;
3550 /* Save the mask. */
3551 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3552 if (err)
3553 goto badframe;
3555 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3556 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3557 goto badframe;
3560 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3562 /* Set up to return from userspace. If provided, use a stub
3563 already in userspace. */
3564 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3565 if (ka->sa_flags & TARGET_SA_RESTORER) {
3566 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3567 } else {
3568 uint32_t t;
3569 /* Note, these encodings are _big endian_! */
3570 /* addi r12, r0, __NR_sigreturn */
3571 t = 0x31800000UL | TARGET_NR_sigreturn;
3572 err |= __put_user(t, frame->tramp + 0);
3573 /* brki r14, 0x8 */
3574 t = 0xb9cc0008UL;
3575 err |= __put_user(t, frame->tramp + 1);
3577 /* Return from sighandler will jump to the tramp.
3578 Negative 8 offset because return is rtsd r15, 8 */
3579 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3582 if (err)
3583 goto badframe;
3585 /* Set up registers for signal handler */
3586 env->regs[1] = frame_addr;
3587 /* Signal handler args: */
3588 env->regs[5] = sig; /* Arg 0: signum */
3589 env->regs[6] = 0;
3590 /* arg 1: sigcontext */
3591 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3593 /* Offset of 4 to handle microblaze rtid r14, 0 */
3594 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3596 unlock_user_struct(frame, frame_addr, 1);
3597 return;
3598 badframe:
3599 unlock_user_struct(frame, frame_addr, 1);
3600 force_sig(TARGET_SIGSEGV);
3603 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3604 target_siginfo_t *info,
3605 target_sigset_t *set, CPUMBState *env)
3607 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3610 long do_sigreturn(CPUMBState *env)
3612 struct target_signal_frame *frame;
3613 abi_ulong frame_addr;
3614 target_sigset_t target_set;
3615 sigset_t set;
3616 int i;
3618 frame_addr = env->regs[R_SP];
3619 /* Make sure the guest isn't playing games. */
3620 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3621 goto badframe;
3623 /* Restore blocked signals */
3624 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3625 goto badframe;
3626 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3627 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3628 goto badframe;
3630 target_to_host_sigset_internal(&set, &target_set);
3631 sigprocmask(SIG_SETMASK, &set, NULL);
3633 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3634 /* We got here through a sigreturn syscall, our path back is via an
3635 rtb insn so setup r14 for that. */
3636 env->regs[14] = env->sregs[SR_PC];
3638 unlock_user_struct(frame, frame_addr, 0);
3639 return env->regs[10];
3640 badframe:
3641 unlock_user_struct(frame, frame_addr, 0);
3642 force_sig(TARGET_SIGSEGV);
3645 long do_rt_sigreturn(CPUMBState *env)
3647 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3648 return -TARGET_ENOSYS;
3651 #elif defined(TARGET_CRIS)
3653 struct target_sigcontext {
3654 struct target_pt_regs regs; /* needs to be first */
3655 uint32_t oldmask;
3656 uint32_t usp; /* usp before stacking this gunk on it */
3659 /* Signal frames. */
3660 struct target_signal_frame {
3661 struct target_sigcontext sc;
3662 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3663 uint16_t retcode[4]; /* Trampoline code. */
3666 struct rt_signal_frame {
3667 siginfo_t *pinfo;
3668 void *puc;
3669 siginfo_t info;
3670 struct ucontext uc;
3671 uint16_t retcode[4]; /* Trampoline code. */
3674 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3676 __put_user(env->regs[0], &sc->regs.r0);
3677 __put_user(env->regs[1], &sc->regs.r1);
3678 __put_user(env->regs[2], &sc->regs.r2);
3679 __put_user(env->regs[3], &sc->regs.r3);
3680 __put_user(env->regs[4], &sc->regs.r4);
3681 __put_user(env->regs[5], &sc->regs.r5);
3682 __put_user(env->regs[6], &sc->regs.r6);
3683 __put_user(env->regs[7], &sc->regs.r7);
3684 __put_user(env->regs[8], &sc->regs.r8);
3685 __put_user(env->regs[9], &sc->regs.r9);
3686 __put_user(env->regs[10], &sc->regs.r10);
3687 __put_user(env->regs[11], &sc->regs.r11);
3688 __put_user(env->regs[12], &sc->regs.r12);
3689 __put_user(env->regs[13], &sc->regs.r13);
3690 __put_user(env->regs[14], &sc->usp);
3691 __put_user(env->regs[15], &sc->regs.acr);
3692 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3693 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3694 __put_user(env->pc, &sc->regs.erp);
3697 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3699 __get_user(env->regs[0], &sc->regs.r0);
3700 __get_user(env->regs[1], &sc->regs.r1);
3701 __get_user(env->regs[2], &sc->regs.r2);
3702 __get_user(env->regs[3], &sc->regs.r3);
3703 __get_user(env->regs[4], &sc->regs.r4);
3704 __get_user(env->regs[5], &sc->regs.r5);
3705 __get_user(env->regs[6], &sc->regs.r6);
3706 __get_user(env->regs[7], &sc->regs.r7);
3707 __get_user(env->regs[8], &sc->regs.r8);
3708 __get_user(env->regs[9], &sc->regs.r9);
3709 __get_user(env->regs[10], &sc->regs.r10);
3710 __get_user(env->regs[11], &sc->regs.r11);
3711 __get_user(env->regs[12], &sc->regs.r12);
3712 __get_user(env->regs[13], &sc->regs.r13);
3713 __get_user(env->regs[14], &sc->usp);
3714 __get_user(env->regs[15], &sc->regs.acr);
3715 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3716 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3717 __get_user(env->pc, &sc->regs.erp);
3720 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3722 abi_ulong sp;
3723 /* Align the stack downwards to 4. */
3724 sp = (env->regs[R_SP] & ~3);
3725 return sp - framesize;
3728 static void setup_frame(int sig, struct target_sigaction *ka,
3729 target_sigset_t *set, CPUCRISState *env)
3731 struct target_signal_frame *frame;
3732 abi_ulong frame_addr;
3733 int err = 0;
3734 int i;
3736 frame_addr = get_sigframe(env, sizeof *frame);
3737 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3738 goto badframe;
3741 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3742 * use this trampoline anymore but it sets it up for GDB.
3743 * In QEMU, using the trampoline simplifies things a bit so we use it.
3745 * This is movu.w __NR_sigreturn, r9; break 13;
3747 err |= __put_user(0x9c5f, frame->retcode+0);
3748 err |= __put_user(TARGET_NR_sigreturn,
3749 frame->retcode + 1);
3750 err |= __put_user(0xe93d, frame->retcode + 2);
3752 /* Save the mask. */
3753 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3754 if (err)
3755 goto badframe;
3757 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3758 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3759 goto badframe;
3762 setup_sigcontext(&frame->sc, env);
3764 /* Move the stack and setup the arguments for the handler. */
3765 env->regs[R_SP] = frame_addr;
3766 env->regs[10] = sig;
3767 env->pc = (unsigned long) ka->_sa_handler;
3768 /* Link SRP so the guest returns through the trampoline. */
3769 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3771 unlock_user_struct(frame, frame_addr, 1);
3772 return;
3773 badframe:
3774 unlock_user_struct(frame, frame_addr, 1);
3775 force_sig(TARGET_SIGSEGV);
3778 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3779 target_siginfo_t *info,
3780 target_sigset_t *set, CPUCRISState *env)
3782 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3785 long do_sigreturn(CPUCRISState *env)
3787 struct target_signal_frame *frame;
3788 abi_ulong frame_addr;
3789 target_sigset_t target_set;
3790 sigset_t set;
3791 int i;
3793 frame_addr = env->regs[R_SP];
3794 /* Make sure the guest isn't playing games. */
3795 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3796 goto badframe;
3798 /* Restore blocked signals */
3799 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3800 goto badframe;
3801 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3802 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3803 goto badframe;
3805 target_to_host_sigset_internal(&set, &target_set);
3806 sigprocmask(SIG_SETMASK, &set, NULL);
3808 restore_sigcontext(&frame->sc, env);
3809 unlock_user_struct(frame, frame_addr, 0);
3810 return env->regs[10];
3811 badframe:
3812 unlock_user_struct(frame, frame_addr, 0);
3813 force_sig(TARGET_SIGSEGV);
3816 long do_rt_sigreturn(CPUCRISState *env)
3818 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3819 return -TARGET_ENOSYS;
3822 #elif defined(TARGET_OPENRISC)
3824 struct target_sigcontext {
3825 struct target_pt_regs regs;
3826 abi_ulong oldmask;
3827 abi_ulong usp;
3830 struct target_ucontext {
3831 abi_ulong tuc_flags;
3832 abi_ulong tuc_link;
3833 target_stack_t tuc_stack;
3834 struct target_sigcontext tuc_mcontext;
3835 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3838 struct target_rt_sigframe {
3839 abi_ulong pinfo;
3840 uint64_t puc;
3841 struct target_siginfo info;
3842 struct target_sigcontext sc;
3843 struct target_ucontext uc;
3844 unsigned char retcode[16]; /* trampoline code */
3847 /* This is the asm-generic/ucontext.h version */
3848 #if 0
3849 static int restore_sigcontext(CPUOpenRISCState *regs,
3850 struct target_sigcontext *sc)
3852 unsigned int err = 0;
3853 unsigned long old_usp;
3855 /* Alwys make any pending restarted system call return -EINTR */
3856 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3858 /* restore the regs from &sc->regs (same as sc, since regs is first)
3859 * (sc is already checked for VERIFY_READ since the sigframe was
3860 * checked in sys_sigreturn previously)
3863 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3864 goto badframe;
3867 /* make sure the U-flag is set so user-mode cannot fool us */
3869 regs->sr &= ~SR_SM;
3871 /* restore the old USP as it was before we stacked the sc etc.
3872 * (we cannot just pop the sigcontext since we aligned the sp and
3873 * stuff after pushing it)
3876 err |= __get_user(old_usp, &sc->usp);
3877 phx_signal("old_usp 0x%lx", old_usp);
3879 __PHX__ REALLY /* ??? */
3880 wrusp(old_usp);
3881 regs->gpr[1] = old_usp;
3883 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3884 * after this completes, but we don't use that mechanism. maybe we can
3885 * use it now ?
3888 return err;
3890 badframe:
3891 return 1;
3893 #endif
3895 /* Set up a signal frame. */
3897 static int setup_sigcontext(struct target_sigcontext *sc,
3898 CPUOpenRISCState *regs,
3899 unsigned long mask)
3901 int err = 0;
3902 unsigned long usp = regs->gpr[1];
3904 /* copy the regs. they are first in sc so we can use sc directly */
3906 /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3908 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3909 the signal handler. The frametype will be restored to its previous
3910 value in restore_sigcontext. */
3911 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3913 /* then some other stuff */
3914 err |= __put_user(mask, &sc->oldmask);
3915 err |= __put_user(usp, &sc->usp); return err;
3918 static inline unsigned long align_sigframe(unsigned long sp)
3920 unsigned long i;
3921 i = sp & ~3UL;
3922 return i;
3925 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3926 CPUOpenRISCState *regs,
3927 size_t frame_size)
3929 unsigned long sp = regs->gpr[1];
3930 int onsigstack = on_sig_stack(sp);
3932 /* redzone */
3933 /* This is the X/Open sanctioned signal stack switching. */
3934 if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
3935 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3938 sp = align_sigframe(sp - frame_size);
3941 * If we are on the alternate signal stack and would overflow it, don't.
3942 * Return an always-bogus address instead so we will die with SIGSEGV.
3945 if (onsigstack && !likely(on_sig_stack(sp))) {
3946 return -1L;
3949 return sp;
3952 static void setup_frame(int sig, struct target_sigaction *ka,
3953 target_sigset_t *set, CPUOpenRISCState *env)
3955 qemu_log("Not implement.\n");
3958 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3959 target_siginfo_t *info,
3960 target_sigset_t *set, CPUOpenRISCState *env)
3962 int err = 0;
3963 abi_ulong frame_addr;
3964 unsigned long return_ip;
3965 struct target_rt_sigframe *frame;
3966 abi_ulong info_addr, uc_addr;
3968 frame_addr = get_sigframe(ka, env, sizeof *frame);
3970 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3971 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3972 goto give_sigsegv;
3975 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
3976 err |= __put_user(info_addr, &frame->pinfo);
3977 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
3978 err |= __put_user(uc_addr, &frame->puc);
3980 if (ka->sa_flags & SA_SIGINFO) {
3981 err |= copy_siginfo_to_user(&frame->info, info);
3983 if (err) {
3984 goto give_sigsegv;
3987 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3988 err |= __put_user(0, &frame->uc.tuc_flags);
3989 err |= __put_user(0, &frame->uc.tuc_link);
3990 err |= __put_user(target_sigaltstack_used.ss_sp,
3991 &frame->uc.tuc_stack.ss_sp);
3992 err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
3993 err |= __put_user(target_sigaltstack_used.ss_size,
3994 &frame->uc.tuc_stack.ss_size);
3995 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
3997 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3999 if (err) {
4000 goto give_sigsegv;
4003 /* trampoline - the desired return ip is the retcode itself */
4004 return_ip = (unsigned long)&frame->retcode;
4005 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
4006 err |= __put_user(0xa960, (short *)(frame->retcode + 0));
4007 err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
4008 err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
4009 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
4011 if (err) {
4012 goto give_sigsegv;
4015 /* TODO what is the current->exec_domain stuff and invmap ? */
4017 /* Set up registers for signal handler */
4018 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
4019 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
4020 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
4021 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
4022 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
4024 /* actually move the usp to reflect the stacked frame */
4025 env->gpr[1] = (unsigned long)frame;
4027 return;
4029 give_sigsegv:
4030 unlock_user_struct(frame, frame_addr, 1);
4031 if (sig == TARGET_SIGSEGV) {
4032 ka->_sa_handler = TARGET_SIG_DFL;
4034 force_sig(TARGET_SIGSEGV);
4037 long do_sigreturn(CPUOpenRISCState *env)
4040 qemu_log("do_sigreturn: not implemented\n");
4041 return -TARGET_ENOSYS;
4044 long do_rt_sigreturn(CPUOpenRISCState *env)
4046 qemu_log("do_rt_sigreturn: not implemented\n");
4047 return -TARGET_ENOSYS;
4049 /* TARGET_OPENRISC */
4051 #elif defined(TARGET_S390X)
4053 #define __NUM_GPRS 16
4054 #define __NUM_FPRS 16
4055 #define __NUM_ACRS 16
4057 #define S390_SYSCALL_SIZE 2
4058 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4060 #define _SIGCONTEXT_NSIG 64
4061 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4062 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4063 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4064 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4065 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4067 typedef struct {
4068 target_psw_t psw;
4069 target_ulong gprs[__NUM_GPRS];
4070 unsigned int acrs[__NUM_ACRS];
4071 } target_s390_regs_common;
4073 typedef struct {
4074 unsigned int fpc;
4075 double fprs[__NUM_FPRS];
4076 } target_s390_fp_regs;
4078 typedef struct {
4079 target_s390_regs_common regs;
4080 target_s390_fp_regs fpregs;
4081 } target_sigregs;
4083 struct target_sigcontext {
4084 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4085 target_sigregs *sregs;
4088 typedef struct {
4089 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4090 struct target_sigcontext sc;
4091 target_sigregs sregs;
4092 int signo;
4093 uint8_t retcode[S390_SYSCALL_SIZE];
4094 } sigframe;
4096 struct target_ucontext {
4097 target_ulong tuc_flags;
4098 struct target_ucontext *tuc_link;
4099 target_stack_t tuc_stack;
4100 target_sigregs tuc_mcontext;
4101 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4104 typedef struct {
4105 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4106 uint8_t retcode[S390_SYSCALL_SIZE];
4107 struct target_siginfo info;
4108 struct target_ucontext uc;
4109 } rt_sigframe;
4111 static inline abi_ulong
4112 get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4114 abi_ulong sp;
4116 /* Default to using normal stack */
4117 sp = env->regs[15];
4119 /* This is the X/Open sanctioned signal stack switching. */
4120 if (ka->sa_flags & TARGET_SA_ONSTACK) {
4121 if (!sas_ss_flags(sp)) {
4122 sp = target_sigaltstack_used.ss_sp +
4123 target_sigaltstack_used.ss_size;
4127 /* This is the legacy signal stack switching. */
4128 else if (/* FIXME !user_mode(regs) */ 0 &&
4129 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4130 ka->sa_restorer) {
4131 sp = (abi_ulong) ka->sa_restorer;
4134 return (sp - frame_size) & -8ul;
4137 static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4139 int i;
4140 //save_access_regs(current->thread.acrs); FIXME
4142 /* Copy a 'clean' PSW mask to the user to avoid leaking
4143 information about whether PER is currently on. */
4144 __put_user(env->psw.mask, &sregs->regs.psw.mask);
4145 __put_user(env->psw.addr, &sregs->regs.psw.addr);
4146 for (i = 0; i < 16; i++) {
4147 __put_user(env->regs[i], &sregs->regs.gprs[i]);
4149 for (i = 0; i < 16; i++) {
4150 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
4153 * We have to store the fp registers to current->thread.fp_regs
4154 * to merge them with the emulated registers.
4156 //save_fp_regs(&current->thread.fp_regs); FIXME
4157 for (i = 0; i < 16; i++) {
4158 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4162 static void setup_frame(int sig, struct target_sigaction *ka,
4163 target_sigset_t *set, CPUS390XState *env)
4165 sigframe *frame;
4166 abi_ulong frame_addr;
4168 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4169 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4170 (unsigned long long)frame_addr);
4171 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4172 goto give_sigsegv;
4175 qemu_log("%s: 1\n", __FUNCTION__);
4176 if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
4177 goto give_sigsegv;
4180 save_sigregs(env, &frame->sregs);
4182 __put_user((abi_ulong)(unsigned long)&frame->sregs,
4183 (abi_ulong *)&frame->sc.sregs);
4185 /* Set up to return from userspace. If provided, use a stub
4186 already in userspace. */
4187 if (ka->sa_flags & TARGET_SA_RESTORER) {
4188 env->regs[14] = (unsigned long)
4189 ka->sa_restorer | PSW_ADDR_AMODE;
4190 } else {
4191 env->regs[14] = (unsigned long)
4192 frame->retcode | PSW_ADDR_AMODE;
4193 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
4194 (uint16_t *)(frame->retcode)))
4195 goto give_sigsegv;
4198 /* Set up backchain. */
4199 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4200 goto give_sigsegv;
4203 /* Set up registers for signal handler */
4204 env->regs[15] = frame_addr;
4205 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4207 env->regs[2] = sig; //map_signal(sig);
4208 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
4210 /* We forgot to include these in the sigcontext.
4211 To avoid breaking binary compatibility, they are passed as args. */
4212 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4213 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4215 /* Place signal number on stack to allow backtrace from handler. */
4216 if (__put_user(env->regs[2], (int *) &frame->signo)) {
4217 goto give_sigsegv;
4219 unlock_user_struct(frame, frame_addr, 1);
4220 return;
4222 give_sigsegv:
4223 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4224 unlock_user_struct(frame, frame_addr, 1);
4225 force_sig(TARGET_SIGSEGV);
4228 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4229 target_siginfo_t *info,
4230 target_sigset_t *set, CPUS390XState *env)
4232 int i;
4233 rt_sigframe *frame;
4234 abi_ulong frame_addr;
4236 frame_addr = get_sigframe(ka, env, sizeof *frame);
4237 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4238 (unsigned long long)frame_addr);
4239 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4240 goto give_sigsegv;
4243 qemu_log("%s: 1\n", __FUNCTION__);
4244 if (copy_siginfo_to_user(&frame->info, info)) {
4245 goto give_sigsegv;
4248 /* Create the ucontext. */
4249 __put_user(0, &frame->uc.tuc_flags);
4250 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
4251 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
4252 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
4253 &frame->uc.tuc_stack.ss_flags);
4254 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
4255 save_sigregs(env, &frame->uc.tuc_mcontext);
4256 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
4257 __put_user((abi_ulong)set->sig[i],
4258 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
4261 /* Set up to return from userspace. If provided, use a stub
4262 already in userspace. */
4263 if (ka->sa_flags & TARGET_SA_RESTORER) {
4264 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4265 } else {
4266 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4267 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
4268 (uint16_t *)(frame->retcode))) {
4269 goto give_sigsegv;
4273 /* Set up backchain. */
4274 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4275 goto give_sigsegv;
4278 /* Set up registers for signal handler */
4279 env->regs[15] = frame_addr;
4280 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4282 env->regs[2] = sig; //map_signal(sig);
4283 env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
4284 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
4285 return;
4287 give_sigsegv:
4288 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4289 unlock_user_struct(frame, frame_addr, 1);
4290 force_sig(TARGET_SIGSEGV);
4293 static int
4294 restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4296 int err = 0;
4297 int i;
4299 for (i = 0; i < 16; i++) {
4300 err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
4303 err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
4304 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4305 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4306 (unsigned long long)env->psw.addr);
4307 err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
4308 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4310 for (i = 0; i < 16; i++) {
4311 err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
4313 for (i = 0; i < 16; i++) {
4314 err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4317 return err;
4320 long do_sigreturn(CPUS390XState *env)
4322 sigframe *frame;
4323 abi_ulong frame_addr = env->regs[15];
4324 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4325 (unsigned long long)frame_addr);
4326 target_sigset_t target_set;
4327 sigset_t set;
4329 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4330 goto badframe;
4332 if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
4333 goto badframe;
4336 target_to_host_sigset_internal(&set, &target_set);
4337 sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4339 if (restore_sigregs(env, &frame->sregs)) {
4340 goto badframe;
4343 unlock_user_struct(frame, frame_addr, 0);
4344 return env->regs[2];
4346 badframe:
4347 unlock_user_struct(frame, frame_addr, 0);
4348 force_sig(TARGET_SIGSEGV);
4349 return 0;
4352 long do_rt_sigreturn(CPUS390XState *env)
4354 rt_sigframe *frame;
4355 abi_ulong frame_addr = env->regs[15];
4356 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4357 (unsigned long long)frame_addr);
4358 sigset_t set;
4360 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4361 goto badframe;
4363 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4365 sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4367 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4368 goto badframe;
4371 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4372 get_sp_from_cpustate(env)) == -EFAULT) {
4373 goto badframe;
4375 unlock_user_struct(frame, frame_addr, 0);
4376 return env->regs[2];
4378 badframe:
4379 unlock_user_struct(frame, frame_addr, 0);
4380 force_sig(TARGET_SIGSEGV);
4381 return 0;
4384 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4386 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4387 the signal handling is different enough that we haven't implemented
4388 support for PPC64 yet. Hence the restriction above.
4390 There are various #if'd blocks for code for TARGET_PPC64. These
4391 blocks should go away so that we can successfully run 32-bit and
4392 64-bit binaries on a QEMU configured for PPC64. */
4394 /* Size of dummy stack frame allocated when calling signal handler.
4395 See arch/powerpc/include/asm/ptrace.h. */
4396 #if defined(TARGET_PPC64)
4397 #define SIGNAL_FRAMESIZE 128
4398 #else
4399 #define SIGNAL_FRAMESIZE 64
4400 #endif
4402 /* See arch/powerpc/include/asm/sigcontext.h. */
4403 struct target_sigcontext {
4404 target_ulong _unused[4];
4405 int32_t signal;
4406 #if defined(TARGET_PPC64)
4407 int32_t pad0;
4408 #endif
4409 target_ulong handler;
4410 target_ulong oldmask;
4411 target_ulong regs; /* struct pt_regs __user * */
4412 /* TODO: PPC64 includes extra bits here. */
4415 /* Indices for target_mcontext.mc_gregs, below.
4416 See arch/powerpc/include/asm/ptrace.h for details. */
4417 enum {
4418 TARGET_PT_R0 = 0,
4419 TARGET_PT_R1 = 1,
4420 TARGET_PT_R2 = 2,
4421 TARGET_PT_R3 = 3,
4422 TARGET_PT_R4 = 4,
4423 TARGET_PT_R5 = 5,
4424 TARGET_PT_R6 = 6,
4425 TARGET_PT_R7 = 7,
4426 TARGET_PT_R8 = 8,
4427 TARGET_PT_R9 = 9,
4428 TARGET_PT_R10 = 10,
4429 TARGET_PT_R11 = 11,
4430 TARGET_PT_R12 = 12,
4431 TARGET_PT_R13 = 13,
4432 TARGET_PT_R14 = 14,
4433 TARGET_PT_R15 = 15,
4434 TARGET_PT_R16 = 16,
4435 TARGET_PT_R17 = 17,
4436 TARGET_PT_R18 = 18,
4437 TARGET_PT_R19 = 19,
4438 TARGET_PT_R20 = 20,
4439 TARGET_PT_R21 = 21,
4440 TARGET_PT_R22 = 22,
4441 TARGET_PT_R23 = 23,
4442 TARGET_PT_R24 = 24,
4443 TARGET_PT_R25 = 25,
4444 TARGET_PT_R26 = 26,
4445 TARGET_PT_R27 = 27,
4446 TARGET_PT_R28 = 28,
4447 TARGET_PT_R29 = 29,
4448 TARGET_PT_R30 = 30,
4449 TARGET_PT_R31 = 31,
4450 TARGET_PT_NIP = 32,
4451 TARGET_PT_MSR = 33,
4452 TARGET_PT_ORIG_R3 = 34,
4453 TARGET_PT_CTR = 35,
4454 TARGET_PT_LNK = 36,
4455 TARGET_PT_XER = 37,
4456 TARGET_PT_CCR = 38,
4457 /* Yes, there are two registers with #39. One is 64-bit only. */
4458 TARGET_PT_MQ = 39,
4459 TARGET_PT_SOFTE = 39,
4460 TARGET_PT_TRAP = 40,
4461 TARGET_PT_DAR = 41,
4462 TARGET_PT_DSISR = 42,
4463 TARGET_PT_RESULT = 43,
4464 TARGET_PT_REGS_COUNT = 44
4467 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4468 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4469 struct target_mcontext {
4470 target_ulong mc_gregs[48];
4471 /* Includes fpscr. */
4472 uint64_t mc_fregs[33];
4473 target_ulong mc_pad[2];
4474 /* We need to handle Altivec and SPE at the same time, which no
4475 kernel needs to do. Fortunately, the kernel defines this bit to
4476 be Altivec-register-large all the time, rather than trying to
4477 twiddle it based on the specific platform. */
4478 union {
4479 /* SPE vector registers. One extra for SPEFSCR. */
4480 uint32_t spe[33];
4481 /* Altivec vector registers. The packing of VSCR and VRSAVE
4482 varies depending on whether we're PPC64 or not: PPC64 splits
4483 them apart; PPC32 stuffs them together. */
4484 #if defined(TARGET_PPC64)
4485 #define QEMU_NVRREG 34
4486 #else
4487 #define QEMU_NVRREG 33
4488 #endif
4489 ppc_avr_t altivec[QEMU_NVRREG];
4490 #undef QEMU_NVRREG
4491 } mc_vregs __attribute__((__aligned__(16)));
4494 struct target_ucontext {
4495 target_ulong tuc_flags;
4496 target_ulong tuc_link; /* struct ucontext __user * */
4497 struct target_sigaltstack tuc_stack;
4498 #if !defined(TARGET_PPC64)
4499 int32_t tuc_pad[7];
4500 target_ulong tuc_regs; /* struct mcontext __user *
4501 points to uc_mcontext field */
4502 #endif
4503 target_sigset_t tuc_sigmask;
4504 #if defined(TARGET_PPC64)
4505 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4506 struct target_sigcontext tuc_mcontext;
4507 #else
4508 int32_t tuc_maskext[30];
4509 int32_t tuc_pad2[3];
4510 struct target_mcontext tuc_mcontext;
4511 #endif
4514 /* See arch/powerpc/kernel/signal_32.c. */
4515 struct target_sigframe {
4516 struct target_sigcontext sctx;
4517 struct target_mcontext mctx;
4518 int32_t abigap[56];
4521 struct target_rt_sigframe {
4522 struct target_siginfo info;
4523 struct target_ucontext uc;
4524 int32_t abigap[56];
4527 /* We use the mc_pad field for the signal return trampoline. */
4528 #define tramp mc_pad
4530 /* See arch/powerpc/kernel/signal.c. */
4531 static target_ulong get_sigframe(struct target_sigaction *ka,
4532 CPUPPCState *env,
4533 int frame_size)
4535 target_ulong oldsp, newsp;
4537 oldsp = env->gpr[1];
4539 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4540 (sas_ss_flags(oldsp) == 0)) {
4541 oldsp = (target_sigaltstack_used.ss_sp
4542 + target_sigaltstack_used.ss_size);
4545 newsp = (oldsp - frame_size) & ~0xFUL;
4547 return newsp;
4550 static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4551 int sigret)
4553 target_ulong msr = env->msr;
4554 int i;
4555 target_ulong ccr = 0;
4557 /* In general, the kernel attempts to be intelligent about what it
4558 needs to save for Altivec/FP/SPE registers. We don't care that
4559 much, so we just go ahead and save everything. */
4561 /* Save general registers. */
4562 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4563 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
4564 return 1;
4567 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4568 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4569 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4570 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4571 return 1;
4573 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4574 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4576 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4577 return 1;
4579 /* Save Altivec registers if necessary. */
4580 if (env->insns_flags & PPC_ALTIVEC) {
4581 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4582 ppc_avr_t *avr = &env->avr[i];
4583 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4585 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4586 __put_user(avr->u64[1], &vreg->u64[1])) {
4587 return 1;
4590 /* Set MSR_VR in the saved MSR value to indicate that
4591 frame->mc_vregs contains valid data. */
4592 msr |= MSR_VR;
4593 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4594 &frame->mc_vregs.altivec[32].u32[3]))
4595 return 1;
4598 /* Save floating point registers. */
4599 if (env->insns_flags & PPC_FLOAT) {
4600 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4601 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
4602 return 1;
4605 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
4606 return 1;
4609 /* Save SPE registers. The kernel only saves the high half. */
4610 if (env->insns_flags & PPC_SPE) {
4611 #if defined(TARGET_PPC64)
4612 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4613 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
4614 return 1;
4617 #else
4618 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4619 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4620 return 1;
4623 #endif
4624 /* Set MSR_SPE in the saved MSR value to indicate that
4625 frame->mc_vregs contains valid data. */
4626 msr |= MSR_SPE;
4627 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4628 return 1;
4631 /* Store MSR. */
4632 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4633 return 1;
4635 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4636 if (sigret) {
4637 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4638 __put_user(0x44000002UL, &frame->tramp[1])) {
4639 return 1;
4643 return 0;
4646 static int restore_user_regs(CPUPPCState *env,
4647 struct target_mcontext *frame, int sig)
4649 target_ulong save_r2 = 0;
4650 target_ulong msr;
4651 target_ulong ccr;
4653 int i;
4655 if (!sig) {
4656 save_r2 = env->gpr[2];
4659 /* Restore general registers. */
4660 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4661 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
4662 return 1;
4665 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4666 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4667 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4668 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4669 return 1;
4670 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4671 return 1;
4673 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4674 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4677 if (!sig) {
4678 env->gpr[2] = save_r2;
4680 /* Restore MSR. */
4681 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4682 return 1;
4684 /* If doing signal return, restore the previous little-endian mode. */
4685 if (sig)
4686 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4688 /* Restore Altivec registers if necessary. */
4689 if (env->insns_flags & PPC_ALTIVEC) {
4690 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4691 ppc_avr_t *avr = &env->avr[i];
4692 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4694 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4695 __get_user(avr->u64[1], &vreg->u64[1])) {
4696 return 1;
4699 /* Set MSR_VEC in the saved MSR value to indicate that
4700 frame->mc_vregs contains valid data. */
4701 if (__get_user(env->spr[SPR_VRSAVE],
4702 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
4703 return 1;
4706 /* Restore floating point registers. */
4707 if (env->insns_flags & PPC_FLOAT) {
4708 uint64_t fpscr;
4709 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4710 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4711 return 1;
4714 if (__get_user(fpscr, &frame->mc_fregs[32]))
4715 return 1;
4716 env->fpscr = (uint32_t) fpscr;
4719 /* Save SPE registers. The kernel only saves the high half. */
4720 if (env->insns_flags & PPC_SPE) {
4721 #if defined(TARGET_PPC64)
4722 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4723 uint32_t hi;
4725 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4726 return 1;
4728 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4730 #else
4731 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4732 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4733 return 1;
4736 #endif
4737 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4738 return 1;
4741 return 0;
4744 static void setup_frame(int sig, struct target_sigaction *ka,
4745 target_sigset_t *set, CPUPPCState *env)
4747 struct target_sigframe *frame;
4748 struct target_sigcontext *sc;
4749 target_ulong frame_addr, newsp;
4750 int err = 0;
4751 int signal;
4753 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4754 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4755 goto sigsegv;
4756 sc = &frame->sctx;
4758 signal = current_exec_domain_sig(sig);
4760 err |= __put_user(ka->_sa_handler, &sc->handler);
4761 err |= __put_user(set->sig[0], &sc->oldmask);
4762 #if defined(TARGET_PPC64)
4763 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4764 #else
4765 err |= __put_user(set->sig[1], &sc->_unused[3]);
4766 #endif
4767 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4768 err |= __put_user(sig, &sc->signal);
4770 /* Save user regs. */
4771 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4773 /* The kernel checks for the presence of a VDSO here. We don't
4774 emulate a vdso, so use a sigreturn system call. */
4775 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4777 /* Turn off all fp exceptions. */
4778 env->fpscr = 0;
4780 /* Create a stack frame for the caller of the handler. */
4781 newsp = frame_addr - SIGNAL_FRAMESIZE;
4782 err |= put_user(env->gpr[1], newsp, target_ulong);
4784 if (err)
4785 goto sigsegv;
4787 /* Set up registers for signal handler. */
4788 env->gpr[1] = newsp;
4789 env->gpr[3] = signal;
4790 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
4791 env->nip = (target_ulong) ka->_sa_handler;
4792 /* Signal handlers are entered in big-endian mode. */
4793 env->msr &= ~MSR_LE;
4795 unlock_user_struct(frame, frame_addr, 1);
4796 return;
4798 sigsegv:
4799 unlock_user_struct(frame, frame_addr, 1);
4800 qemu_log("segfaulting from setup_frame\n");
4801 force_sig(TARGET_SIGSEGV);
4804 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4805 target_siginfo_t *info,
4806 target_sigset_t *set, CPUPPCState *env)
4808 struct target_rt_sigframe *rt_sf;
4809 struct target_mcontext *frame;
4810 target_ulong rt_sf_addr, newsp = 0;
4811 int i, err = 0;
4812 int signal;
4814 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4815 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4816 goto sigsegv;
4818 signal = current_exec_domain_sig(sig);
4820 err |= copy_siginfo_to_user(&rt_sf->info, info);
4822 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4823 err |= __put_user(0, &rt_sf->uc.tuc_link);
4824 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4825 &rt_sf->uc.tuc_stack.ss_sp);
4826 err |= __put_user(sas_ss_flags(env->gpr[1]),
4827 &rt_sf->uc.tuc_stack.ss_flags);
4828 err |= __put_user(target_sigaltstack_used.ss_size,
4829 &rt_sf->uc.tuc_stack.ss_size);
4830 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4831 &rt_sf->uc.tuc_regs);
4832 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4833 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4836 frame = &rt_sf->uc.tuc_mcontext;
4837 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4839 /* The kernel checks for the presence of a VDSO here. We don't
4840 emulate a vdso, so use a sigreturn system call. */
4841 env->lr = (target_ulong) h2g(frame->tramp);
4843 /* Turn off all fp exceptions. */
4844 env->fpscr = 0;
4846 /* Create a stack frame for the caller of the handler. */
4847 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4848 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4850 if (err)
4851 goto sigsegv;
4853 /* Set up registers for signal handler. */
4854 env->gpr[1] = newsp;
4855 env->gpr[3] = (target_ulong) signal;
4856 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4857 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4858 env->gpr[6] = (target_ulong) h2g(rt_sf);
4859 env->nip = (target_ulong) ka->_sa_handler;
4860 /* Signal handlers are entered in big-endian mode. */
4861 env->msr &= ~MSR_LE;
4863 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4864 return;
4866 sigsegv:
4867 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4868 qemu_log("segfaulting from setup_rt_frame\n");
4869 force_sig(TARGET_SIGSEGV);
4873 long do_sigreturn(CPUPPCState *env)
4875 struct target_sigcontext *sc = NULL;
4876 struct target_mcontext *sr = NULL;
4877 target_ulong sr_addr = 0, sc_addr;
4878 sigset_t blocked;
4879 target_sigset_t set;
4881 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4882 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4883 goto sigsegv;
4885 #if defined(TARGET_PPC64)
4886 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4887 #else
4888 if(__get_user(set.sig[0], &sc->oldmask) ||
4889 __get_user(set.sig[1], &sc->_unused[3]))
4890 goto sigsegv;
4891 #endif
4892 target_to_host_sigset_internal(&blocked, &set);
4893 sigprocmask(SIG_SETMASK, &blocked, NULL);
4895 if (__get_user(sr_addr, &sc->regs))
4896 goto sigsegv;
4897 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4898 goto sigsegv;
4899 if (restore_user_regs(env, sr, 1))
4900 goto sigsegv;
4902 unlock_user_struct(sr, sr_addr, 1);
4903 unlock_user_struct(sc, sc_addr, 1);
4904 return -TARGET_QEMU_ESIGRETURN;
4906 sigsegv:
4907 unlock_user_struct(sr, sr_addr, 1);
4908 unlock_user_struct(sc, sc_addr, 1);
4909 qemu_log("segfaulting from do_sigreturn\n");
4910 force_sig(TARGET_SIGSEGV);
4911 return 0;
4914 /* See arch/powerpc/kernel/signal_32.c. */
4915 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4917 struct target_mcontext *mcp;
4918 target_ulong mcp_addr;
4919 sigset_t blocked;
4920 target_sigset_t set;
4922 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4923 sizeof (set)))
4924 return 1;
4926 #if defined(TARGET_PPC64)
4927 fprintf (stderr, "do_setcontext: not implemented\n");
4928 return 0;
4929 #else
4930 if (__get_user(mcp_addr, &ucp->tuc_regs))
4931 return 1;
4933 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4934 return 1;
4936 target_to_host_sigset_internal(&blocked, &set);
4937 sigprocmask(SIG_SETMASK, &blocked, NULL);
4938 if (restore_user_regs(env, mcp, sig))
4939 goto sigsegv;
4941 unlock_user_struct(mcp, mcp_addr, 1);
4942 return 0;
4944 sigsegv:
4945 unlock_user_struct(mcp, mcp_addr, 1);
4946 return 1;
4947 #endif
4950 long do_rt_sigreturn(CPUPPCState *env)
4952 struct target_rt_sigframe *rt_sf = NULL;
4953 target_ulong rt_sf_addr;
4955 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4956 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4957 goto sigsegv;
4959 if (do_setcontext(&rt_sf->uc, env, 1))
4960 goto sigsegv;
4962 do_sigaltstack(rt_sf_addr
4963 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4964 0, env->gpr[1]);
4966 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4967 return -TARGET_QEMU_ESIGRETURN;
4969 sigsegv:
4970 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4971 qemu_log("segfaulting from do_rt_sigreturn\n");
4972 force_sig(TARGET_SIGSEGV);
4973 return 0;
4976 #elif defined(TARGET_M68K)
4978 struct target_sigcontext {
4979 abi_ulong sc_mask;
4980 abi_ulong sc_usp;
4981 abi_ulong sc_d0;
4982 abi_ulong sc_d1;
4983 abi_ulong sc_a0;
4984 abi_ulong sc_a1;
4985 unsigned short sc_sr;
4986 abi_ulong sc_pc;
4989 struct target_sigframe
4991 abi_ulong pretcode;
4992 int sig;
4993 int code;
4994 abi_ulong psc;
4995 char retcode[8];
4996 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4997 struct target_sigcontext sc;
5000 typedef int target_greg_t;
5001 #define TARGET_NGREG 18
5002 typedef target_greg_t target_gregset_t[TARGET_NGREG];
5004 typedef struct target_fpregset {
5005 int f_fpcntl[3];
5006 int f_fpregs[8*3];
5007 } target_fpregset_t;
5009 struct target_mcontext {
5010 int version;
5011 target_gregset_t gregs;
5012 target_fpregset_t fpregs;
5015 #define TARGET_MCONTEXT_VERSION 2
5017 struct target_ucontext {
5018 abi_ulong tuc_flags;
5019 abi_ulong tuc_link;
5020 target_stack_t tuc_stack;
5021 struct target_mcontext tuc_mcontext;
5022 abi_long tuc_filler[80];
5023 target_sigset_t tuc_sigmask;
5026 struct target_rt_sigframe
5028 abi_ulong pretcode;
5029 int sig;
5030 abi_ulong pinfo;
5031 abi_ulong puc;
5032 char retcode[8];
5033 struct target_siginfo info;
5034 struct target_ucontext uc;
5037 static int
5038 setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
5039 abi_ulong mask)
5041 int err = 0;
5043 err |= __put_user(mask, &sc->sc_mask);
5044 err |= __put_user(env->aregs[7], &sc->sc_usp);
5045 err |= __put_user(env->dregs[0], &sc->sc_d0);
5046 err |= __put_user(env->dregs[1], &sc->sc_d1);
5047 err |= __put_user(env->aregs[0], &sc->sc_a0);
5048 err |= __put_user(env->aregs[1], &sc->sc_a1);
5049 err |= __put_user(env->sr, &sc->sc_sr);
5050 err |= __put_user(env->pc, &sc->sc_pc);
5052 return err;
5055 static int
5056 restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
5058 int err = 0;
5059 int temp;
5061 err |= __get_user(env->aregs[7], &sc->sc_usp);
5062 err |= __get_user(env->dregs[1], &sc->sc_d1);
5063 err |= __get_user(env->aregs[0], &sc->sc_a0);
5064 err |= __get_user(env->aregs[1], &sc->sc_a1);
5065 err |= __get_user(env->pc, &sc->sc_pc);
5066 err |= __get_user(temp, &sc->sc_sr);
5067 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5069 *pd0 = tswapl(sc->sc_d0);
5071 return err;
5075 * Determine which stack to use..
5077 static inline abi_ulong
5078 get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5079 size_t frame_size)
5081 unsigned long sp;
5083 sp = regs->aregs[7];
5085 /* This is the X/Open sanctioned signal stack switching. */
5086 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
5087 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5090 return ((sp - frame_size) & -8UL);
5093 static void setup_frame(int sig, struct target_sigaction *ka,
5094 target_sigset_t *set, CPUM68KState *env)
5096 struct target_sigframe *frame;
5097 abi_ulong frame_addr;
5098 abi_ulong retcode_addr;
5099 abi_ulong sc_addr;
5100 int err = 0;
5101 int i;
5103 frame_addr = get_sigframe(ka, env, sizeof *frame);
5104 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5105 goto give_sigsegv;
5107 err |= __put_user(sig, &frame->sig);
5109 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
5110 err |= __put_user(sc_addr, &frame->psc);
5112 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
5113 if (err)
5114 goto give_sigsegv;
5116 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5117 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
5118 goto give_sigsegv;
5121 /* Set up to return from userspace. */
5123 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5124 err |= __put_user(retcode_addr, &frame->pretcode);
5126 /* moveq #,d0; trap #0 */
5128 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5129 (long *)(frame->retcode));
5131 if (err)
5132 goto give_sigsegv;
5134 /* Set up to return from userspace */
5136 env->aregs[7] = frame_addr;
5137 env->pc = ka->_sa_handler;
5139 unlock_user_struct(frame, frame_addr, 1);
5140 return;
5142 give_sigsegv:
5143 unlock_user_struct(frame, frame_addr, 1);
5144 force_sig(TARGET_SIGSEGV);
5147 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5148 CPUM68KState *env)
5150 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5151 int err;
5153 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
5154 err |= __put_user(env->dregs[0], &gregs[0]);
5155 err |= __put_user(env->dregs[1], &gregs[1]);
5156 err |= __put_user(env->dregs[2], &gregs[2]);
5157 err |= __put_user(env->dregs[3], &gregs[3]);
5158 err |= __put_user(env->dregs[4], &gregs[4]);
5159 err |= __put_user(env->dregs[5], &gregs[5]);
5160 err |= __put_user(env->dregs[6], &gregs[6]);
5161 err |= __put_user(env->dregs[7], &gregs[7]);
5162 err |= __put_user(env->aregs[0], &gregs[8]);
5163 err |= __put_user(env->aregs[1], &gregs[9]);
5164 err |= __put_user(env->aregs[2], &gregs[10]);
5165 err |= __put_user(env->aregs[3], &gregs[11]);
5166 err |= __put_user(env->aregs[4], &gregs[12]);
5167 err |= __put_user(env->aregs[5], &gregs[13]);
5168 err |= __put_user(env->aregs[6], &gregs[14]);
5169 err |= __put_user(env->aregs[7], &gregs[15]);
5170 err |= __put_user(env->pc, &gregs[16]);
5171 err |= __put_user(env->sr, &gregs[17]);
5173 return err;
5176 static inline int target_rt_restore_ucontext(CPUM68KState *env,
5177 struct target_ucontext *uc,
5178 int *pd0)
5180 int temp;
5181 int err;
5182 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5184 err = __get_user(temp, &uc->tuc_mcontext.version);
5185 if (temp != TARGET_MCONTEXT_VERSION)
5186 goto badframe;
5188 /* restore passed registers */
5189 err |= __get_user(env->dregs[0], &gregs[0]);
5190 err |= __get_user(env->dregs[1], &gregs[1]);
5191 err |= __get_user(env->dregs[2], &gregs[2]);
5192 err |= __get_user(env->dregs[3], &gregs[3]);
5193 err |= __get_user(env->dregs[4], &gregs[4]);
5194 err |= __get_user(env->dregs[5], &gregs[5]);
5195 err |= __get_user(env->dregs[6], &gregs[6]);
5196 err |= __get_user(env->dregs[7], &gregs[7]);
5197 err |= __get_user(env->aregs[0], &gregs[8]);
5198 err |= __get_user(env->aregs[1], &gregs[9]);
5199 err |= __get_user(env->aregs[2], &gregs[10]);
5200 err |= __get_user(env->aregs[3], &gregs[11]);
5201 err |= __get_user(env->aregs[4], &gregs[12]);
5202 err |= __get_user(env->aregs[5], &gregs[13]);
5203 err |= __get_user(env->aregs[6], &gregs[14]);
5204 err |= __get_user(env->aregs[7], &gregs[15]);
5205 err |= __get_user(env->pc, &gregs[16]);
5206 err |= __get_user(temp, &gregs[17]);
5207 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5209 *pd0 = env->dregs[0];
5210 return err;
5212 badframe:
5213 return 1;
5216 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5217 target_siginfo_t *info,
5218 target_sigset_t *set, CPUM68KState *env)
5220 struct target_rt_sigframe *frame;
5221 abi_ulong frame_addr;
5222 abi_ulong retcode_addr;
5223 abi_ulong info_addr;
5224 abi_ulong uc_addr;
5225 int err = 0;
5226 int i;
5228 frame_addr = get_sigframe(ka, env, sizeof *frame);
5229 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5230 goto give_sigsegv;
5232 err |= __put_user(sig, &frame->sig);
5234 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5235 err |= __put_user(info_addr, &frame->pinfo);
5237 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5238 err |= __put_user(uc_addr, &frame->puc);
5240 err |= copy_siginfo_to_user(&frame->info, info);
5242 /* Create the ucontext */
5244 err |= __put_user(0, &frame->uc.tuc_flags);
5245 err |= __put_user(0, &frame->uc.tuc_link);
5246 err |= __put_user(target_sigaltstack_used.ss_sp,
5247 &frame->uc.tuc_stack.ss_sp);
5248 err |= __put_user(sas_ss_flags(env->aregs[7]),
5249 &frame->uc.tuc_stack.ss_flags);
5250 err |= __put_user(target_sigaltstack_used.ss_size,
5251 &frame->uc.tuc_stack.ss_size);
5252 err |= target_rt_setup_ucontext(&frame->uc, env);
5254 if (err)
5255 goto give_sigsegv;
5257 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5258 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
5259 goto give_sigsegv;
5262 /* Set up to return from userspace. */
5264 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5265 err |= __put_user(retcode_addr, &frame->pretcode);
5267 /* moveq #,d0; notb d0; trap #0 */
5269 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
5270 (long *)(frame->retcode + 0));
5271 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
5273 if (err)
5274 goto give_sigsegv;
5276 /* Set up to return from userspace */
5278 env->aregs[7] = frame_addr;
5279 env->pc = ka->_sa_handler;
5281 unlock_user_struct(frame, frame_addr, 1);
5282 return;
5284 give_sigsegv:
5285 unlock_user_struct(frame, frame_addr, 1);
5286 force_sig(TARGET_SIGSEGV);
5289 long do_sigreturn(CPUM68KState *env)
5291 struct target_sigframe *frame;
5292 abi_ulong frame_addr = env->aregs[7] - 4;
5293 target_sigset_t target_set;
5294 sigset_t set;
5295 int d0, i;
5297 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5298 goto badframe;
5300 /* set blocked signals */
5302 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
5303 goto badframe;
5305 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5306 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
5307 goto badframe;
5310 target_to_host_sigset_internal(&set, &target_set);
5311 sigprocmask(SIG_SETMASK, &set, NULL);
5313 /* restore registers */
5315 if (restore_sigcontext(env, &frame->sc, &d0))
5316 goto badframe;
5318 unlock_user_struct(frame, frame_addr, 0);
5319 return d0;
5321 badframe:
5322 unlock_user_struct(frame, frame_addr, 0);
5323 force_sig(TARGET_SIGSEGV);
5324 return 0;
5327 long do_rt_sigreturn(CPUM68KState *env)
5329 struct target_rt_sigframe *frame;
5330 abi_ulong frame_addr = env->aregs[7] - 4;
5331 target_sigset_t target_set;
5332 sigset_t set;
5333 int d0;
5335 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5336 goto badframe;
5338 target_to_host_sigset_internal(&set, &target_set);
5339 sigprocmask(SIG_SETMASK, &set, NULL);
5341 /* restore registers */
5343 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5344 goto badframe;
5346 if (do_sigaltstack(frame_addr +
5347 offsetof(struct target_rt_sigframe, uc.tuc_stack),
5348 0, get_sp_from_cpustate(env)) == -EFAULT)
5349 goto badframe;
5351 unlock_user_struct(frame, frame_addr, 0);
5352 return d0;
5354 badframe:
5355 unlock_user_struct(frame, frame_addr, 0);
5356 force_sig(TARGET_SIGSEGV);
5357 return 0;
5360 #elif defined(TARGET_ALPHA)
5362 struct target_sigcontext {
5363 abi_long sc_onstack;
5364 abi_long sc_mask;
5365 abi_long sc_pc;
5366 abi_long sc_ps;
5367 abi_long sc_regs[32];
5368 abi_long sc_ownedfp;
5369 abi_long sc_fpregs[32];
5370 abi_ulong sc_fpcr;
5371 abi_ulong sc_fp_control;
5372 abi_ulong sc_reserved1;
5373 abi_ulong sc_reserved2;
5374 abi_ulong sc_ssize;
5375 abi_ulong sc_sbase;
5376 abi_ulong sc_traparg_a0;
5377 abi_ulong sc_traparg_a1;
5378 abi_ulong sc_traparg_a2;
5379 abi_ulong sc_fp_trap_pc;
5380 abi_ulong sc_fp_trigger_sum;
5381 abi_ulong sc_fp_trigger_inst;
5384 struct target_ucontext {
5385 abi_ulong tuc_flags;
5386 abi_ulong tuc_link;
5387 abi_ulong tuc_osf_sigmask;
5388 target_stack_t tuc_stack;
5389 struct target_sigcontext tuc_mcontext;
5390 target_sigset_t tuc_sigmask;
5393 struct target_sigframe {
5394 struct target_sigcontext sc;
5395 unsigned int retcode[3];
5398 struct target_rt_sigframe {
5399 target_siginfo_t info;
5400 struct target_ucontext uc;
5401 unsigned int retcode[3];
5404 #define INSN_MOV_R30_R16 0x47fe0410
5405 #define INSN_LDI_R0 0x201f0000
5406 #define INSN_CALLSYS 0x00000083
5408 static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5409 abi_ulong frame_addr, target_sigset_t *set)
5411 int i, err = 0;
5413 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
5414 err |= __put_user(set->sig[0], &sc->sc_mask);
5415 err |= __put_user(env->pc, &sc->sc_pc);
5416 err |= __put_user(8, &sc->sc_ps);
5418 for (i = 0; i < 31; ++i) {
5419 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
5421 err |= __put_user(0, &sc->sc_regs[31]);
5423 for (i = 0; i < 31; ++i) {
5424 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
5426 err |= __put_user(0, &sc->sc_fpregs[31]);
5427 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5429 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5430 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5431 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5433 return err;
5436 static int restore_sigcontext(CPUAlphaState *env,
5437 struct target_sigcontext *sc)
5439 uint64_t fpcr;
5440 int i, err = 0;
5442 err |= __get_user(env->pc, &sc->sc_pc);
5444 for (i = 0; i < 31; ++i) {
5445 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5447 for (i = 0; i < 31; ++i) {
5448 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5451 err |= __get_user(fpcr, &sc->sc_fpcr);
5452 cpu_alpha_store_fpcr(env, fpcr);
5454 return err;
5457 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5458 CPUAlphaState *env,
5459 unsigned long framesize)
5461 abi_ulong sp = env->ir[IR_SP];
5463 /* This is the X/Open sanctioned signal stack switching. */
5464 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5465 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5467 return (sp - framesize) & -32;
5470 static void setup_frame(int sig, struct target_sigaction *ka,
5471 target_sigset_t *set, CPUAlphaState *env)
5473 abi_ulong frame_addr, r26;
5474 struct target_sigframe *frame;
5475 int err = 0;
5477 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5478 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5479 goto give_sigsegv;
5482 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5484 if (ka->sa_restorer) {
5485 r26 = ka->sa_restorer;
5486 } else {
5487 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5488 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5489 &frame->retcode[1]);
5490 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5491 /* imb() */
5492 r26 = frame_addr;
5495 unlock_user_struct(frame, frame_addr, 1);
5497 if (err) {
5498 give_sigsegv:
5499 if (sig == TARGET_SIGSEGV) {
5500 ka->_sa_handler = TARGET_SIG_DFL;
5502 force_sig(TARGET_SIGSEGV);
5505 env->ir[IR_RA] = r26;
5506 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5507 env->ir[IR_A0] = sig;
5508 env->ir[IR_A1] = 0;
5509 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5510 env->ir[IR_SP] = frame_addr;
5513 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5514 target_siginfo_t *info,
5515 target_sigset_t *set, CPUAlphaState *env)
5517 abi_ulong frame_addr, r26;
5518 struct target_rt_sigframe *frame;
5519 int i, err = 0;
5521 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5522 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5523 goto give_sigsegv;
5526 err |= copy_siginfo_to_user(&frame->info, info);
5528 err |= __put_user(0, &frame->uc.tuc_flags);
5529 err |= __put_user(0, &frame->uc.tuc_link);
5530 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5531 err |= __put_user(target_sigaltstack_used.ss_sp,
5532 &frame->uc.tuc_stack.ss_sp);
5533 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
5534 &frame->uc.tuc_stack.ss_flags);
5535 err |= __put_user(target_sigaltstack_used.ss_size,
5536 &frame->uc.tuc_stack.ss_size);
5537 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5538 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5539 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5542 if (ka->sa_restorer) {
5543 r26 = ka->sa_restorer;
5544 } else {
5545 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5546 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5547 &frame->retcode[1]);
5548 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5549 /* imb(); */
5550 r26 = frame_addr;
5553 if (err) {
5554 give_sigsegv:
5555 if (sig == TARGET_SIGSEGV) {
5556 ka->_sa_handler = TARGET_SIG_DFL;
5558 force_sig(TARGET_SIGSEGV);
5561 env->ir[IR_RA] = r26;
5562 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5563 env->ir[IR_A0] = sig;
5564 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5565 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5566 env->ir[IR_SP] = frame_addr;
5569 long do_sigreturn(CPUAlphaState *env)
5571 struct target_sigcontext *sc;
5572 abi_ulong sc_addr = env->ir[IR_A0];
5573 target_sigset_t target_set;
5574 sigset_t set;
5576 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5577 goto badframe;
5580 target_sigemptyset(&target_set);
5581 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5582 goto badframe;
5585 target_to_host_sigset_internal(&set, &target_set);
5586 sigprocmask(SIG_SETMASK, &set, NULL);
5588 if (restore_sigcontext(env, sc)) {
5589 goto badframe;
5591 unlock_user_struct(sc, sc_addr, 0);
5592 return env->ir[IR_V0];
5594 badframe:
5595 unlock_user_struct(sc, sc_addr, 0);
5596 force_sig(TARGET_SIGSEGV);
5599 long do_rt_sigreturn(CPUAlphaState *env)
5601 abi_ulong frame_addr = env->ir[IR_A0];
5602 struct target_rt_sigframe *frame;
5603 sigset_t set;
5605 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5606 goto badframe;
5608 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5609 sigprocmask(SIG_SETMASK, &set, NULL);
5611 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5612 goto badframe;
5614 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5615 uc.tuc_stack),
5616 0, env->ir[IR_SP]) == -EFAULT) {
5617 goto badframe;
5620 unlock_user_struct(frame, frame_addr, 0);
5621 return env->ir[IR_V0];
5624 badframe:
5625 unlock_user_struct(frame, frame_addr, 0);
5626 force_sig(TARGET_SIGSEGV);
5629 #else
5631 static void setup_frame(int sig, struct target_sigaction *ka,
5632 target_sigset_t *set, CPUArchState *env)
5634 fprintf(stderr, "setup_frame: not implemented\n");
5637 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5638 target_siginfo_t *info,
5639 target_sigset_t *set, CPUArchState *env)
5641 fprintf(stderr, "setup_rt_frame: not implemented\n");
5644 long do_sigreturn(CPUArchState *env)
5646 fprintf(stderr, "do_sigreturn: not implemented\n");
5647 return -TARGET_ENOSYS;
5650 long do_rt_sigreturn(CPUArchState *env)
5652 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5653 return -TARGET_ENOSYS;
5656 #endif
5658 void process_pending_signals(CPUArchState *cpu_env)
5660 CPUState *cpu = ENV_GET_CPU(cpu_env);
5661 int sig;
5662 abi_ulong handler;
5663 sigset_t set, old_set;
5664 target_sigset_t target_old_set;
5665 struct emulated_sigtable *k;
5666 struct target_sigaction *sa;
5667 struct sigqueue *q;
5668 TaskState *ts = cpu_env->opaque;
5670 if (!ts->signal_pending)
5671 return;
5673 /* FIXME: This is not threadsafe. */
5674 k = ts->sigtab;
5675 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5676 if (k->pending)
5677 goto handle_signal;
5678 k++;
5680 /* if no signal is pending, just return */
5681 ts->signal_pending = 0;
5682 return;
5684 handle_signal:
5685 #ifdef DEBUG_SIGNAL
5686 fprintf(stderr, "qemu: process signal %d\n", sig);
5687 #endif
5688 /* dequeue signal */
5689 q = k->first;
5690 k->first = q->next;
5691 if (!k->first)
5692 k->pending = 0;
5694 sig = gdb_handlesig(cpu, sig);
5695 if (!sig) {
5696 sa = NULL;
5697 handler = TARGET_SIG_IGN;
5698 } else {
5699 sa = &sigact_table[sig - 1];
5700 handler = sa->_sa_handler;
5703 if (handler == TARGET_SIG_DFL) {
5704 /* default handler : ignore some signal. The other are job control or fatal */
5705 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5706 kill(getpid(),SIGSTOP);
5707 } else if (sig != TARGET_SIGCHLD &&
5708 sig != TARGET_SIGURG &&
5709 sig != TARGET_SIGWINCH &&
5710 sig != TARGET_SIGCONT) {
5711 force_sig(sig);
5713 } else if (handler == TARGET_SIG_IGN) {
5714 /* ignore sig */
5715 } else if (handler == TARGET_SIG_ERR) {
5716 force_sig(sig);
5717 } else {
5718 /* compute the blocked signals during the handler execution */
5719 target_to_host_sigset(&set, &sa->sa_mask);
5720 /* SA_NODEFER indicates that the current signal should not be
5721 blocked during the handler */
5722 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5723 sigaddset(&set, target_to_host_signal(sig));
5725 /* block signals in the handler using Linux */
5726 sigprocmask(SIG_BLOCK, &set, &old_set);
5727 /* save the previous blocked signal state to restore it at the
5728 end of the signal execution (see do_sigreturn) */
5729 host_to_target_sigset_internal(&target_old_set, &old_set);
5731 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5732 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5734 CPUX86State *env = cpu_env;
5735 if (env->eflags & VM_MASK)
5736 save_v86_state(env);
5738 #endif
5739 /* prepare the stack frame of the virtual CPU */
5740 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5741 /* These targets do not have traditional signals. */
5742 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5743 #else
5744 if (sa->sa_flags & TARGET_SA_SIGINFO)
5745 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5746 else
5747 setup_frame(sig, sa, &target_old_set, cpu_env);
5748 #endif
5749 if (sa->sa_flags & TARGET_SA_RESETHAND)
5750 sa->_sa_handler = TARGET_SIG_DFL;
5752 if (q != &k->info)
5753 free_sigqueue(cpu_env, q);