virtio-balloon: don't hardcode config size value
[qemu/ar7.git] / linux-user / signal.c
blob01d7c393df1dffe996d321090d17a709f48da507
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 sigaction(host_sig, &act, NULL);
425 /* For some reason raise(host_sig) doesn't send the signal when
426 * statically linked on x86-64. */
427 kill(getpid(), host_sig);
429 /* Make sure the signal isn't masked (just reuse the mask inside
430 of act) */
431 sigdelset(&act.sa_mask, host_sig);
432 sigsuspend(&act.sa_mask);
434 /* unreachable */
435 abort();
438 /* queue a signal so that it will be send to the virtual CPU as soon
439 as possible */
440 int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
442 TaskState *ts = env->opaque;
443 struct emulated_sigtable *k;
444 struct sigqueue *q, **pq;
445 abi_ulong handler;
446 int queue;
448 #if defined(DEBUG_SIGNAL)
449 fprintf(stderr, "queue_signal: sig=%d\n",
450 sig);
451 #endif
452 k = &ts->sigtab[sig - 1];
453 queue = gdb_queuesig ();
454 handler = sigact_table[sig - 1]._sa_handler;
455 if (!queue && handler == TARGET_SIG_DFL) {
456 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
457 kill(getpid(),SIGSTOP);
458 return 0;
459 } else
460 /* default handler : ignore some signal. The other are fatal */
461 if (sig != TARGET_SIGCHLD &&
462 sig != TARGET_SIGURG &&
463 sig != TARGET_SIGWINCH &&
464 sig != TARGET_SIGCONT) {
465 force_sig(sig);
466 } else {
467 return 0; /* indicate ignored */
469 } else if (!queue && handler == TARGET_SIG_IGN) {
470 /* ignore signal */
471 return 0;
472 } else if (!queue && handler == TARGET_SIG_ERR) {
473 force_sig(sig);
474 } else {
475 pq = &k->first;
476 if (sig < TARGET_SIGRTMIN) {
477 /* if non real time signal, we queue exactly one signal */
478 if (!k->pending)
479 q = &k->info;
480 else
481 return 0;
482 } else {
483 if (!k->pending) {
484 /* first signal */
485 q = &k->info;
486 } else {
487 q = alloc_sigqueue(env);
488 if (!q)
489 return -EAGAIN;
490 while (*pq != NULL)
491 pq = &(*pq)->next;
494 *pq = q;
495 q->info = *info;
496 q->next = NULL;
497 k->pending = 1;
498 /* signal that a new signal is pending */
499 ts->signal_pending = 1;
500 return 1; /* indicates that the signal was queued */
504 static void host_signal_handler(int host_signum, siginfo_t *info,
505 void *puc)
507 CPUArchState *env = thread_cpu->env_ptr;
508 int sig;
509 target_siginfo_t tinfo;
511 /* the CPU emulator uses some host signals to detect exceptions,
512 we forward to it some signals */
513 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
514 && info->si_code > 0) {
515 if (cpu_signal_handler(host_signum, info, puc))
516 return;
519 /* get target signal number */
520 sig = host_to_target_signal(host_signum);
521 if (sig < 1 || sig > TARGET_NSIG)
522 return;
523 #if defined(DEBUG_SIGNAL)
524 fprintf(stderr, "qemu: got signal %d\n", sig);
525 #endif
526 host_to_target_siginfo_noswap(&tinfo, info);
527 if (queue_signal(env, sig, &tinfo) == 1) {
528 /* interrupt the virtual CPU as soon as possible */
529 cpu_exit(thread_cpu);
533 /* do_sigaltstack() returns target values and errnos. */
534 /* compare linux/kernel/signal.c:do_sigaltstack() */
535 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
537 int ret;
538 struct target_sigaltstack oss;
540 /* XXX: test errors */
541 if(uoss_addr)
543 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
544 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
545 __put_user(sas_ss_flags(sp), &oss.ss_flags);
548 if(uss_addr)
550 struct target_sigaltstack *uss;
551 struct target_sigaltstack ss;
553 ret = -TARGET_EFAULT;
554 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
555 || __get_user(ss.ss_sp, &uss->ss_sp)
556 || __get_user(ss.ss_size, &uss->ss_size)
557 || __get_user(ss.ss_flags, &uss->ss_flags))
558 goto out;
559 unlock_user_struct(uss, uss_addr, 0);
561 ret = -TARGET_EPERM;
562 if (on_sig_stack(sp))
563 goto out;
565 ret = -TARGET_EINVAL;
566 if (ss.ss_flags != TARGET_SS_DISABLE
567 && ss.ss_flags != TARGET_SS_ONSTACK
568 && ss.ss_flags != 0)
569 goto out;
571 if (ss.ss_flags == TARGET_SS_DISABLE) {
572 ss.ss_size = 0;
573 ss.ss_sp = 0;
574 } else {
575 ret = -TARGET_ENOMEM;
576 if (ss.ss_size < MINSIGSTKSZ)
577 goto out;
580 target_sigaltstack_used.ss_sp = ss.ss_sp;
581 target_sigaltstack_used.ss_size = ss.ss_size;
584 if (uoss_addr) {
585 ret = -TARGET_EFAULT;
586 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
587 goto out;
590 ret = 0;
591 out:
592 return ret;
595 /* do_sigaction() return host values and errnos */
596 int do_sigaction(int sig, const struct target_sigaction *act,
597 struct target_sigaction *oact)
599 struct target_sigaction *k;
600 struct sigaction act1;
601 int host_sig;
602 int ret = 0;
604 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
605 return -EINVAL;
606 k = &sigact_table[sig - 1];
607 #if defined(DEBUG_SIGNAL)
608 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
609 sig, act, oact);
610 #endif
611 if (oact) {
612 __put_user(k->_sa_handler, &oact->_sa_handler);
613 __put_user(k->sa_flags, &oact->sa_flags);
614 #if !defined(TARGET_MIPS)
615 __put_user(k->sa_restorer, &oact->sa_restorer);
616 #endif
617 /* Not swapped. */
618 oact->sa_mask = k->sa_mask;
620 if (act) {
621 /* FIXME: This is not threadsafe. */
622 __get_user(k->_sa_handler, &act->_sa_handler);
623 __get_user(k->sa_flags, &act->sa_flags);
624 #if !defined(TARGET_MIPS)
625 __get_user(k->sa_restorer, &act->sa_restorer);
626 #endif
627 /* To be swapped in target_to_host_sigset. */
628 k->sa_mask = act->sa_mask;
630 /* we update the host linux signal state */
631 host_sig = target_to_host_signal(sig);
632 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
633 sigfillset(&act1.sa_mask);
634 act1.sa_flags = SA_SIGINFO;
635 if (k->sa_flags & TARGET_SA_RESTART)
636 act1.sa_flags |= SA_RESTART;
637 /* NOTE: it is important to update the host kernel signal
638 ignore state to avoid getting unexpected interrupted
639 syscalls */
640 if (k->_sa_handler == TARGET_SIG_IGN) {
641 act1.sa_sigaction = (void *)SIG_IGN;
642 } else if (k->_sa_handler == TARGET_SIG_DFL) {
643 if (fatal_signal (sig))
644 act1.sa_sigaction = host_signal_handler;
645 else
646 act1.sa_sigaction = (void *)SIG_DFL;
647 } else {
648 act1.sa_sigaction = host_signal_handler;
650 ret = sigaction(host_sig, &act1, NULL);
653 return ret;
656 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
657 const target_siginfo_t *info)
659 tswap_siginfo(tinfo, info);
660 return 0;
663 static inline int current_exec_domain_sig(int sig)
665 return /* current->exec_domain && current->exec_domain->signal_invmap
666 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
669 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
671 /* from the Linux kernel */
673 struct target_fpreg {
674 uint16_t significand[4];
675 uint16_t exponent;
678 struct target_fpxreg {
679 uint16_t significand[4];
680 uint16_t exponent;
681 uint16_t padding[3];
684 struct target_xmmreg {
685 abi_ulong element[4];
688 struct target_fpstate {
689 /* Regular FPU environment */
690 abi_ulong cw;
691 abi_ulong sw;
692 abi_ulong tag;
693 abi_ulong ipoff;
694 abi_ulong cssel;
695 abi_ulong dataoff;
696 abi_ulong datasel;
697 struct target_fpreg _st[8];
698 uint16_t status;
699 uint16_t magic; /* 0xffff = regular FPU data only */
701 /* FXSR FPU environment */
702 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
703 abi_ulong mxcsr;
704 abi_ulong reserved;
705 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
706 struct target_xmmreg _xmm[8];
707 abi_ulong padding[56];
710 #define X86_FXSR_MAGIC 0x0000
712 struct target_sigcontext {
713 uint16_t gs, __gsh;
714 uint16_t fs, __fsh;
715 uint16_t es, __esh;
716 uint16_t ds, __dsh;
717 abi_ulong edi;
718 abi_ulong esi;
719 abi_ulong ebp;
720 abi_ulong esp;
721 abi_ulong ebx;
722 abi_ulong edx;
723 abi_ulong ecx;
724 abi_ulong eax;
725 abi_ulong trapno;
726 abi_ulong err;
727 abi_ulong eip;
728 uint16_t cs, __csh;
729 abi_ulong eflags;
730 abi_ulong esp_at_signal;
731 uint16_t ss, __ssh;
732 abi_ulong fpstate; /* pointer */
733 abi_ulong oldmask;
734 abi_ulong cr2;
737 struct target_ucontext {
738 abi_ulong tuc_flags;
739 abi_ulong tuc_link;
740 target_stack_t tuc_stack;
741 struct target_sigcontext tuc_mcontext;
742 target_sigset_t tuc_sigmask; /* mask last for extensibility */
745 struct sigframe
747 abi_ulong pretcode;
748 int sig;
749 struct target_sigcontext sc;
750 struct target_fpstate fpstate;
751 abi_ulong extramask[TARGET_NSIG_WORDS-1];
752 char retcode[8];
755 struct rt_sigframe
757 abi_ulong pretcode;
758 int sig;
759 abi_ulong pinfo;
760 abi_ulong puc;
761 struct target_siginfo info;
762 struct target_ucontext uc;
763 struct target_fpstate fpstate;
764 char retcode[8];
768 * Set up a signal frame.
771 /* XXX: save x87 state */
772 static int
773 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
774 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
776 int err = 0;
777 uint16_t magic;
779 /* already locked in setup_frame() */
780 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
781 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
782 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
783 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
784 err |= __put_user(env->regs[R_EDI], &sc->edi);
785 err |= __put_user(env->regs[R_ESI], &sc->esi);
786 err |= __put_user(env->regs[R_EBP], &sc->ebp);
787 err |= __put_user(env->regs[R_ESP], &sc->esp);
788 err |= __put_user(env->regs[R_EBX], &sc->ebx);
789 err |= __put_user(env->regs[R_EDX], &sc->edx);
790 err |= __put_user(env->regs[R_ECX], &sc->ecx);
791 err |= __put_user(env->regs[R_EAX], &sc->eax);
792 err |= __put_user(env->exception_index, &sc->trapno);
793 err |= __put_user(env->error_code, &sc->err);
794 err |= __put_user(env->eip, &sc->eip);
795 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
796 err |= __put_user(env->eflags, &sc->eflags);
797 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
798 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
800 cpu_x86_fsave(env, fpstate_addr, 1);
801 fpstate->status = fpstate->sw;
802 magic = 0xffff;
803 err |= __put_user(magic, &fpstate->magic);
804 err |= __put_user(fpstate_addr, &sc->fpstate);
806 /* non-iBCS2 extensions.. */
807 err |= __put_user(mask, &sc->oldmask);
808 err |= __put_user(env->cr[2], &sc->cr2);
809 return err;
813 * Determine which stack to use..
816 static inline abi_ulong
817 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
819 unsigned long esp;
821 /* Default to using normal stack */
822 esp = env->regs[R_ESP];
823 /* This is the X/Open sanctioned signal stack switching. */
824 if (ka->sa_flags & TARGET_SA_ONSTACK) {
825 if (sas_ss_flags(esp) == 0)
826 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
829 /* This is the legacy signal stack switching. */
830 else
831 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
832 !(ka->sa_flags & TARGET_SA_RESTORER) &&
833 ka->sa_restorer) {
834 esp = (unsigned long) ka->sa_restorer;
836 return (esp - frame_size) & -8ul;
839 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
840 static void setup_frame(int sig, struct target_sigaction *ka,
841 target_sigset_t *set, CPUX86State *env)
843 abi_ulong frame_addr;
844 struct sigframe *frame;
845 int i, err = 0;
847 frame_addr = get_sigframe(ka, env, sizeof(*frame));
849 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
850 goto give_sigsegv;
852 err |= __put_user(current_exec_domain_sig(sig),
853 &frame->sig);
854 if (err)
855 goto give_sigsegv;
857 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
858 frame_addr + offsetof(struct sigframe, fpstate));
859 if (err)
860 goto give_sigsegv;
862 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
863 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
864 goto give_sigsegv;
867 /* Set up to return from userspace. If provided, use a stub
868 already in userspace. */
869 if (ka->sa_flags & TARGET_SA_RESTORER) {
870 err |= __put_user(ka->sa_restorer, &frame->pretcode);
871 } else {
872 uint16_t val16;
873 abi_ulong retcode_addr;
874 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
875 err |= __put_user(retcode_addr, &frame->pretcode);
876 /* This is popl %eax ; movl $,%eax ; int $0x80 */
877 val16 = 0xb858;
878 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
879 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
880 val16 = 0x80cd;
881 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
884 if (err)
885 goto give_sigsegv;
887 /* Set up registers for signal handler */
888 env->regs[R_ESP] = frame_addr;
889 env->eip = ka->_sa_handler;
891 cpu_x86_load_seg(env, R_DS, __USER_DS);
892 cpu_x86_load_seg(env, R_ES, __USER_DS);
893 cpu_x86_load_seg(env, R_SS, __USER_DS);
894 cpu_x86_load_seg(env, R_CS, __USER_CS);
895 env->eflags &= ~TF_MASK;
897 unlock_user_struct(frame, frame_addr, 1);
899 return;
901 give_sigsegv:
902 unlock_user_struct(frame, frame_addr, 1);
903 if (sig == TARGET_SIGSEGV)
904 ka->_sa_handler = TARGET_SIG_DFL;
905 force_sig(TARGET_SIGSEGV /* , current */);
908 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
909 static void setup_rt_frame(int sig, struct target_sigaction *ka,
910 target_siginfo_t *info,
911 target_sigset_t *set, CPUX86State *env)
913 abi_ulong frame_addr, addr;
914 struct rt_sigframe *frame;
915 int i, err = 0;
917 frame_addr = get_sigframe(ka, env, sizeof(*frame));
919 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
920 goto give_sigsegv;
922 err |= __put_user(current_exec_domain_sig(sig),
923 &frame->sig);
924 addr = frame_addr + offsetof(struct rt_sigframe, info);
925 err |= __put_user(addr, &frame->pinfo);
926 addr = frame_addr + offsetof(struct rt_sigframe, uc);
927 err |= __put_user(addr, &frame->puc);
928 err |= copy_siginfo_to_user(&frame->info, info);
929 if (err)
930 goto give_sigsegv;
932 /* Create the ucontext. */
933 err |= __put_user(0, &frame->uc.tuc_flags);
934 err |= __put_user(0, &frame->uc.tuc_link);
935 err |= __put_user(target_sigaltstack_used.ss_sp,
936 &frame->uc.tuc_stack.ss_sp);
937 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
938 &frame->uc.tuc_stack.ss_flags);
939 err |= __put_user(target_sigaltstack_used.ss_size,
940 &frame->uc.tuc_stack.ss_size);
941 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
942 env, set->sig[0],
943 frame_addr + offsetof(struct rt_sigframe, fpstate));
944 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
945 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
946 goto give_sigsegv;
949 /* Set up to return from userspace. If provided, use a stub
950 already in userspace. */
951 if (ka->sa_flags & TARGET_SA_RESTORER) {
952 err |= __put_user(ka->sa_restorer, &frame->pretcode);
953 } else {
954 uint16_t val16;
955 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
956 err |= __put_user(addr, &frame->pretcode);
957 /* This is movl $,%eax ; int $0x80 */
958 err |= __put_user(0xb8, (char *)(frame->retcode+0));
959 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
960 val16 = 0x80cd;
961 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
964 if (err)
965 goto give_sigsegv;
967 /* Set up registers for signal handler */
968 env->regs[R_ESP] = frame_addr;
969 env->eip = ka->_sa_handler;
971 cpu_x86_load_seg(env, R_DS, __USER_DS);
972 cpu_x86_load_seg(env, R_ES, __USER_DS);
973 cpu_x86_load_seg(env, R_SS, __USER_DS);
974 cpu_x86_load_seg(env, R_CS, __USER_CS);
975 env->eflags &= ~TF_MASK;
977 unlock_user_struct(frame, frame_addr, 1);
979 return;
981 give_sigsegv:
982 unlock_user_struct(frame, frame_addr, 1);
983 if (sig == TARGET_SIGSEGV)
984 ka->_sa_handler = TARGET_SIG_DFL;
985 force_sig(TARGET_SIGSEGV /* , current */);
988 static int
989 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
991 unsigned int err = 0;
992 abi_ulong fpstate_addr;
993 unsigned int tmpflags;
995 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
996 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
997 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
998 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
1000 env->regs[R_EDI] = tswapl(sc->edi);
1001 env->regs[R_ESI] = tswapl(sc->esi);
1002 env->regs[R_EBP] = tswapl(sc->ebp);
1003 env->regs[R_ESP] = tswapl(sc->esp);
1004 env->regs[R_EBX] = tswapl(sc->ebx);
1005 env->regs[R_EDX] = tswapl(sc->edx);
1006 env->regs[R_ECX] = tswapl(sc->ecx);
1007 env->eip = tswapl(sc->eip);
1009 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
1010 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
1012 tmpflags = tswapl(sc->eflags);
1013 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1014 // regs->orig_eax = -1; /* disable syscall checks */
1016 fpstate_addr = tswapl(sc->fpstate);
1017 if (fpstate_addr != 0) {
1018 if (!access_ok(VERIFY_READ, fpstate_addr,
1019 sizeof(struct target_fpstate)))
1020 goto badframe;
1021 cpu_x86_frstor(env, fpstate_addr, 1);
1024 *peax = tswapl(sc->eax);
1025 return err;
1026 badframe:
1027 return 1;
1030 long do_sigreturn(CPUX86State *env)
1032 struct sigframe *frame;
1033 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1034 target_sigset_t target_set;
1035 sigset_t set;
1036 int eax, i;
1038 #if defined(DEBUG_SIGNAL)
1039 fprintf(stderr, "do_sigreturn\n");
1040 #endif
1041 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1042 goto badframe;
1043 /* set blocked signals */
1044 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1045 goto badframe;
1046 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1047 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1048 goto badframe;
1051 target_to_host_sigset_internal(&set, &target_set);
1052 sigprocmask(SIG_SETMASK, &set, NULL);
1054 /* restore registers */
1055 if (restore_sigcontext(env, &frame->sc, &eax))
1056 goto badframe;
1057 unlock_user_struct(frame, frame_addr, 0);
1058 return eax;
1060 badframe:
1061 unlock_user_struct(frame, frame_addr, 0);
1062 force_sig(TARGET_SIGSEGV);
1063 return 0;
1066 long do_rt_sigreturn(CPUX86State *env)
1068 abi_ulong frame_addr;
1069 struct rt_sigframe *frame;
1070 sigset_t set;
1071 int eax;
1073 frame_addr = env->regs[R_ESP] - 4;
1074 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1075 goto badframe;
1076 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1077 sigprocmask(SIG_SETMASK, &set, NULL);
1079 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1080 goto badframe;
1082 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1083 get_sp_from_cpustate(env)) == -EFAULT)
1084 goto badframe;
1086 unlock_user_struct(frame, frame_addr, 0);
1087 return eax;
1089 badframe:
1090 unlock_user_struct(frame, frame_addr, 0);
1091 force_sig(TARGET_SIGSEGV);
1092 return 0;
1095 #elif defined(TARGET_AARCH64)
1097 struct target_sigcontext {
1098 uint64_t fault_address;
1099 /* AArch64 registers */
1100 uint64_t regs[31];
1101 uint64_t sp;
1102 uint64_t pc;
1103 uint64_t pstate;
1104 /* 4K reserved for FP/SIMD state and future expansion */
1105 char __reserved[4096] __attribute__((__aligned__(16)));
1108 struct target_ucontext {
1109 abi_ulong tuc_flags;
1110 abi_ulong tuc_link;
1111 target_stack_t tuc_stack;
1112 target_sigset_t tuc_sigmask;
1113 /* glibc uses a 1024-bit sigset_t */
1114 char __unused[1024 / 8 - sizeof(target_sigset_t)];
1115 /* last for future expansion */
1116 struct target_sigcontext tuc_mcontext;
1120 * Header to be used at the beginning of structures extending the user
1121 * context. Such structures must be placed after the rt_sigframe on the stack
1122 * and be 16-byte aligned. The last structure must be a dummy one with the
1123 * magic and size set to 0.
1125 struct target_aarch64_ctx {
1126 uint32_t magic;
1127 uint32_t size;
1130 #define TARGET_FPSIMD_MAGIC 0x46508001
1132 struct target_fpsimd_context {
1133 struct target_aarch64_ctx head;
1134 uint32_t fpsr;
1135 uint32_t fpcr;
1136 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
1140 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1141 * user space as it will change with the addition of new context. User space
1142 * should check the magic/size information.
1144 struct target_aux_context {
1145 struct target_fpsimd_context fpsimd;
1146 /* additional context to be added before "end" */
1147 struct target_aarch64_ctx end;
1150 struct target_rt_sigframe {
1151 struct target_siginfo info;
1152 struct target_ucontext uc;
1153 uint64_t fp;
1154 uint64_t lr;
1155 uint32_t tramp[2];
1158 static int target_setup_sigframe(struct target_rt_sigframe *sf,
1159 CPUARMState *env, target_sigset_t *set)
1161 int i;
1162 struct target_aux_context *aux =
1163 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1165 /* set up the stack frame for unwinding */
1166 __put_user(env->xregs[29], &sf->fp);
1167 __put_user(env->xregs[30], &sf->lr);
1169 for (i = 0; i < 31; i++) {
1170 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1172 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1173 __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
1174 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
1176 __put_user(/*current->thread.fault_address*/ 0,
1177 &sf->uc.tuc_mcontext.fault_address);
1179 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
1180 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
1183 for (i = 0; i < 32; i++) {
1184 #ifdef TARGET_WORDS_BIGENDIAN
1185 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1186 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1187 #else
1188 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1189 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1190 #endif
1192 __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
1193 __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
1194 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
1195 __put_user(sizeof(struct target_fpsimd_context),
1196 &aux->fpsimd.head.size);
1198 /* set the "end" magic */
1199 __put_user(0, &aux->end.magic);
1200 __put_user(0, &aux->end.size);
1202 return 0;
1205 static int target_restore_sigframe(CPUARMState *env,
1206 struct target_rt_sigframe *sf)
1208 sigset_t set;
1209 int i;
1210 struct target_aux_context *aux =
1211 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1212 uint32_t magic, size, fpsr, fpcr;
1213 uint64_t pstate;
1215 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1216 sigprocmask(SIG_SETMASK, &set, NULL);
1218 for (i = 0; i < 31; i++) {
1219 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1222 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1223 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
1224 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
1225 pstate_write(env, pstate);
1227 __get_user(magic, &aux->fpsimd.head.magic);
1228 __get_user(size, &aux->fpsimd.head.size);
1230 if (magic != TARGET_FPSIMD_MAGIC
1231 || size != sizeof(struct target_fpsimd_context)) {
1232 return 1;
1235 for (i = 0; i < 32 * 2; i++) {
1236 __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]);
1238 __get_user(fpsr, &aux->fpsimd.fpsr);
1239 vfp_set_fpsr(env, fpsr);
1240 __get_user(fpcr, &aux->fpsimd.fpcr);
1241 vfp_set_fpcr(env, fpcr);
1243 return 0;
1246 static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1248 abi_ulong sp;
1250 sp = env->xregs[31];
1253 * This is the X/Open sanctioned signal stack switching.
1255 if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
1256 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1259 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1261 return sp;
1264 static void target_setup_frame(int usig, struct target_sigaction *ka,
1265 target_siginfo_t *info, target_sigset_t *set,
1266 CPUARMState *env)
1268 struct target_rt_sigframe *frame;
1269 abi_ulong frame_addr;
1271 frame_addr = get_sigframe(ka, env);
1272 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1273 goto give_sigsegv;
1276 __put_user(0, &frame->uc.tuc_flags);
1277 __put_user(0, &frame->uc.tuc_link);
1279 __put_user(target_sigaltstack_used.ss_sp,
1280 &frame->uc.tuc_stack.ss_sp);
1281 __put_user(sas_ss_flags(env->xregs[31]),
1282 &frame->uc.tuc_stack.ss_flags);
1283 __put_user(target_sigaltstack_used.ss_size,
1284 &frame->uc.tuc_stack.ss_size);
1285 target_setup_sigframe(frame, env, set);
1286 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1287 __put_user(0xd2801168, &frame->tramp[0]);
1288 __put_user(0xd4000001, &frame->tramp[1]);
1289 env->xregs[0] = usig;
1290 env->xregs[31] = frame_addr;
1291 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
1292 env->pc = ka->_sa_handler;
1293 env->xregs[30] = env->xregs[31] +
1294 offsetof(struct target_rt_sigframe, tramp);
1295 if (info) {
1296 if (copy_siginfo_to_user(&frame->info, info)) {
1297 goto give_sigsegv;
1299 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1300 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1303 unlock_user_struct(frame, frame_addr, 1);
1304 return;
1306 give_sigsegv:
1307 unlock_user_struct(frame, frame_addr, 1);
1308 force_sig(TARGET_SIGSEGV);
1311 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1312 target_siginfo_t *info, target_sigset_t *set,
1313 CPUARMState *env)
1315 target_setup_frame(sig, ka, info, set, env);
1318 static void setup_frame(int sig, struct target_sigaction *ka,
1319 target_sigset_t *set, CPUARMState *env)
1321 target_setup_frame(sig, ka, 0, set, env);
1324 long do_rt_sigreturn(CPUARMState *env)
1326 struct target_rt_sigframe *frame;
1327 abi_ulong frame_addr = env->xregs[31];
1329 if (frame_addr & 15) {
1330 goto badframe;
1333 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1334 goto badframe;
1337 if (target_restore_sigframe(env, frame)) {
1338 goto badframe;
1341 if (do_sigaltstack(frame_addr +
1342 offsetof(struct target_rt_sigframe, uc.tuc_stack),
1343 0, get_sp_from_cpustate(env)) == -EFAULT) {
1344 goto badframe;
1347 unlock_user_struct(frame, frame_addr, 0);
1348 return env->xregs[0];
1350 badframe:
1351 unlock_user_struct(frame, frame_addr, 0);
1352 force_sig(TARGET_SIGSEGV);
1353 return 0;
1356 long do_sigreturn(CPUARMState *env)
1358 return do_rt_sigreturn(env);
1361 #elif defined(TARGET_ARM)
1363 struct target_sigcontext {
1364 abi_ulong trap_no;
1365 abi_ulong error_code;
1366 abi_ulong oldmask;
1367 abi_ulong arm_r0;
1368 abi_ulong arm_r1;
1369 abi_ulong arm_r2;
1370 abi_ulong arm_r3;
1371 abi_ulong arm_r4;
1372 abi_ulong arm_r5;
1373 abi_ulong arm_r6;
1374 abi_ulong arm_r7;
1375 abi_ulong arm_r8;
1376 abi_ulong arm_r9;
1377 abi_ulong arm_r10;
1378 abi_ulong arm_fp;
1379 abi_ulong arm_ip;
1380 abi_ulong arm_sp;
1381 abi_ulong arm_lr;
1382 abi_ulong arm_pc;
1383 abi_ulong arm_cpsr;
1384 abi_ulong fault_address;
1387 struct target_ucontext_v1 {
1388 abi_ulong tuc_flags;
1389 abi_ulong tuc_link;
1390 target_stack_t tuc_stack;
1391 struct target_sigcontext tuc_mcontext;
1392 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1395 struct target_ucontext_v2 {
1396 abi_ulong tuc_flags;
1397 abi_ulong tuc_link;
1398 target_stack_t tuc_stack;
1399 struct target_sigcontext tuc_mcontext;
1400 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1401 char __unused[128 - sizeof(target_sigset_t)];
1402 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1405 struct target_user_vfp {
1406 uint64_t fpregs[32];
1407 abi_ulong fpscr;
1410 struct target_user_vfp_exc {
1411 abi_ulong fpexc;
1412 abi_ulong fpinst;
1413 abi_ulong fpinst2;
1416 struct target_vfp_sigframe {
1417 abi_ulong magic;
1418 abi_ulong size;
1419 struct target_user_vfp ufp;
1420 struct target_user_vfp_exc ufp_exc;
1421 } __attribute__((__aligned__(8)));
1423 struct target_iwmmxt_sigframe {
1424 abi_ulong magic;
1425 abi_ulong size;
1426 uint64_t regs[16];
1427 /* Note that not all the coprocessor control registers are stored here */
1428 uint32_t wcssf;
1429 uint32_t wcasf;
1430 uint32_t wcgr0;
1431 uint32_t wcgr1;
1432 uint32_t wcgr2;
1433 uint32_t wcgr3;
1434 } __attribute__((__aligned__(8)));
1436 #define TARGET_VFP_MAGIC 0x56465001
1437 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1439 struct sigframe_v1
1441 struct target_sigcontext sc;
1442 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1443 abi_ulong retcode;
1446 struct sigframe_v2
1448 struct target_ucontext_v2 uc;
1449 abi_ulong retcode;
1452 struct rt_sigframe_v1
1454 abi_ulong pinfo;
1455 abi_ulong puc;
1456 struct target_siginfo info;
1457 struct target_ucontext_v1 uc;
1458 abi_ulong retcode;
1461 struct rt_sigframe_v2
1463 struct target_siginfo info;
1464 struct target_ucontext_v2 uc;
1465 abi_ulong retcode;
1468 #define TARGET_CONFIG_CPU_32 1
1471 * For ARM syscalls, we encode the syscall number into the instruction.
1473 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1474 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1477 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1478 * need two 16-bit instructions.
1480 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1481 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1483 static const abi_ulong retcodes[4] = {
1484 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1485 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1489 #define __get_user_error(x,p,e) __get_user(x, p)
1491 static inline int valid_user_regs(CPUARMState *regs)
1493 return 1;
1496 static void
1497 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1498 CPUARMState *env, abi_ulong mask)
1500 __put_user(env->regs[0], &sc->arm_r0);
1501 __put_user(env->regs[1], &sc->arm_r1);
1502 __put_user(env->regs[2], &sc->arm_r2);
1503 __put_user(env->regs[3], &sc->arm_r3);
1504 __put_user(env->regs[4], &sc->arm_r4);
1505 __put_user(env->regs[5], &sc->arm_r5);
1506 __put_user(env->regs[6], &sc->arm_r6);
1507 __put_user(env->regs[7], &sc->arm_r7);
1508 __put_user(env->regs[8], &sc->arm_r8);
1509 __put_user(env->regs[9], &sc->arm_r9);
1510 __put_user(env->regs[10], &sc->arm_r10);
1511 __put_user(env->regs[11], &sc->arm_fp);
1512 __put_user(env->regs[12], &sc->arm_ip);
1513 __put_user(env->regs[13], &sc->arm_sp);
1514 __put_user(env->regs[14], &sc->arm_lr);
1515 __put_user(env->regs[15], &sc->arm_pc);
1516 #ifdef TARGET_CONFIG_CPU_32
1517 __put_user(cpsr_read(env), &sc->arm_cpsr);
1518 #endif
1520 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1521 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1522 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1523 __put_user(mask, &sc->oldmask);
1526 static inline abi_ulong
1527 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1529 unsigned long sp = regs->regs[13];
1532 * This is the X/Open sanctioned signal stack switching.
1534 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1535 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1537 * ATPCS B01 mandates 8-byte alignment
1539 return (sp - framesize) & ~7;
1542 static int
1543 setup_return(CPUARMState *env, struct target_sigaction *ka,
1544 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1546 abi_ulong handler = ka->_sa_handler;
1547 abi_ulong retcode;
1548 int thumb = handler & 1;
1549 uint32_t cpsr = cpsr_read(env);
1551 cpsr &= ~CPSR_IT;
1552 if (thumb) {
1553 cpsr |= CPSR_T;
1554 } else {
1555 cpsr &= ~CPSR_T;
1558 if (ka->sa_flags & TARGET_SA_RESTORER) {
1559 retcode = ka->sa_restorer;
1560 } else {
1561 unsigned int idx = thumb;
1563 if (ka->sa_flags & TARGET_SA_SIGINFO)
1564 idx += 2;
1566 if (__put_user(retcodes[idx], rc))
1567 return 1;
1569 retcode = rc_addr + thumb;
1572 env->regs[0] = usig;
1573 env->regs[13] = frame_addr;
1574 env->regs[14] = retcode;
1575 env->regs[15] = handler & (thumb ? ~1 : ~3);
1576 cpsr_write(env, cpsr, 0xffffffff);
1578 return 0;
1581 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1583 int i;
1584 struct target_vfp_sigframe *vfpframe;
1585 vfpframe = (struct target_vfp_sigframe *)regspace;
1586 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1587 __put_user(sizeof(*vfpframe), &vfpframe->size);
1588 for (i = 0; i < 32; i++) {
1589 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1591 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1592 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1593 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1594 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1595 return (abi_ulong*)(vfpframe+1);
1598 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1599 CPUARMState *env)
1601 int i;
1602 struct target_iwmmxt_sigframe *iwmmxtframe;
1603 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1604 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1605 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1606 for (i = 0; i < 16; i++) {
1607 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1609 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1610 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1611 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1612 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1613 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1614 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1615 return (abi_ulong*)(iwmmxtframe+1);
1618 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1619 target_sigset_t *set, CPUARMState *env)
1621 struct target_sigaltstack stack;
1622 int i;
1623 abi_ulong *regspace;
1625 /* Clear all the bits of the ucontext we don't use. */
1626 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1628 memset(&stack, 0, sizeof(stack));
1629 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1630 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1631 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1632 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1634 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1635 /* Save coprocessor signal frame. */
1636 regspace = uc->tuc_regspace;
1637 if (arm_feature(env, ARM_FEATURE_VFP)) {
1638 regspace = setup_sigframe_v2_vfp(regspace, env);
1640 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1641 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1644 /* Write terminating magic word */
1645 __put_user(0, regspace);
1647 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1648 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1652 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1653 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1654 target_sigset_t *set, CPUARMState *regs)
1656 struct sigframe_v1 *frame;
1657 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1658 int i;
1660 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1661 return;
1663 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1665 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1666 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1667 goto end;
1670 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1671 frame_addr + offsetof(struct sigframe_v1, retcode));
1673 end:
1674 unlock_user_struct(frame, frame_addr, 1);
1677 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1678 target_sigset_t *set, CPUARMState *regs)
1680 struct sigframe_v2 *frame;
1681 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1683 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1684 return;
1686 setup_sigframe_v2(&frame->uc, set, regs);
1688 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1689 frame_addr + offsetof(struct sigframe_v2, retcode));
1691 unlock_user_struct(frame, frame_addr, 1);
1694 static void setup_frame(int usig, struct target_sigaction *ka,
1695 target_sigset_t *set, CPUARMState *regs)
1697 if (get_osversion() >= 0x020612) {
1698 setup_frame_v2(usig, ka, set, regs);
1699 } else {
1700 setup_frame_v1(usig, ka, set, regs);
1704 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1705 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1706 target_siginfo_t *info,
1707 target_sigset_t *set, CPUARMState *env)
1709 struct rt_sigframe_v1 *frame;
1710 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1711 struct target_sigaltstack stack;
1712 int i;
1713 abi_ulong info_addr, uc_addr;
1715 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1716 return /* 1 */;
1718 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1719 __put_user(info_addr, &frame->pinfo);
1720 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1721 __put_user(uc_addr, &frame->puc);
1722 copy_siginfo_to_user(&frame->info, info);
1724 /* Clear all the bits of the ucontext we don't use. */
1725 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1727 memset(&stack, 0, sizeof(stack));
1728 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1729 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1730 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1731 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1733 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1734 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1735 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1736 goto end;
1739 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1740 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1742 env->regs[1] = info_addr;
1743 env->regs[2] = uc_addr;
1745 end:
1746 unlock_user_struct(frame, frame_addr, 1);
1749 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1750 target_siginfo_t *info,
1751 target_sigset_t *set, CPUARMState *env)
1753 struct rt_sigframe_v2 *frame;
1754 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1755 abi_ulong info_addr, uc_addr;
1757 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1758 return /* 1 */;
1760 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1761 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1762 copy_siginfo_to_user(&frame->info, info);
1764 setup_sigframe_v2(&frame->uc, set, env);
1766 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1767 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1769 env->regs[1] = info_addr;
1770 env->regs[2] = uc_addr;
1772 unlock_user_struct(frame, frame_addr, 1);
1775 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1776 target_siginfo_t *info,
1777 target_sigset_t *set, CPUARMState *env)
1779 if (get_osversion() >= 0x020612) {
1780 setup_rt_frame_v2(usig, ka, info, set, env);
1781 } else {
1782 setup_rt_frame_v1(usig, ka, info, set, env);
1786 static int
1787 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1789 int err = 0;
1790 uint32_t cpsr;
1792 __get_user_error(env->regs[0], &sc->arm_r0, err);
1793 __get_user_error(env->regs[1], &sc->arm_r1, err);
1794 __get_user_error(env->regs[2], &sc->arm_r2, err);
1795 __get_user_error(env->regs[3], &sc->arm_r3, err);
1796 __get_user_error(env->regs[4], &sc->arm_r4, err);
1797 __get_user_error(env->regs[5], &sc->arm_r5, err);
1798 __get_user_error(env->regs[6], &sc->arm_r6, err);
1799 __get_user_error(env->regs[7], &sc->arm_r7, err);
1800 __get_user_error(env->regs[8], &sc->arm_r8, err);
1801 __get_user_error(env->regs[9], &sc->arm_r9, err);
1802 __get_user_error(env->regs[10], &sc->arm_r10, err);
1803 __get_user_error(env->regs[11], &sc->arm_fp, err);
1804 __get_user_error(env->regs[12], &sc->arm_ip, err);
1805 __get_user_error(env->regs[13], &sc->arm_sp, err);
1806 __get_user_error(env->regs[14], &sc->arm_lr, err);
1807 __get_user_error(env->regs[15], &sc->arm_pc, err);
1808 #ifdef TARGET_CONFIG_CPU_32
1809 __get_user_error(cpsr, &sc->arm_cpsr, err);
1810 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1811 #endif
1813 err |= !valid_user_regs(env);
1815 return err;
1818 static long do_sigreturn_v1(CPUARMState *env)
1820 abi_ulong frame_addr;
1821 struct sigframe_v1 *frame = NULL;
1822 target_sigset_t set;
1823 sigset_t host_set;
1824 int i;
1827 * Since we stacked the signal on a 64-bit boundary,
1828 * then 'sp' should be word aligned here. If it's
1829 * not, then the user is trying to mess with us.
1831 frame_addr = env->regs[13];
1832 if (frame_addr & 7) {
1833 goto badframe;
1836 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1837 goto badframe;
1839 if (__get_user(set.sig[0], &frame->sc.oldmask))
1840 goto badframe;
1841 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1842 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1843 goto badframe;
1846 target_to_host_sigset_internal(&host_set, &set);
1847 sigprocmask(SIG_SETMASK, &host_set, NULL);
1849 if (restore_sigcontext(env, &frame->sc))
1850 goto badframe;
1852 #if 0
1853 /* Send SIGTRAP if we're single-stepping */
1854 if (ptrace_cancel_bpt(current))
1855 send_sig(SIGTRAP, current, 1);
1856 #endif
1857 unlock_user_struct(frame, frame_addr, 0);
1858 return env->regs[0];
1860 badframe:
1861 unlock_user_struct(frame, frame_addr, 0);
1862 force_sig(TARGET_SIGSEGV /* , current */);
1863 return 0;
1866 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1868 int i;
1869 abi_ulong magic, sz;
1870 uint32_t fpscr, fpexc;
1871 struct target_vfp_sigframe *vfpframe;
1872 vfpframe = (struct target_vfp_sigframe *)regspace;
1874 __get_user(magic, &vfpframe->magic);
1875 __get_user(sz, &vfpframe->size);
1876 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1877 return 0;
1879 for (i = 0; i < 32; i++) {
1880 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1882 __get_user(fpscr, &vfpframe->ufp.fpscr);
1883 vfp_set_fpscr(env, fpscr);
1884 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1885 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1886 * and the exception flag is cleared
1888 fpexc |= (1 << 30);
1889 fpexc &= ~((1 << 31) | (1 << 28));
1890 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1891 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1892 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1893 return (abi_ulong*)(vfpframe + 1);
1896 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1897 abi_ulong *regspace)
1899 int i;
1900 abi_ulong magic, sz;
1901 struct target_iwmmxt_sigframe *iwmmxtframe;
1902 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1904 __get_user(magic, &iwmmxtframe->magic);
1905 __get_user(sz, &iwmmxtframe->size);
1906 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1907 return 0;
1909 for (i = 0; i < 16; i++) {
1910 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1912 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1913 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1914 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1915 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1916 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1917 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1918 return (abi_ulong*)(iwmmxtframe + 1);
1921 static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1922 struct target_ucontext_v2 *uc)
1924 sigset_t host_set;
1925 abi_ulong *regspace;
1927 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1928 sigprocmask(SIG_SETMASK, &host_set, NULL);
1930 if (restore_sigcontext(env, &uc->tuc_mcontext))
1931 return 1;
1933 /* Restore coprocessor signal frame */
1934 regspace = uc->tuc_regspace;
1935 if (arm_feature(env, ARM_FEATURE_VFP)) {
1936 regspace = restore_sigframe_v2_vfp(env, regspace);
1937 if (!regspace) {
1938 return 1;
1941 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1942 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1943 if (!regspace) {
1944 return 1;
1948 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1949 return 1;
1951 #if 0
1952 /* Send SIGTRAP if we're single-stepping */
1953 if (ptrace_cancel_bpt(current))
1954 send_sig(SIGTRAP, current, 1);
1955 #endif
1957 return 0;
1960 static long do_sigreturn_v2(CPUARMState *env)
1962 abi_ulong frame_addr;
1963 struct sigframe_v2 *frame = NULL;
1966 * Since we stacked the signal on a 64-bit boundary,
1967 * then 'sp' should be word aligned here. If it's
1968 * not, then the user is trying to mess with us.
1970 frame_addr = env->regs[13];
1971 if (frame_addr & 7) {
1972 goto badframe;
1975 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1976 goto badframe;
1978 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1979 goto badframe;
1981 unlock_user_struct(frame, frame_addr, 0);
1982 return env->regs[0];
1984 badframe:
1985 unlock_user_struct(frame, frame_addr, 0);
1986 force_sig(TARGET_SIGSEGV /* , current */);
1987 return 0;
1990 long do_sigreturn(CPUARMState *env)
1992 if (get_osversion() >= 0x020612) {
1993 return do_sigreturn_v2(env);
1994 } else {
1995 return do_sigreturn_v1(env);
1999 static long do_rt_sigreturn_v1(CPUARMState *env)
2001 abi_ulong frame_addr;
2002 struct rt_sigframe_v1 *frame = NULL;
2003 sigset_t host_set;
2006 * Since we stacked the signal on a 64-bit boundary,
2007 * then 'sp' should be word aligned here. If it's
2008 * not, then the user is trying to mess with us.
2010 frame_addr = env->regs[13];
2011 if (frame_addr & 7) {
2012 goto badframe;
2015 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2016 goto badframe;
2018 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2019 sigprocmask(SIG_SETMASK, &host_set, NULL);
2021 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2022 goto badframe;
2024 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2025 goto badframe;
2027 #if 0
2028 /* Send SIGTRAP if we're single-stepping */
2029 if (ptrace_cancel_bpt(current))
2030 send_sig(SIGTRAP, current, 1);
2031 #endif
2032 unlock_user_struct(frame, frame_addr, 0);
2033 return env->regs[0];
2035 badframe:
2036 unlock_user_struct(frame, frame_addr, 0);
2037 force_sig(TARGET_SIGSEGV /* , current */);
2038 return 0;
2041 static long do_rt_sigreturn_v2(CPUARMState *env)
2043 abi_ulong frame_addr;
2044 struct rt_sigframe_v2 *frame = NULL;
2047 * Since we stacked the signal on a 64-bit boundary,
2048 * then 'sp' should be word aligned here. If it's
2049 * not, then the user is trying to mess with us.
2051 frame_addr = env->regs[13];
2052 if (frame_addr & 7) {
2053 goto badframe;
2056 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2057 goto badframe;
2059 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2060 goto badframe;
2062 unlock_user_struct(frame, frame_addr, 0);
2063 return env->regs[0];
2065 badframe:
2066 unlock_user_struct(frame, frame_addr, 0);
2067 force_sig(TARGET_SIGSEGV /* , current */);
2068 return 0;
2071 long do_rt_sigreturn(CPUARMState *env)
2073 if (get_osversion() >= 0x020612) {
2074 return do_rt_sigreturn_v2(env);
2075 } else {
2076 return do_rt_sigreturn_v1(env);
2080 #elif defined(TARGET_SPARC)
2082 #define __SUNOS_MAXWIN 31
2084 /* This is what SunOS does, so shall I. */
2085 struct target_sigcontext {
2086 abi_ulong sigc_onstack; /* state to restore */
2088 abi_ulong sigc_mask; /* sigmask to restore */
2089 abi_ulong sigc_sp; /* stack pointer */
2090 abi_ulong sigc_pc; /* program counter */
2091 abi_ulong sigc_npc; /* next program counter */
2092 abi_ulong sigc_psr; /* for condition codes etc */
2093 abi_ulong sigc_g1; /* User uses these two registers */
2094 abi_ulong sigc_o0; /* within the trampoline code. */
2096 /* Now comes information regarding the users window set
2097 * at the time of the signal.
2099 abi_ulong sigc_oswins; /* outstanding windows */
2101 /* stack ptrs for each regwin buf */
2102 char *sigc_spbuf[__SUNOS_MAXWIN];
2104 /* Windows to restore after signal */
2105 struct {
2106 abi_ulong locals[8];
2107 abi_ulong ins[8];
2108 } sigc_wbuf[__SUNOS_MAXWIN];
2110 /* A Sparc stack frame */
2111 struct sparc_stackf {
2112 abi_ulong locals[8];
2113 abi_ulong ins[8];
2114 /* It's simpler to treat fp and callers_pc as elements of ins[]
2115 * since we never need to access them ourselves.
2117 char *structptr;
2118 abi_ulong xargs[6];
2119 abi_ulong xxargs[1];
2122 typedef struct {
2123 struct {
2124 abi_ulong psr;
2125 abi_ulong pc;
2126 abi_ulong npc;
2127 abi_ulong y;
2128 abi_ulong u_regs[16]; /* globals and ins */
2129 } si_regs;
2130 int si_mask;
2131 } __siginfo_t;
2133 typedef struct {
2134 abi_ulong si_float_regs[32];
2135 unsigned long si_fsr;
2136 unsigned long si_fpqdepth;
2137 struct {
2138 unsigned long *insn_addr;
2139 unsigned long insn;
2140 } si_fpqueue [16];
2141 } qemu_siginfo_fpu_t;
2144 struct target_signal_frame {
2145 struct sparc_stackf ss;
2146 __siginfo_t info;
2147 abi_ulong fpu_save;
2148 abi_ulong insns[2] __attribute__ ((aligned (8)));
2149 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
2150 abi_ulong extra_size; /* Should be 0 */
2151 qemu_siginfo_fpu_t fpu_state;
2153 struct target_rt_signal_frame {
2154 struct sparc_stackf ss;
2155 siginfo_t info;
2156 abi_ulong regs[20];
2157 sigset_t mask;
2158 abi_ulong fpu_save;
2159 unsigned int insns[2];
2160 stack_t stack;
2161 unsigned int extra_size; /* Should be 0 */
2162 qemu_siginfo_fpu_t fpu_state;
2165 #define UREG_O0 16
2166 #define UREG_O6 22
2167 #define UREG_I0 0
2168 #define UREG_I1 1
2169 #define UREG_I2 2
2170 #define UREG_I3 3
2171 #define UREG_I4 4
2172 #define UREG_I5 5
2173 #define UREG_I6 6
2174 #define UREG_I7 7
2175 #define UREG_L0 8
2176 #define UREG_FP UREG_I6
2177 #define UREG_SP UREG_O6
2179 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2180 CPUSPARCState *env,
2181 unsigned long framesize)
2183 abi_ulong sp;
2185 sp = env->regwptr[UREG_FP];
2187 /* This is the X/Open sanctioned signal stack switching. */
2188 if (sa->sa_flags & TARGET_SA_ONSTACK) {
2189 if (!on_sig_stack(sp)
2190 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2191 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2193 return sp - framesize;
2196 static int
2197 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2199 int err = 0, i;
2201 err |= __put_user(env->psr, &si->si_regs.psr);
2202 err |= __put_user(env->pc, &si->si_regs.pc);
2203 err |= __put_user(env->npc, &si->si_regs.npc);
2204 err |= __put_user(env->y, &si->si_regs.y);
2205 for (i=0; i < 8; i++) {
2206 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
2208 for (i=0; i < 8; i++) {
2209 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2211 err |= __put_user(mask, &si->si_mask);
2212 return err;
2215 #if 0
2216 static int
2217 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2218 CPUSPARCState *env, unsigned long mask)
2220 int err = 0;
2222 err |= __put_user(mask, &sc->sigc_mask);
2223 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
2224 err |= __put_user(env->pc, &sc->sigc_pc);
2225 err |= __put_user(env->npc, &sc->sigc_npc);
2226 err |= __put_user(env->psr, &sc->sigc_psr);
2227 err |= __put_user(env->gregs[1], &sc->sigc_g1);
2228 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
2230 return err;
2232 #endif
2233 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2235 static void setup_frame(int sig, struct target_sigaction *ka,
2236 target_sigset_t *set, CPUSPARCState *env)
2238 abi_ulong sf_addr;
2239 struct target_signal_frame *sf;
2240 int sigframe_size, err, i;
2242 /* 1. Make sure everything is clean */
2243 //synchronize_user_stack();
2245 sigframe_size = NF_ALIGNEDSZ;
2246 sf_addr = get_sigframe(ka, env, sigframe_size);
2248 sf = lock_user(VERIFY_WRITE, sf_addr,
2249 sizeof(struct target_signal_frame), 0);
2250 if (!sf)
2251 goto sigsegv;
2253 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2254 #if 0
2255 if (invalid_frame_pointer(sf, sigframe_size))
2256 goto sigill_and_return;
2257 #endif
2258 /* 2. Save the current process state */
2259 err = setup___siginfo(&sf->info, env, set->sig[0]);
2260 err |= __put_user(0, &sf->extra_size);
2262 //err |= save_fpu_state(regs, &sf->fpu_state);
2263 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
2265 err |= __put_user(set->sig[0], &sf->info.si_mask);
2266 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2267 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
2270 for (i = 0; i < 8; i++) {
2271 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2273 for (i = 0; i < 8; i++) {
2274 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
2276 if (err)
2277 goto sigsegv;
2279 /* 3. signal handler back-trampoline and parameters */
2280 env->regwptr[UREG_FP] = sf_addr;
2281 env->regwptr[UREG_I0] = sig;
2282 env->regwptr[UREG_I1] = sf_addr +
2283 offsetof(struct target_signal_frame, info);
2284 env->regwptr[UREG_I2] = sf_addr +
2285 offsetof(struct target_signal_frame, info);
2287 /* 4. signal handler */
2288 env->pc = ka->_sa_handler;
2289 env->npc = (env->pc + 4);
2290 /* 5. return to kernel instructions */
2291 if (ka->sa_restorer)
2292 env->regwptr[UREG_I7] = ka->sa_restorer;
2293 else {
2294 uint32_t val32;
2296 env->regwptr[UREG_I7] = sf_addr +
2297 offsetof(struct target_signal_frame, insns) - 2 * 4;
2299 /* mov __NR_sigreturn, %g1 */
2300 val32 = 0x821020d8;
2301 err |= __put_user(val32, &sf->insns[0]);
2303 /* t 0x10 */
2304 val32 = 0x91d02010;
2305 err |= __put_user(val32, &sf->insns[1]);
2306 if (err)
2307 goto sigsegv;
2309 /* Flush instruction space. */
2310 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2311 // tb_flush(env);
2313 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2314 return;
2315 #if 0
2316 sigill_and_return:
2317 force_sig(TARGET_SIGILL);
2318 #endif
2319 sigsegv:
2320 //fprintf(stderr, "force_sig\n");
2321 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2322 force_sig(TARGET_SIGSEGV);
2324 static inline int
2325 restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)
2327 int err;
2328 #if 0
2329 #ifdef CONFIG_SMP
2330 if (current->flags & PF_USEDFPU)
2331 regs->psr &= ~PSR_EF;
2332 #else
2333 if (current == last_task_used_math) {
2334 last_task_used_math = 0;
2335 regs->psr &= ~PSR_EF;
2337 #endif
2338 current->used_math = 1;
2339 current->flags &= ~PF_USEDFPU;
2340 #endif
2341 #if 0
2342 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2343 return -EFAULT;
2344 #endif
2346 /* XXX: incorrect */
2347 err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],
2348 (sizeof(abi_ulong) * 32));
2349 err |= __get_user(env->fsr, &fpu->si_fsr);
2350 #if 0
2351 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2352 if (current->thread.fpqdepth != 0)
2353 err |= __copy_from_user(&current->thread.fpqueue[0],
2354 &fpu->si_fpqueue[0],
2355 ((sizeof(unsigned long) +
2356 (sizeof(unsigned long *)))*16));
2357 #endif
2358 return err;
2362 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2363 target_siginfo_t *info,
2364 target_sigset_t *set, CPUSPARCState *env)
2366 fprintf(stderr, "setup_rt_frame: not implemented\n");
2369 long do_sigreturn(CPUSPARCState *env)
2371 abi_ulong sf_addr;
2372 struct target_signal_frame *sf;
2373 uint32_t up_psr, pc, npc;
2374 target_sigset_t set;
2375 sigset_t host_set;
2376 int err, i;
2378 sf_addr = env->regwptr[UREG_FP];
2379 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2380 goto segv_and_exit;
2381 #if 0
2382 fprintf(stderr, "sigreturn\n");
2383 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2384 #endif
2385 //cpu_dump_state(env, stderr, fprintf, 0);
2387 /* 1. Make sure we are not getting garbage from the user */
2389 if (sf_addr & 3)
2390 goto segv_and_exit;
2392 err = __get_user(pc, &sf->info.si_regs.pc);
2393 err |= __get_user(npc, &sf->info.si_regs.npc);
2395 if ((pc | npc) & 3)
2396 goto segv_and_exit;
2398 /* 2. Restore the state */
2399 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2401 /* User can only change condition codes and FPU enabling in %psr. */
2402 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2403 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2405 env->pc = pc;
2406 env->npc = npc;
2407 err |= __get_user(env->y, &sf->info.si_regs.y);
2408 for (i=0; i < 8; i++) {
2409 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2411 for (i=0; i < 8; i++) {
2412 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2415 /* FIXME: implement FPU save/restore:
2416 * __get_user(fpu_save, &sf->fpu_save);
2417 * if (fpu_save)
2418 * err |= restore_fpu_state(env, fpu_save);
2421 /* This is pretty much atomic, no amount locking would prevent
2422 * the races which exist anyways.
2424 err |= __get_user(set.sig[0], &sf->info.si_mask);
2425 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2426 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2429 target_to_host_sigset_internal(&host_set, &set);
2430 sigprocmask(SIG_SETMASK, &host_set, NULL);
2432 if (err)
2433 goto segv_and_exit;
2434 unlock_user_struct(sf, sf_addr, 0);
2435 return env->regwptr[0];
2437 segv_and_exit:
2438 unlock_user_struct(sf, sf_addr, 0);
2439 force_sig(TARGET_SIGSEGV);
2442 long do_rt_sigreturn(CPUSPARCState *env)
2444 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2445 return -TARGET_ENOSYS;
2448 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2449 #define MC_TSTATE 0
2450 #define MC_PC 1
2451 #define MC_NPC 2
2452 #define MC_Y 3
2453 #define MC_G1 4
2454 #define MC_G2 5
2455 #define MC_G3 6
2456 #define MC_G4 7
2457 #define MC_G5 8
2458 #define MC_G6 9
2459 #define MC_G7 10
2460 #define MC_O0 11
2461 #define MC_O1 12
2462 #define MC_O2 13
2463 #define MC_O3 14
2464 #define MC_O4 15
2465 #define MC_O5 16
2466 #define MC_O6 17
2467 #define MC_O7 18
2468 #define MC_NGREG 19
2470 typedef abi_ulong target_mc_greg_t;
2471 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2473 struct target_mc_fq {
2474 abi_ulong *mcfq_addr;
2475 uint32_t mcfq_insn;
2478 struct target_mc_fpu {
2479 union {
2480 uint32_t sregs[32];
2481 uint64_t dregs[32];
2482 //uint128_t qregs[16];
2483 } mcfpu_fregs;
2484 abi_ulong mcfpu_fsr;
2485 abi_ulong mcfpu_fprs;
2486 abi_ulong mcfpu_gsr;
2487 struct target_mc_fq *mcfpu_fq;
2488 unsigned char mcfpu_qcnt;
2489 unsigned char mcfpu_qentsz;
2490 unsigned char mcfpu_enab;
2492 typedef struct target_mc_fpu target_mc_fpu_t;
2494 typedef struct {
2495 target_mc_gregset_t mc_gregs;
2496 target_mc_greg_t mc_fp;
2497 target_mc_greg_t mc_i7;
2498 target_mc_fpu_t mc_fpregs;
2499 } target_mcontext_t;
2501 struct target_ucontext {
2502 struct target_ucontext *tuc_link;
2503 abi_ulong tuc_flags;
2504 target_sigset_t tuc_sigmask;
2505 target_mcontext_t tuc_mcontext;
2508 /* A V9 register window */
2509 struct target_reg_window {
2510 abi_ulong locals[8];
2511 abi_ulong ins[8];
2514 #define TARGET_STACK_BIAS 2047
2516 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2517 void sparc64_set_context(CPUSPARCState *env)
2519 abi_ulong ucp_addr;
2520 struct target_ucontext *ucp;
2521 target_mc_gregset_t *grp;
2522 abi_ulong pc, npc, tstate;
2523 abi_ulong fp, i7, w_addr;
2524 int err;
2525 unsigned int i;
2527 ucp_addr = env->regwptr[UREG_I0];
2528 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2529 goto do_sigsegv;
2530 grp = &ucp->tuc_mcontext.mc_gregs;
2531 err = __get_user(pc, &((*grp)[MC_PC]));
2532 err |= __get_user(npc, &((*grp)[MC_NPC]));
2533 if (err || ((pc | npc) & 3))
2534 goto do_sigsegv;
2535 if (env->regwptr[UREG_I1]) {
2536 target_sigset_t target_set;
2537 sigset_t set;
2539 if (TARGET_NSIG_WORDS == 1) {
2540 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2541 goto do_sigsegv;
2542 } else {
2543 abi_ulong *src, *dst;
2544 src = ucp->tuc_sigmask.sig;
2545 dst = target_set.sig;
2546 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2547 err |= __get_user(*dst, src);
2549 if (err)
2550 goto do_sigsegv;
2552 target_to_host_sigset_internal(&set, &target_set);
2553 sigprocmask(SIG_SETMASK, &set, NULL);
2555 env->pc = pc;
2556 env->npc = npc;
2557 err |= __get_user(env->y, &((*grp)[MC_Y]));
2558 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2559 env->asi = (tstate >> 24) & 0xff;
2560 cpu_put_ccr(env, tstate >> 32);
2561 cpu_put_cwp64(env, tstate & 0x1f);
2562 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2563 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2564 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2565 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2566 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2567 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2568 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2569 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2570 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2571 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2572 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2573 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2574 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2575 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2576 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2578 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2579 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2581 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2582 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2583 abi_ulong) != 0)
2584 goto do_sigsegv;
2585 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2586 abi_ulong) != 0)
2587 goto do_sigsegv;
2588 /* FIXME this does not match how the kernel handles the FPU in
2589 * its sparc64_set_context implementation. In particular the FPU
2590 * is only restored if fenab is non-zero in:
2591 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2593 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2595 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2596 for (i = 0; i < 64; i++, src++) {
2597 if (i & 1) {
2598 err |= __get_user(env->fpr[i/2].l.lower, src);
2599 } else {
2600 err |= __get_user(env->fpr[i/2].l.upper, src);
2604 err |= __get_user(env->fsr,
2605 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2606 err |= __get_user(env->gsr,
2607 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2608 if (err)
2609 goto do_sigsegv;
2610 unlock_user_struct(ucp, ucp_addr, 0);
2611 return;
2612 do_sigsegv:
2613 unlock_user_struct(ucp, ucp_addr, 0);
2614 force_sig(TARGET_SIGSEGV);
2617 void sparc64_get_context(CPUSPARCState *env)
2619 abi_ulong ucp_addr;
2620 struct target_ucontext *ucp;
2621 target_mc_gregset_t *grp;
2622 target_mcontext_t *mcp;
2623 abi_ulong fp, i7, w_addr;
2624 int err;
2625 unsigned int i;
2626 target_sigset_t target_set;
2627 sigset_t set;
2629 ucp_addr = env->regwptr[UREG_I0];
2630 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2631 goto do_sigsegv;
2633 mcp = &ucp->tuc_mcontext;
2634 grp = &mcp->mc_gregs;
2636 /* Skip over the trap instruction, first. */
2637 env->pc = env->npc;
2638 env->npc += 4;
2640 err = 0;
2642 sigprocmask(0, NULL, &set);
2643 host_to_target_sigset_internal(&target_set, &set);
2644 if (TARGET_NSIG_WORDS == 1) {
2645 err |= __put_user(target_set.sig[0],
2646 (abi_ulong *)&ucp->tuc_sigmask);
2647 } else {
2648 abi_ulong *src, *dst;
2649 src = target_set.sig;
2650 dst = ucp->tuc_sigmask.sig;
2651 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2652 err |= __put_user(*src, dst);
2654 if (err)
2655 goto do_sigsegv;
2658 /* XXX: tstate must be saved properly */
2659 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2660 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2661 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2662 err |= __put_user(env->y, &((*grp)[MC_Y]));
2663 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2664 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2665 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2666 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2667 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2668 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2669 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2670 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2671 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2672 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2673 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2674 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2675 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2676 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2677 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2679 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2680 fp = i7 = 0;
2681 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2682 abi_ulong) != 0)
2683 goto do_sigsegv;
2684 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2685 abi_ulong) != 0)
2686 goto do_sigsegv;
2687 err |= __put_user(fp, &(mcp->mc_fp));
2688 err |= __put_user(i7, &(mcp->mc_i7));
2691 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2692 for (i = 0; i < 64; i++, dst++) {
2693 if (i & 1) {
2694 err |= __put_user(env->fpr[i/2].l.lower, dst);
2695 } else {
2696 err |= __put_user(env->fpr[i/2].l.upper, dst);
2700 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2701 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2702 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2704 if (err)
2705 goto do_sigsegv;
2706 unlock_user_struct(ucp, ucp_addr, 1);
2707 return;
2708 do_sigsegv:
2709 unlock_user_struct(ucp, ucp_addr, 1);
2710 force_sig(TARGET_SIGSEGV);
2712 #endif
2713 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2715 # if defined(TARGET_ABI_MIPSO32)
2716 struct target_sigcontext {
2717 uint32_t sc_regmask; /* Unused */
2718 uint32_t sc_status;
2719 uint64_t sc_pc;
2720 uint64_t sc_regs[32];
2721 uint64_t sc_fpregs[32];
2722 uint32_t sc_ownedfp; /* Unused */
2723 uint32_t sc_fpc_csr;
2724 uint32_t sc_fpc_eir; /* Unused */
2725 uint32_t sc_used_math;
2726 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2727 uint32_t pad0;
2728 uint64_t sc_mdhi;
2729 uint64_t sc_mdlo;
2730 target_ulong sc_hi1; /* Was sc_cause */
2731 target_ulong sc_lo1; /* Was sc_badvaddr */
2732 target_ulong sc_hi2; /* Was sc_sigset[4] */
2733 target_ulong sc_lo2;
2734 target_ulong sc_hi3;
2735 target_ulong sc_lo3;
2737 # else /* N32 || N64 */
2738 struct target_sigcontext {
2739 uint64_t sc_regs[32];
2740 uint64_t sc_fpregs[32];
2741 uint64_t sc_mdhi;
2742 uint64_t sc_hi1;
2743 uint64_t sc_hi2;
2744 uint64_t sc_hi3;
2745 uint64_t sc_mdlo;
2746 uint64_t sc_lo1;
2747 uint64_t sc_lo2;
2748 uint64_t sc_lo3;
2749 uint64_t sc_pc;
2750 uint32_t sc_fpc_csr;
2751 uint32_t sc_used_math;
2752 uint32_t sc_dsp;
2753 uint32_t sc_reserved;
2755 # endif /* O32 */
2757 struct sigframe {
2758 uint32_t sf_ass[4]; /* argument save space for o32 */
2759 uint32_t sf_code[2]; /* signal trampoline */
2760 struct target_sigcontext sf_sc;
2761 target_sigset_t sf_mask;
2764 struct target_ucontext {
2765 target_ulong tuc_flags;
2766 target_ulong tuc_link;
2767 target_stack_t tuc_stack;
2768 target_ulong pad0;
2769 struct target_sigcontext tuc_mcontext;
2770 target_sigset_t tuc_sigmask;
2773 struct target_rt_sigframe {
2774 uint32_t rs_ass[4]; /* argument save space for o32 */
2775 uint32_t rs_code[2]; /* signal trampoline */
2776 struct target_siginfo rs_info;
2777 struct target_ucontext rs_uc;
2780 /* Install trampoline to jump back from signal handler */
2781 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2783 int err = 0;
2786 * Set up the return code ...
2788 * li v0, __NR__foo_sigreturn
2789 * syscall
2792 err |= __put_user(0x24020000 + syscall, tramp + 0);
2793 err |= __put_user(0x0000000c , tramp + 1);
2794 return err;
2797 static inline int
2798 setup_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2800 int err = 0;
2801 int i;
2803 err |= __put_user(exception_resume_pc(regs), &sc->sc_pc);
2804 regs->hflags &= ~MIPS_HFLAG_BMASK;
2806 __put_user(0, &sc->sc_regs[0]);
2807 for (i = 1; i < 32; ++i) {
2808 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2811 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2812 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2814 /* Rather than checking for dsp existence, always copy. The storage
2815 would just be garbage otherwise. */
2816 err |= __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
2817 err |= __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
2818 err |= __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
2819 err |= __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
2820 err |= __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
2821 err |= __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
2823 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2824 err |= __put_user(dsp, &sc->sc_dsp);
2827 err |= __put_user(1, &sc->sc_used_math);
2829 for (i = 0; i < 32; ++i) {
2830 err |= __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2833 return err;
2836 static inline int
2837 restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2839 int err = 0;
2840 int i;
2842 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2844 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2845 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2847 for (i = 1; i < 32; ++i) {
2848 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2851 err |= __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
2852 err |= __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
2853 err |= __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
2854 err |= __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
2855 err |= __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
2856 err |= __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
2858 uint32_t dsp;
2859 err |= __get_user(dsp, &sc->sc_dsp);
2860 cpu_wrdsp(dsp, 0x3ff, regs);
2863 for (i = 0; i < 32; ++i) {
2864 err |= __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2867 return err;
2871 * Determine which stack to use..
2873 static inline abi_ulong
2874 get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2876 unsigned long sp;
2878 /* Default to using normal stack */
2879 sp = regs->active_tc.gpr[29];
2882 * FPU emulator may have its own trampoline active just
2883 * above the user stack, 16-bytes before the next lowest
2884 * 16 byte boundary. Try to avoid trashing it.
2886 sp -= 32;
2888 /* This is the X/Open sanctioned signal stack switching. */
2889 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2890 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2893 return (sp - frame_size) & ~7;
2896 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2898 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2899 env->hflags &= ~MIPS_HFLAG_M16;
2900 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2901 env->active_tc.PC &= ~(target_ulong) 1;
2905 # if defined(TARGET_ABI_MIPSO32)
2906 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2907 static void setup_frame(int sig, struct target_sigaction * ka,
2908 target_sigset_t *set, CPUMIPSState *regs)
2910 struct sigframe *frame;
2911 abi_ulong frame_addr;
2912 int i;
2914 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2915 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2916 goto give_sigsegv;
2918 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2920 if(setup_sigcontext(regs, &frame->sf_sc))
2921 goto give_sigsegv;
2923 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2924 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2925 goto give_sigsegv;
2929 * Arguments to signal handler:
2931 * a0 = signal number
2932 * a1 = 0 (should be cause)
2933 * a2 = pointer to struct sigcontext
2935 * $25 and PC point to the signal handler, $29 points to the
2936 * struct sigframe.
2938 regs->active_tc.gpr[ 4] = sig;
2939 regs->active_tc.gpr[ 5] = 0;
2940 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2941 regs->active_tc.gpr[29] = frame_addr;
2942 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2943 /* The original kernel code sets CP0_EPC to the handler
2944 * since it returns to userland using eret
2945 * we cannot do this here, and we must set PC directly */
2946 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2947 mips_set_hflags_isa_mode_from_pc(regs);
2948 unlock_user_struct(frame, frame_addr, 1);
2949 return;
2951 give_sigsegv:
2952 unlock_user_struct(frame, frame_addr, 1);
2953 force_sig(TARGET_SIGSEGV/*, current*/);
2956 long do_sigreturn(CPUMIPSState *regs)
2958 struct sigframe *frame;
2959 abi_ulong frame_addr;
2960 sigset_t blocked;
2961 target_sigset_t target_set;
2962 int i;
2964 #if defined(DEBUG_SIGNAL)
2965 fprintf(stderr, "do_sigreturn\n");
2966 #endif
2967 frame_addr = regs->active_tc.gpr[29];
2968 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2969 goto badframe;
2971 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2972 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2973 goto badframe;
2976 target_to_host_sigset_internal(&blocked, &target_set);
2977 sigprocmask(SIG_SETMASK, &blocked, NULL);
2979 if (restore_sigcontext(regs, &frame->sf_sc))
2980 goto badframe;
2982 #if 0
2984 * Don't let your children do this ...
2986 __asm__ __volatile__(
2987 "move\t$29, %0\n\t"
2988 "j\tsyscall_exit"
2989 :/* no outputs */
2990 :"r" (&regs));
2991 /* Unreached */
2992 #endif
2994 regs->active_tc.PC = regs->CP0_EPC;
2995 mips_set_hflags_isa_mode_from_pc(regs);
2996 /* I am not sure this is right, but it seems to work
2997 * maybe a problem with nested signals ? */
2998 regs->CP0_EPC = 0;
2999 return -TARGET_QEMU_ESIGRETURN;
3001 badframe:
3002 force_sig(TARGET_SIGSEGV/*, current*/);
3003 return 0;
3005 # endif /* O32 */
3007 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3008 target_siginfo_t *info,
3009 target_sigset_t *set, CPUMIPSState *env)
3011 struct target_rt_sigframe *frame;
3012 abi_ulong frame_addr;
3013 int i;
3015 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3016 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3017 goto give_sigsegv;
3019 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3021 copy_siginfo_to_user(&frame->rs_info, info);
3023 __put_user(0, &frame->rs_uc.tuc_flags);
3024 __put_user(0, &frame->rs_uc.tuc_link);
3025 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
3026 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
3027 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3028 &frame->rs_uc.tuc_stack.ss_flags);
3030 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3032 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3033 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3037 * Arguments to signal handler:
3039 * a0 = signal number
3040 * a1 = pointer to siginfo_t
3041 * a2 = pointer to struct ucontext
3043 * $25 and PC point to the signal handler, $29 points to the
3044 * struct sigframe.
3046 env->active_tc.gpr[ 4] = sig;
3047 env->active_tc.gpr[ 5] = frame_addr
3048 + offsetof(struct target_rt_sigframe, rs_info);
3049 env->active_tc.gpr[ 6] = frame_addr
3050 + offsetof(struct target_rt_sigframe, rs_uc);
3051 env->active_tc.gpr[29] = frame_addr;
3052 env->active_tc.gpr[31] = frame_addr
3053 + offsetof(struct target_rt_sigframe, rs_code);
3054 /* The original kernel code sets CP0_EPC to the handler
3055 * since it returns to userland using eret
3056 * we cannot do this here, and we must set PC directly */
3057 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3058 mips_set_hflags_isa_mode_from_pc(env);
3059 unlock_user_struct(frame, frame_addr, 1);
3060 return;
3062 give_sigsegv:
3063 unlock_user_struct(frame, frame_addr, 1);
3064 force_sig(TARGET_SIGSEGV/*, current*/);
3067 long do_rt_sigreturn(CPUMIPSState *env)
3069 struct target_rt_sigframe *frame;
3070 abi_ulong frame_addr;
3071 sigset_t blocked;
3073 #if defined(DEBUG_SIGNAL)
3074 fprintf(stderr, "do_rt_sigreturn\n");
3075 #endif
3076 frame_addr = env->active_tc.gpr[29];
3077 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3078 goto badframe;
3080 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3081 sigprocmask(SIG_SETMASK, &blocked, NULL);
3083 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
3084 goto badframe;
3086 if (do_sigaltstack(frame_addr +
3087 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3088 0, get_sp_from_cpustate(env)) == -EFAULT)
3089 goto badframe;
3091 env->active_tc.PC = env->CP0_EPC;
3092 mips_set_hflags_isa_mode_from_pc(env);
3093 /* I am not sure this is right, but it seems to work
3094 * maybe a problem with nested signals ? */
3095 env->CP0_EPC = 0;
3096 return -TARGET_QEMU_ESIGRETURN;
3098 badframe:
3099 force_sig(TARGET_SIGSEGV/*, current*/);
3100 return 0;
3103 #elif defined(TARGET_SH4)
3106 * code and data structures from linux kernel:
3107 * include/asm-sh/sigcontext.h
3108 * arch/sh/kernel/signal.c
3111 struct target_sigcontext {
3112 target_ulong oldmask;
3114 /* CPU registers */
3115 target_ulong sc_gregs[16];
3116 target_ulong sc_pc;
3117 target_ulong sc_pr;
3118 target_ulong sc_sr;
3119 target_ulong sc_gbr;
3120 target_ulong sc_mach;
3121 target_ulong sc_macl;
3123 /* FPU registers */
3124 target_ulong sc_fpregs[16];
3125 target_ulong sc_xfpregs[16];
3126 unsigned int sc_fpscr;
3127 unsigned int sc_fpul;
3128 unsigned int sc_ownedfp;
3131 struct target_sigframe
3133 struct target_sigcontext sc;
3134 target_ulong extramask[TARGET_NSIG_WORDS-1];
3135 uint16_t retcode[3];
3139 struct target_ucontext {
3140 target_ulong tuc_flags;
3141 struct target_ucontext *tuc_link;
3142 target_stack_t tuc_stack;
3143 struct target_sigcontext tuc_mcontext;
3144 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3147 struct target_rt_sigframe
3149 struct target_siginfo info;
3150 struct target_ucontext uc;
3151 uint16_t retcode[3];
3155 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3156 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3158 static abi_ulong get_sigframe(struct target_sigaction *ka,
3159 unsigned long sp, size_t frame_size)
3161 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
3162 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3165 return (sp - frame_size) & -8ul;
3168 static int setup_sigcontext(struct target_sigcontext *sc,
3169 CPUSH4State *regs, unsigned long mask)
3171 int err = 0;
3172 int i;
3174 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
3175 COPY(gregs[0]); COPY(gregs[1]);
3176 COPY(gregs[2]); COPY(gregs[3]);
3177 COPY(gregs[4]); COPY(gregs[5]);
3178 COPY(gregs[6]); COPY(gregs[7]);
3179 COPY(gregs[8]); COPY(gregs[9]);
3180 COPY(gregs[10]); COPY(gregs[11]);
3181 COPY(gregs[12]); COPY(gregs[13]);
3182 COPY(gregs[14]); COPY(gregs[15]);
3183 COPY(gbr); COPY(mach);
3184 COPY(macl); COPY(pr);
3185 COPY(sr); COPY(pc);
3186 #undef COPY
3188 for (i=0; i<16; i++) {
3189 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3191 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
3192 err |= __put_user(regs->fpul, &sc->sc_fpul);
3194 /* non-iBCS2 extensions.. */
3195 err |= __put_user(mask, &sc->oldmask);
3197 return err;
3200 static int restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3201 target_ulong *r0_p)
3203 unsigned int err = 0;
3204 int i;
3206 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3207 COPY(gregs[1]);
3208 COPY(gregs[2]); COPY(gregs[3]);
3209 COPY(gregs[4]); COPY(gregs[5]);
3210 COPY(gregs[6]); COPY(gregs[7]);
3211 COPY(gregs[8]); COPY(gregs[9]);
3212 COPY(gregs[10]); COPY(gregs[11]);
3213 COPY(gregs[12]); COPY(gregs[13]);
3214 COPY(gregs[14]); COPY(gregs[15]);
3215 COPY(gbr); COPY(mach);
3216 COPY(macl); COPY(pr);
3217 COPY(sr); COPY(pc);
3218 #undef COPY
3220 for (i=0; i<16; i++) {
3221 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3223 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3224 err |= __get_user(regs->fpul, &sc->sc_fpul);
3226 regs->tra = -1; /* disable syscall checks */
3227 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3228 return err;
3231 static void setup_frame(int sig, struct target_sigaction *ka,
3232 target_sigset_t *set, CPUSH4State *regs)
3234 struct target_sigframe *frame;
3235 abi_ulong frame_addr;
3236 int i;
3237 int err = 0;
3238 int signal;
3240 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3241 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3242 goto give_sigsegv;
3244 signal = current_exec_domain_sig(sig);
3246 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3248 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3249 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3252 /* Set up to return from userspace. If provided, use a stub
3253 already in userspace. */
3254 if (ka->sa_flags & TARGET_SA_RESTORER) {
3255 regs->pr = (unsigned long) ka->sa_restorer;
3256 } else {
3257 /* Generate return code (system call to sigreturn) */
3258 err |= __put_user(MOVW(2), &frame->retcode[0]);
3259 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3260 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3261 regs->pr = (unsigned long) frame->retcode;
3264 if (err)
3265 goto give_sigsegv;
3267 /* Set up registers for signal handler */
3268 regs->gregs[15] = frame_addr;
3269 regs->gregs[4] = signal; /* Arg for signal handler */
3270 regs->gregs[5] = 0;
3271 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3272 regs->pc = (unsigned long) ka->_sa_handler;
3274 unlock_user_struct(frame, frame_addr, 1);
3275 return;
3277 give_sigsegv:
3278 unlock_user_struct(frame, frame_addr, 1);
3279 force_sig(TARGET_SIGSEGV);
3282 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3283 target_siginfo_t *info,
3284 target_sigset_t *set, CPUSH4State *regs)
3286 struct target_rt_sigframe *frame;
3287 abi_ulong frame_addr;
3288 int i;
3289 int err = 0;
3290 int signal;
3292 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3293 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3294 goto give_sigsegv;
3296 signal = current_exec_domain_sig(sig);
3298 err |= copy_siginfo_to_user(&frame->info, info);
3300 /* Create the ucontext. */
3301 err |= __put_user(0, &frame->uc.tuc_flags);
3302 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3303 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3304 &frame->uc.tuc_stack.ss_sp);
3305 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3306 &frame->uc.tuc_stack.ss_flags);
3307 err |= __put_user(target_sigaltstack_used.ss_size,
3308 &frame->uc.tuc_stack.ss_size);
3309 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3310 regs, set->sig[0]);
3311 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3312 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3315 /* Set up to return from userspace. If provided, use a stub
3316 already in userspace. */
3317 if (ka->sa_flags & TARGET_SA_RESTORER) {
3318 regs->pr = (unsigned long) ka->sa_restorer;
3319 } else {
3320 /* Generate return code (system call to sigreturn) */
3321 err |= __put_user(MOVW(2), &frame->retcode[0]);
3322 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3323 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3324 regs->pr = (unsigned long) frame->retcode;
3327 if (err)
3328 goto give_sigsegv;
3330 /* Set up registers for signal handler */
3331 regs->gregs[15] = frame_addr;
3332 regs->gregs[4] = signal; /* Arg for signal handler */
3333 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3334 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3335 regs->pc = (unsigned long) ka->_sa_handler;
3337 unlock_user_struct(frame, frame_addr, 1);
3338 return;
3340 give_sigsegv:
3341 unlock_user_struct(frame, frame_addr, 1);
3342 force_sig(TARGET_SIGSEGV);
3345 long do_sigreturn(CPUSH4State *regs)
3347 struct target_sigframe *frame;
3348 abi_ulong frame_addr;
3349 sigset_t blocked;
3350 target_sigset_t target_set;
3351 target_ulong r0;
3352 int i;
3353 int err = 0;
3355 #if defined(DEBUG_SIGNAL)
3356 fprintf(stderr, "do_sigreturn\n");
3357 #endif
3358 frame_addr = regs->gregs[15];
3359 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3360 goto badframe;
3362 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3363 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3364 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3367 if (err)
3368 goto badframe;
3370 target_to_host_sigset_internal(&blocked, &target_set);
3371 sigprocmask(SIG_SETMASK, &blocked, NULL);
3373 if (restore_sigcontext(regs, &frame->sc, &r0))
3374 goto badframe;
3376 unlock_user_struct(frame, frame_addr, 0);
3377 return r0;
3379 badframe:
3380 unlock_user_struct(frame, frame_addr, 0);
3381 force_sig(TARGET_SIGSEGV);
3382 return 0;
3385 long do_rt_sigreturn(CPUSH4State *regs)
3387 struct target_rt_sigframe *frame;
3388 abi_ulong frame_addr;
3389 sigset_t blocked;
3390 target_ulong r0;
3392 #if defined(DEBUG_SIGNAL)
3393 fprintf(stderr, "do_rt_sigreturn\n");
3394 #endif
3395 frame_addr = regs->gregs[15];
3396 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3397 goto badframe;
3399 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3400 sigprocmask(SIG_SETMASK, &blocked, NULL);
3402 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3403 goto badframe;
3405 if (do_sigaltstack(frame_addr +
3406 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3407 0, get_sp_from_cpustate(regs)) == -EFAULT)
3408 goto badframe;
3410 unlock_user_struct(frame, frame_addr, 0);
3411 return r0;
3413 badframe:
3414 unlock_user_struct(frame, frame_addr, 0);
3415 force_sig(TARGET_SIGSEGV);
3416 return 0;
3418 #elif defined(TARGET_MICROBLAZE)
3420 struct target_sigcontext {
3421 struct target_pt_regs regs; /* needs to be first */
3422 uint32_t oldmask;
3425 struct target_stack_t {
3426 abi_ulong ss_sp;
3427 int ss_flags;
3428 unsigned int ss_size;
3431 struct target_ucontext {
3432 abi_ulong tuc_flags;
3433 abi_ulong tuc_link;
3434 struct target_stack_t tuc_stack;
3435 struct target_sigcontext tuc_mcontext;
3436 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3439 /* Signal frames. */
3440 struct target_signal_frame {
3441 struct target_ucontext uc;
3442 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3443 uint32_t tramp[2];
3446 struct rt_signal_frame {
3447 siginfo_t info;
3448 struct ucontext uc;
3449 uint32_t tramp[2];
3452 static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3454 __put_user(env->regs[0], &sc->regs.r0);
3455 __put_user(env->regs[1], &sc->regs.r1);
3456 __put_user(env->regs[2], &sc->regs.r2);
3457 __put_user(env->regs[3], &sc->regs.r3);
3458 __put_user(env->regs[4], &sc->regs.r4);
3459 __put_user(env->regs[5], &sc->regs.r5);
3460 __put_user(env->regs[6], &sc->regs.r6);
3461 __put_user(env->regs[7], &sc->regs.r7);
3462 __put_user(env->regs[8], &sc->regs.r8);
3463 __put_user(env->regs[9], &sc->regs.r9);
3464 __put_user(env->regs[10], &sc->regs.r10);
3465 __put_user(env->regs[11], &sc->regs.r11);
3466 __put_user(env->regs[12], &sc->regs.r12);
3467 __put_user(env->regs[13], &sc->regs.r13);
3468 __put_user(env->regs[14], &sc->regs.r14);
3469 __put_user(env->regs[15], &sc->regs.r15);
3470 __put_user(env->regs[16], &sc->regs.r16);
3471 __put_user(env->regs[17], &sc->regs.r17);
3472 __put_user(env->regs[18], &sc->regs.r18);
3473 __put_user(env->regs[19], &sc->regs.r19);
3474 __put_user(env->regs[20], &sc->regs.r20);
3475 __put_user(env->regs[21], &sc->regs.r21);
3476 __put_user(env->regs[22], &sc->regs.r22);
3477 __put_user(env->regs[23], &sc->regs.r23);
3478 __put_user(env->regs[24], &sc->regs.r24);
3479 __put_user(env->regs[25], &sc->regs.r25);
3480 __put_user(env->regs[26], &sc->regs.r26);
3481 __put_user(env->regs[27], &sc->regs.r27);
3482 __put_user(env->regs[28], &sc->regs.r28);
3483 __put_user(env->regs[29], &sc->regs.r29);
3484 __put_user(env->regs[30], &sc->regs.r30);
3485 __put_user(env->regs[31], &sc->regs.r31);
3486 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3489 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3491 __get_user(env->regs[0], &sc->regs.r0);
3492 __get_user(env->regs[1], &sc->regs.r1);
3493 __get_user(env->regs[2], &sc->regs.r2);
3494 __get_user(env->regs[3], &sc->regs.r3);
3495 __get_user(env->regs[4], &sc->regs.r4);
3496 __get_user(env->regs[5], &sc->regs.r5);
3497 __get_user(env->regs[6], &sc->regs.r6);
3498 __get_user(env->regs[7], &sc->regs.r7);
3499 __get_user(env->regs[8], &sc->regs.r8);
3500 __get_user(env->regs[9], &sc->regs.r9);
3501 __get_user(env->regs[10], &sc->regs.r10);
3502 __get_user(env->regs[11], &sc->regs.r11);
3503 __get_user(env->regs[12], &sc->regs.r12);
3504 __get_user(env->regs[13], &sc->regs.r13);
3505 __get_user(env->regs[14], &sc->regs.r14);
3506 __get_user(env->regs[15], &sc->regs.r15);
3507 __get_user(env->regs[16], &sc->regs.r16);
3508 __get_user(env->regs[17], &sc->regs.r17);
3509 __get_user(env->regs[18], &sc->regs.r18);
3510 __get_user(env->regs[19], &sc->regs.r19);
3511 __get_user(env->regs[20], &sc->regs.r20);
3512 __get_user(env->regs[21], &sc->regs.r21);
3513 __get_user(env->regs[22], &sc->regs.r22);
3514 __get_user(env->regs[23], &sc->regs.r23);
3515 __get_user(env->regs[24], &sc->regs.r24);
3516 __get_user(env->regs[25], &sc->regs.r25);
3517 __get_user(env->regs[26], &sc->regs.r26);
3518 __get_user(env->regs[27], &sc->regs.r27);
3519 __get_user(env->regs[28], &sc->regs.r28);
3520 __get_user(env->regs[29], &sc->regs.r29);
3521 __get_user(env->regs[30], &sc->regs.r30);
3522 __get_user(env->regs[31], &sc->regs.r31);
3523 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3526 static abi_ulong get_sigframe(struct target_sigaction *ka,
3527 CPUMBState *env, int frame_size)
3529 abi_ulong sp = env->regs[1];
3531 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3532 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3534 return ((sp - frame_size) & -8UL);
3537 static void setup_frame(int sig, struct target_sigaction *ka,
3538 target_sigset_t *set, CPUMBState *env)
3540 struct target_signal_frame *frame;
3541 abi_ulong frame_addr;
3542 int err = 0;
3543 int i;
3545 frame_addr = get_sigframe(ka, env, sizeof *frame);
3546 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3547 goto badframe;
3549 /* Save the mask. */
3550 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3551 if (err)
3552 goto badframe;
3554 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3555 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3556 goto badframe;
3559 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3561 /* Set up to return from userspace. If provided, use a stub
3562 already in userspace. */
3563 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3564 if (ka->sa_flags & TARGET_SA_RESTORER) {
3565 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3566 } else {
3567 uint32_t t;
3568 /* Note, these encodings are _big endian_! */
3569 /* addi r12, r0, __NR_sigreturn */
3570 t = 0x31800000UL | TARGET_NR_sigreturn;
3571 err |= __put_user(t, frame->tramp + 0);
3572 /* brki r14, 0x8 */
3573 t = 0xb9cc0008UL;
3574 err |= __put_user(t, frame->tramp + 1);
3576 /* Return from sighandler will jump to the tramp.
3577 Negative 8 offset because return is rtsd r15, 8 */
3578 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3581 if (err)
3582 goto badframe;
3584 /* Set up registers for signal handler */
3585 env->regs[1] = frame_addr;
3586 /* Signal handler args: */
3587 env->regs[5] = sig; /* Arg 0: signum */
3588 env->regs[6] = 0;
3589 /* arg 1: sigcontext */
3590 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3592 /* Offset of 4 to handle microblaze rtid r14, 0 */
3593 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3595 unlock_user_struct(frame, frame_addr, 1);
3596 return;
3597 badframe:
3598 unlock_user_struct(frame, frame_addr, 1);
3599 force_sig(TARGET_SIGSEGV);
3602 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3603 target_siginfo_t *info,
3604 target_sigset_t *set, CPUMBState *env)
3606 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3609 long do_sigreturn(CPUMBState *env)
3611 struct target_signal_frame *frame;
3612 abi_ulong frame_addr;
3613 target_sigset_t target_set;
3614 sigset_t set;
3615 int i;
3617 frame_addr = env->regs[R_SP];
3618 /* Make sure the guest isn't playing games. */
3619 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3620 goto badframe;
3622 /* Restore blocked signals */
3623 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3624 goto badframe;
3625 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3626 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3627 goto badframe;
3629 target_to_host_sigset_internal(&set, &target_set);
3630 sigprocmask(SIG_SETMASK, &set, NULL);
3632 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3633 /* We got here through a sigreturn syscall, our path back is via an
3634 rtb insn so setup r14 for that. */
3635 env->regs[14] = env->sregs[SR_PC];
3637 unlock_user_struct(frame, frame_addr, 0);
3638 return env->regs[10];
3639 badframe:
3640 unlock_user_struct(frame, frame_addr, 0);
3641 force_sig(TARGET_SIGSEGV);
3644 long do_rt_sigreturn(CPUMBState *env)
3646 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3647 return -TARGET_ENOSYS;
3650 #elif defined(TARGET_CRIS)
3652 struct target_sigcontext {
3653 struct target_pt_regs regs; /* needs to be first */
3654 uint32_t oldmask;
3655 uint32_t usp; /* usp before stacking this gunk on it */
3658 /* Signal frames. */
3659 struct target_signal_frame {
3660 struct target_sigcontext sc;
3661 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3662 uint8_t retcode[8]; /* Trampoline code. */
3665 struct rt_signal_frame {
3666 siginfo_t *pinfo;
3667 void *puc;
3668 siginfo_t info;
3669 struct ucontext uc;
3670 uint8_t retcode[8]; /* Trampoline code. */
3673 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3675 __put_user(env->regs[0], &sc->regs.r0);
3676 __put_user(env->regs[1], &sc->regs.r1);
3677 __put_user(env->regs[2], &sc->regs.r2);
3678 __put_user(env->regs[3], &sc->regs.r3);
3679 __put_user(env->regs[4], &sc->regs.r4);
3680 __put_user(env->regs[5], &sc->regs.r5);
3681 __put_user(env->regs[6], &sc->regs.r6);
3682 __put_user(env->regs[7], &sc->regs.r7);
3683 __put_user(env->regs[8], &sc->regs.r8);
3684 __put_user(env->regs[9], &sc->regs.r9);
3685 __put_user(env->regs[10], &sc->regs.r10);
3686 __put_user(env->regs[11], &sc->regs.r11);
3687 __put_user(env->regs[12], &sc->regs.r12);
3688 __put_user(env->regs[13], &sc->regs.r13);
3689 __put_user(env->regs[14], &sc->usp);
3690 __put_user(env->regs[15], &sc->regs.acr);
3691 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3692 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3693 __put_user(env->pc, &sc->regs.erp);
3696 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3698 __get_user(env->regs[0], &sc->regs.r0);
3699 __get_user(env->regs[1], &sc->regs.r1);
3700 __get_user(env->regs[2], &sc->regs.r2);
3701 __get_user(env->regs[3], &sc->regs.r3);
3702 __get_user(env->regs[4], &sc->regs.r4);
3703 __get_user(env->regs[5], &sc->regs.r5);
3704 __get_user(env->regs[6], &sc->regs.r6);
3705 __get_user(env->regs[7], &sc->regs.r7);
3706 __get_user(env->regs[8], &sc->regs.r8);
3707 __get_user(env->regs[9], &sc->regs.r9);
3708 __get_user(env->regs[10], &sc->regs.r10);
3709 __get_user(env->regs[11], &sc->regs.r11);
3710 __get_user(env->regs[12], &sc->regs.r12);
3711 __get_user(env->regs[13], &sc->regs.r13);
3712 __get_user(env->regs[14], &sc->usp);
3713 __get_user(env->regs[15], &sc->regs.acr);
3714 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3715 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3716 __get_user(env->pc, &sc->regs.erp);
3719 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3721 abi_ulong sp;
3722 /* Align the stack downwards to 4. */
3723 sp = (env->regs[R_SP] & ~3);
3724 return sp - framesize;
3727 static void setup_frame(int sig, struct target_sigaction *ka,
3728 target_sigset_t *set, CPUCRISState *env)
3730 struct target_signal_frame *frame;
3731 abi_ulong frame_addr;
3732 int err = 0;
3733 int i;
3735 frame_addr = get_sigframe(env, sizeof *frame);
3736 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3737 goto badframe;
3740 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3741 * use this trampoline anymore but it sets it up for GDB.
3742 * In QEMU, using the trampoline simplifies things a bit so we use it.
3744 * This is movu.w __NR_sigreturn, r9; break 13;
3746 err |= __put_user(0x9c5f, frame->retcode+0);
3747 err |= __put_user(TARGET_NR_sigreturn,
3748 frame->retcode+2);
3749 err |= __put_user(0xe93d, frame->retcode+4);
3751 /* Save the mask. */
3752 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3753 if (err)
3754 goto badframe;
3756 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3757 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3758 goto badframe;
3761 setup_sigcontext(&frame->sc, env);
3763 /* Move the stack and setup the arguments for the handler. */
3764 env->regs[R_SP] = frame_addr;
3765 env->regs[10] = sig;
3766 env->pc = (unsigned long) ka->_sa_handler;
3767 /* Link SRP so the guest returns through the trampoline. */
3768 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3770 unlock_user_struct(frame, frame_addr, 1);
3771 return;
3772 badframe:
3773 unlock_user_struct(frame, frame_addr, 1);
3774 force_sig(TARGET_SIGSEGV);
3777 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3778 target_siginfo_t *info,
3779 target_sigset_t *set, CPUCRISState *env)
3781 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3784 long do_sigreturn(CPUCRISState *env)
3786 struct target_signal_frame *frame;
3787 abi_ulong frame_addr;
3788 target_sigset_t target_set;
3789 sigset_t set;
3790 int i;
3792 frame_addr = env->regs[R_SP];
3793 /* Make sure the guest isn't playing games. */
3794 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3795 goto badframe;
3797 /* Restore blocked signals */
3798 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3799 goto badframe;
3800 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3801 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3802 goto badframe;
3804 target_to_host_sigset_internal(&set, &target_set);
3805 sigprocmask(SIG_SETMASK, &set, NULL);
3807 restore_sigcontext(&frame->sc, env);
3808 unlock_user_struct(frame, frame_addr, 0);
3809 return env->regs[10];
3810 badframe:
3811 unlock_user_struct(frame, frame_addr, 0);
3812 force_sig(TARGET_SIGSEGV);
3815 long do_rt_sigreturn(CPUCRISState *env)
3817 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3818 return -TARGET_ENOSYS;
3821 #elif defined(TARGET_OPENRISC)
3823 struct target_sigcontext {
3824 struct target_pt_regs regs;
3825 abi_ulong oldmask;
3826 abi_ulong usp;
3829 struct target_ucontext {
3830 abi_ulong tuc_flags;
3831 abi_ulong tuc_link;
3832 target_stack_t tuc_stack;
3833 struct target_sigcontext tuc_mcontext;
3834 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3837 struct target_rt_sigframe {
3838 abi_ulong pinfo;
3839 uint64_t puc;
3840 struct target_siginfo info;
3841 struct target_sigcontext sc;
3842 struct target_ucontext uc;
3843 unsigned char retcode[16]; /* trampoline code */
3846 /* This is the asm-generic/ucontext.h version */
3847 #if 0
3848 static int restore_sigcontext(CPUOpenRISCState *regs,
3849 struct target_sigcontext *sc)
3851 unsigned int err = 0;
3852 unsigned long old_usp;
3854 /* Alwys make any pending restarted system call return -EINTR */
3855 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3857 /* restore the regs from &sc->regs (same as sc, since regs is first)
3858 * (sc is already checked for VERIFY_READ since the sigframe was
3859 * checked in sys_sigreturn previously)
3862 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3863 goto badframe;
3866 /* make sure the U-flag is set so user-mode cannot fool us */
3868 regs->sr &= ~SR_SM;
3870 /* restore the old USP as it was before we stacked the sc etc.
3871 * (we cannot just pop the sigcontext since we aligned the sp and
3872 * stuff after pushing it)
3875 err |= __get_user(old_usp, &sc->usp);
3876 phx_signal("old_usp 0x%lx", old_usp);
3878 __PHX__ REALLY /* ??? */
3879 wrusp(old_usp);
3880 regs->gpr[1] = old_usp;
3882 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3883 * after this completes, but we don't use that mechanism. maybe we can
3884 * use it now ?
3887 return err;
3889 badframe:
3890 return 1;
3892 #endif
3894 /* Set up a signal frame. */
3896 static int setup_sigcontext(struct target_sigcontext *sc,
3897 CPUOpenRISCState *regs,
3898 unsigned long mask)
3900 int err = 0;
3901 unsigned long usp = regs->gpr[1];
3903 /* copy the regs. they are first in sc so we can use sc directly */
3905 /*err |= copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3907 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3908 the signal handler. The frametype will be restored to its previous
3909 value in restore_sigcontext. */
3910 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3912 /* then some other stuff */
3913 err |= __put_user(mask, &sc->oldmask);
3914 err |= __put_user(usp, &sc->usp); return err;
3917 static inline unsigned long align_sigframe(unsigned long sp)
3919 unsigned long i;
3920 i = sp & ~3UL;
3921 return i;
3924 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3925 CPUOpenRISCState *regs,
3926 size_t frame_size)
3928 unsigned long sp = regs->gpr[1];
3929 int onsigstack = on_sig_stack(sp);
3931 /* redzone */
3932 /* This is the X/Open sanctioned signal stack switching. */
3933 if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
3934 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3937 sp = align_sigframe(sp - frame_size);
3940 * If we are on the alternate signal stack and would overflow it, don't.
3941 * Return an always-bogus address instead so we will die with SIGSEGV.
3944 if (onsigstack && !likely(on_sig_stack(sp))) {
3945 return -1L;
3948 return sp;
3951 static void setup_frame(int sig, struct target_sigaction *ka,
3952 target_sigset_t *set, CPUOpenRISCState *env)
3954 qemu_log("Not implement.\n");
3957 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3958 target_siginfo_t *info,
3959 target_sigset_t *set, CPUOpenRISCState *env)
3961 int err = 0;
3962 abi_ulong frame_addr;
3963 unsigned long return_ip;
3964 struct target_rt_sigframe *frame;
3965 abi_ulong info_addr, uc_addr;
3967 frame_addr = get_sigframe(ka, env, sizeof *frame);
3969 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3970 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3971 goto give_sigsegv;
3974 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
3975 err |= __put_user(info_addr, &frame->pinfo);
3976 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
3977 err |= __put_user(uc_addr, &frame->puc);
3979 if (ka->sa_flags & SA_SIGINFO) {
3980 err |= copy_siginfo_to_user(&frame->info, info);
3982 if (err) {
3983 goto give_sigsegv;
3986 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3987 err |= __put_user(0, &frame->uc.tuc_flags);
3988 err |= __put_user(0, &frame->uc.tuc_link);
3989 err |= __put_user(target_sigaltstack_used.ss_sp,
3990 &frame->uc.tuc_stack.ss_sp);
3991 err |= __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
3992 err |= __put_user(target_sigaltstack_used.ss_size,
3993 &frame->uc.tuc_stack.ss_size);
3994 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
3996 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3998 if (err) {
3999 goto give_sigsegv;
4002 /* trampoline - the desired return ip is the retcode itself */
4003 return_ip = (unsigned long)&frame->retcode;
4004 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
4005 err |= __put_user(0xa960, (short *)(frame->retcode + 0));
4006 err |= __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
4007 err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
4008 err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
4010 if (err) {
4011 goto give_sigsegv;
4014 /* TODO what is the current->exec_domain stuff and invmap ? */
4016 /* Set up registers for signal handler */
4017 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
4018 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
4019 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
4020 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
4021 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
4023 /* actually move the usp to reflect the stacked frame */
4024 env->gpr[1] = (unsigned long)frame;
4026 return;
4028 give_sigsegv:
4029 unlock_user_struct(frame, frame_addr, 1);
4030 if (sig == TARGET_SIGSEGV) {
4031 ka->_sa_handler = TARGET_SIG_DFL;
4033 force_sig(TARGET_SIGSEGV);
4036 long do_sigreturn(CPUOpenRISCState *env)
4039 qemu_log("do_sigreturn: not implemented\n");
4040 return -TARGET_ENOSYS;
4043 long do_rt_sigreturn(CPUOpenRISCState *env)
4045 qemu_log("do_rt_sigreturn: not implemented\n");
4046 return -TARGET_ENOSYS;
4048 /* TARGET_OPENRISC */
4050 #elif defined(TARGET_S390X)
4052 #define __NUM_GPRS 16
4053 #define __NUM_FPRS 16
4054 #define __NUM_ACRS 16
4056 #define S390_SYSCALL_SIZE 2
4057 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4059 #define _SIGCONTEXT_NSIG 64
4060 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4061 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4062 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4063 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4064 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4066 typedef struct {
4067 target_psw_t psw;
4068 target_ulong gprs[__NUM_GPRS];
4069 unsigned int acrs[__NUM_ACRS];
4070 } target_s390_regs_common;
4072 typedef struct {
4073 unsigned int fpc;
4074 double fprs[__NUM_FPRS];
4075 } target_s390_fp_regs;
4077 typedef struct {
4078 target_s390_regs_common regs;
4079 target_s390_fp_regs fpregs;
4080 } target_sigregs;
4082 struct target_sigcontext {
4083 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4084 target_sigregs *sregs;
4087 typedef struct {
4088 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4089 struct target_sigcontext sc;
4090 target_sigregs sregs;
4091 int signo;
4092 uint8_t retcode[S390_SYSCALL_SIZE];
4093 } sigframe;
4095 struct target_ucontext {
4096 target_ulong tuc_flags;
4097 struct target_ucontext *tuc_link;
4098 target_stack_t tuc_stack;
4099 target_sigregs tuc_mcontext;
4100 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4103 typedef struct {
4104 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4105 uint8_t retcode[S390_SYSCALL_SIZE];
4106 struct target_siginfo info;
4107 struct target_ucontext uc;
4108 } rt_sigframe;
4110 static inline abi_ulong
4111 get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4113 abi_ulong sp;
4115 /* Default to using normal stack */
4116 sp = env->regs[15];
4118 /* This is the X/Open sanctioned signal stack switching. */
4119 if (ka->sa_flags & TARGET_SA_ONSTACK) {
4120 if (!sas_ss_flags(sp)) {
4121 sp = target_sigaltstack_used.ss_sp +
4122 target_sigaltstack_used.ss_size;
4126 /* This is the legacy signal stack switching. */
4127 else if (/* FIXME !user_mode(regs) */ 0 &&
4128 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4129 ka->sa_restorer) {
4130 sp = (abi_ulong) ka->sa_restorer;
4133 return (sp - frame_size) & -8ul;
4136 static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4138 int i;
4139 //save_access_regs(current->thread.acrs); FIXME
4141 /* Copy a 'clean' PSW mask to the user to avoid leaking
4142 information about whether PER is currently on. */
4143 __put_user(env->psw.mask, &sregs->regs.psw.mask);
4144 __put_user(env->psw.addr, &sregs->regs.psw.addr);
4145 for (i = 0; i < 16; i++) {
4146 __put_user(env->regs[i], &sregs->regs.gprs[i]);
4148 for (i = 0; i < 16; i++) {
4149 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
4152 * We have to store the fp registers to current->thread.fp_regs
4153 * to merge them with the emulated registers.
4155 //save_fp_regs(&current->thread.fp_regs); FIXME
4156 for (i = 0; i < 16; i++) {
4157 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4161 static void setup_frame(int sig, struct target_sigaction *ka,
4162 target_sigset_t *set, CPUS390XState *env)
4164 sigframe *frame;
4165 abi_ulong frame_addr;
4167 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4168 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4169 (unsigned long long)frame_addr);
4170 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4171 goto give_sigsegv;
4174 qemu_log("%s: 1\n", __FUNCTION__);
4175 if (__put_user(set->sig[0], &frame->sc.oldmask[0])) {
4176 goto give_sigsegv;
4179 save_sigregs(env, &frame->sregs);
4181 __put_user((abi_ulong)(unsigned long)&frame->sregs,
4182 (abi_ulong *)&frame->sc.sregs);
4184 /* Set up to return from userspace. If provided, use a stub
4185 already in userspace. */
4186 if (ka->sa_flags & TARGET_SA_RESTORER) {
4187 env->regs[14] = (unsigned long)
4188 ka->sa_restorer | PSW_ADDR_AMODE;
4189 } else {
4190 env->regs[14] = (unsigned long)
4191 frame->retcode | PSW_ADDR_AMODE;
4192 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
4193 (uint16_t *)(frame->retcode)))
4194 goto give_sigsegv;
4197 /* Set up backchain. */
4198 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4199 goto give_sigsegv;
4202 /* Set up registers for signal handler */
4203 env->regs[15] = frame_addr;
4204 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4206 env->regs[2] = sig; //map_signal(sig);
4207 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
4209 /* We forgot to include these in the sigcontext.
4210 To avoid breaking binary compatibility, they are passed as args. */
4211 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4212 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4214 /* Place signal number on stack to allow backtrace from handler. */
4215 if (__put_user(env->regs[2], (int *) &frame->signo)) {
4216 goto give_sigsegv;
4218 unlock_user_struct(frame, frame_addr, 1);
4219 return;
4221 give_sigsegv:
4222 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4223 unlock_user_struct(frame, frame_addr, 1);
4224 force_sig(TARGET_SIGSEGV);
4227 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4228 target_siginfo_t *info,
4229 target_sigset_t *set, CPUS390XState *env)
4231 int i;
4232 rt_sigframe *frame;
4233 abi_ulong frame_addr;
4235 frame_addr = get_sigframe(ka, env, sizeof *frame);
4236 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4237 (unsigned long long)frame_addr);
4238 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4239 goto give_sigsegv;
4242 qemu_log("%s: 1\n", __FUNCTION__);
4243 if (copy_siginfo_to_user(&frame->info, info)) {
4244 goto give_sigsegv;
4247 /* Create the ucontext. */
4248 __put_user(0, &frame->uc.tuc_flags);
4249 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
4250 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
4251 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
4252 &frame->uc.tuc_stack.ss_flags);
4253 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
4254 save_sigregs(env, &frame->uc.tuc_mcontext);
4255 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
4256 __put_user((abi_ulong)set->sig[i],
4257 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
4260 /* Set up to return from userspace. If provided, use a stub
4261 already in userspace. */
4262 if (ka->sa_flags & TARGET_SA_RESTORER) {
4263 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4264 } else {
4265 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4266 if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
4267 (uint16_t *)(frame->retcode))) {
4268 goto give_sigsegv;
4272 /* Set up backchain. */
4273 if (__put_user(env->regs[15], (abi_ulong *) frame)) {
4274 goto give_sigsegv;
4277 /* Set up registers for signal handler */
4278 env->regs[15] = frame_addr;
4279 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4281 env->regs[2] = sig; //map_signal(sig);
4282 env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
4283 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
4284 return;
4286 give_sigsegv:
4287 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4288 unlock_user_struct(frame, frame_addr, 1);
4289 force_sig(TARGET_SIGSEGV);
4292 static int
4293 restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4295 int err = 0;
4296 int i;
4298 for (i = 0; i < 16; i++) {
4299 err |= __get_user(env->regs[i], &sc->regs.gprs[i]);
4302 err |= __get_user(env->psw.mask, &sc->regs.psw.mask);
4303 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4304 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4305 (unsigned long long)env->psw.addr);
4306 err |= __get_user(env->psw.addr, &sc->regs.psw.addr);
4307 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4309 for (i = 0; i < 16; i++) {
4310 err |= __get_user(env->aregs[i], &sc->regs.acrs[i]);
4312 for (i = 0; i < 16; i++) {
4313 err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4316 return err;
4319 long do_sigreturn(CPUS390XState *env)
4321 sigframe *frame;
4322 abi_ulong frame_addr = env->regs[15];
4323 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4324 (unsigned long long)frame_addr);
4325 target_sigset_t target_set;
4326 sigset_t set;
4328 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4329 goto badframe;
4331 if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) {
4332 goto badframe;
4335 target_to_host_sigset_internal(&set, &target_set);
4336 sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4338 if (restore_sigregs(env, &frame->sregs)) {
4339 goto badframe;
4342 unlock_user_struct(frame, frame_addr, 0);
4343 return env->regs[2];
4345 badframe:
4346 unlock_user_struct(frame, frame_addr, 0);
4347 force_sig(TARGET_SIGSEGV);
4348 return 0;
4351 long do_rt_sigreturn(CPUS390XState *env)
4353 rt_sigframe *frame;
4354 abi_ulong frame_addr = env->regs[15];
4355 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4356 (unsigned long long)frame_addr);
4357 sigset_t set;
4359 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4360 goto badframe;
4362 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4364 sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4366 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4367 goto badframe;
4370 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4371 get_sp_from_cpustate(env)) == -EFAULT) {
4372 goto badframe;
4374 unlock_user_struct(frame, frame_addr, 0);
4375 return env->regs[2];
4377 badframe:
4378 unlock_user_struct(frame, frame_addr, 0);
4379 force_sig(TARGET_SIGSEGV);
4380 return 0;
4383 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4385 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4386 the signal handling is different enough that we haven't implemented
4387 support for PPC64 yet. Hence the restriction above.
4389 There are various #if'd blocks for code for TARGET_PPC64. These
4390 blocks should go away so that we can successfully run 32-bit and
4391 64-bit binaries on a QEMU configured for PPC64. */
4393 /* Size of dummy stack frame allocated when calling signal handler.
4394 See arch/powerpc/include/asm/ptrace.h. */
4395 #if defined(TARGET_PPC64)
4396 #define SIGNAL_FRAMESIZE 128
4397 #else
4398 #define SIGNAL_FRAMESIZE 64
4399 #endif
4401 /* See arch/powerpc/include/asm/sigcontext.h. */
4402 struct target_sigcontext {
4403 target_ulong _unused[4];
4404 int32_t signal;
4405 #if defined(TARGET_PPC64)
4406 int32_t pad0;
4407 #endif
4408 target_ulong handler;
4409 target_ulong oldmask;
4410 target_ulong regs; /* struct pt_regs __user * */
4411 /* TODO: PPC64 includes extra bits here. */
4414 /* Indices for target_mcontext.mc_gregs, below.
4415 See arch/powerpc/include/asm/ptrace.h for details. */
4416 enum {
4417 TARGET_PT_R0 = 0,
4418 TARGET_PT_R1 = 1,
4419 TARGET_PT_R2 = 2,
4420 TARGET_PT_R3 = 3,
4421 TARGET_PT_R4 = 4,
4422 TARGET_PT_R5 = 5,
4423 TARGET_PT_R6 = 6,
4424 TARGET_PT_R7 = 7,
4425 TARGET_PT_R8 = 8,
4426 TARGET_PT_R9 = 9,
4427 TARGET_PT_R10 = 10,
4428 TARGET_PT_R11 = 11,
4429 TARGET_PT_R12 = 12,
4430 TARGET_PT_R13 = 13,
4431 TARGET_PT_R14 = 14,
4432 TARGET_PT_R15 = 15,
4433 TARGET_PT_R16 = 16,
4434 TARGET_PT_R17 = 17,
4435 TARGET_PT_R18 = 18,
4436 TARGET_PT_R19 = 19,
4437 TARGET_PT_R20 = 20,
4438 TARGET_PT_R21 = 21,
4439 TARGET_PT_R22 = 22,
4440 TARGET_PT_R23 = 23,
4441 TARGET_PT_R24 = 24,
4442 TARGET_PT_R25 = 25,
4443 TARGET_PT_R26 = 26,
4444 TARGET_PT_R27 = 27,
4445 TARGET_PT_R28 = 28,
4446 TARGET_PT_R29 = 29,
4447 TARGET_PT_R30 = 30,
4448 TARGET_PT_R31 = 31,
4449 TARGET_PT_NIP = 32,
4450 TARGET_PT_MSR = 33,
4451 TARGET_PT_ORIG_R3 = 34,
4452 TARGET_PT_CTR = 35,
4453 TARGET_PT_LNK = 36,
4454 TARGET_PT_XER = 37,
4455 TARGET_PT_CCR = 38,
4456 /* Yes, there are two registers with #39. One is 64-bit only. */
4457 TARGET_PT_MQ = 39,
4458 TARGET_PT_SOFTE = 39,
4459 TARGET_PT_TRAP = 40,
4460 TARGET_PT_DAR = 41,
4461 TARGET_PT_DSISR = 42,
4462 TARGET_PT_RESULT = 43,
4463 TARGET_PT_REGS_COUNT = 44
4466 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4467 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4468 struct target_mcontext {
4469 target_ulong mc_gregs[48];
4470 /* Includes fpscr. */
4471 uint64_t mc_fregs[33];
4472 target_ulong mc_pad[2];
4473 /* We need to handle Altivec and SPE at the same time, which no
4474 kernel needs to do. Fortunately, the kernel defines this bit to
4475 be Altivec-register-large all the time, rather than trying to
4476 twiddle it based on the specific platform. */
4477 union {
4478 /* SPE vector registers. One extra for SPEFSCR. */
4479 uint32_t spe[33];
4480 /* Altivec vector registers. The packing of VSCR and VRSAVE
4481 varies depending on whether we're PPC64 or not: PPC64 splits
4482 them apart; PPC32 stuffs them together. */
4483 #if defined(TARGET_PPC64)
4484 #define QEMU_NVRREG 34
4485 #else
4486 #define QEMU_NVRREG 33
4487 #endif
4488 ppc_avr_t altivec[QEMU_NVRREG];
4489 #undef QEMU_NVRREG
4490 } mc_vregs __attribute__((__aligned__(16)));
4493 struct target_ucontext {
4494 target_ulong tuc_flags;
4495 target_ulong tuc_link; /* struct ucontext __user * */
4496 struct target_sigaltstack tuc_stack;
4497 #if !defined(TARGET_PPC64)
4498 int32_t tuc_pad[7];
4499 target_ulong tuc_regs; /* struct mcontext __user *
4500 points to uc_mcontext field */
4501 #endif
4502 target_sigset_t tuc_sigmask;
4503 #if defined(TARGET_PPC64)
4504 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4505 struct target_sigcontext tuc_mcontext;
4506 #else
4507 int32_t tuc_maskext[30];
4508 int32_t tuc_pad2[3];
4509 struct target_mcontext tuc_mcontext;
4510 #endif
4513 /* See arch/powerpc/kernel/signal_32.c. */
4514 struct target_sigframe {
4515 struct target_sigcontext sctx;
4516 struct target_mcontext mctx;
4517 int32_t abigap[56];
4520 struct target_rt_sigframe {
4521 struct target_siginfo info;
4522 struct target_ucontext uc;
4523 int32_t abigap[56];
4526 /* We use the mc_pad field for the signal return trampoline. */
4527 #define tramp mc_pad
4529 /* See arch/powerpc/kernel/signal.c. */
4530 static target_ulong get_sigframe(struct target_sigaction *ka,
4531 CPUPPCState *env,
4532 int frame_size)
4534 target_ulong oldsp, newsp;
4536 oldsp = env->gpr[1];
4538 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4539 (sas_ss_flags(oldsp) == 0)) {
4540 oldsp = (target_sigaltstack_used.ss_sp
4541 + target_sigaltstack_used.ss_size);
4544 newsp = (oldsp - frame_size) & ~0xFUL;
4546 return newsp;
4549 static int save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4550 int sigret)
4552 target_ulong msr = env->msr;
4553 int i;
4554 target_ulong ccr = 0;
4556 /* In general, the kernel attempts to be intelligent about what it
4557 needs to save for Altivec/FP/SPE registers. We don't care that
4558 much, so we just go ahead and save everything. */
4560 /* Save general registers. */
4561 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4562 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
4563 return 1;
4566 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4567 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4568 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4569 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4570 return 1;
4572 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4573 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4575 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4576 return 1;
4578 /* Save Altivec registers if necessary. */
4579 if (env->insns_flags & PPC_ALTIVEC) {
4580 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4581 ppc_avr_t *avr = &env->avr[i];
4582 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4584 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
4585 __put_user(avr->u64[1], &vreg->u64[1])) {
4586 return 1;
4589 /* Set MSR_VR in the saved MSR value to indicate that
4590 frame->mc_vregs contains valid data. */
4591 msr |= MSR_VR;
4592 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
4593 &frame->mc_vregs.altivec[32].u32[3]))
4594 return 1;
4597 /* Save floating point registers. */
4598 if (env->insns_flags & PPC_FLOAT) {
4599 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4600 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
4601 return 1;
4604 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
4605 return 1;
4608 /* Save SPE registers. The kernel only saves the high half. */
4609 if (env->insns_flags & PPC_SPE) {
4610 #if defined(TARGET_PPC64)
4611 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4612 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
4613 return 1;
4616 #else
4617 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4618 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4619 return 1;
4622 #endif
4623 /* Set MSR_SPE in the saved MSR value to indicate that
4624 frame->mc_vregs contains valid data. */
4625 msr |= MSR_SPE;
4626 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4627 return 1;
4630 /* Store MSR. */
4631 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4632 return 1;
4634 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4635 if (sigret) {
4636 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
4637 __put_user(0x44000002UL, &frame->tramp[1])) {
4638 return 1;
4642 return 0;
4645 static int restore_user_regs(CPUPPCState *env,
4646 struct target_mcontext *frame, int sig)
4648 target_ulong save_r2 = 0;
4649 target_ulong msr;
4650 target_ulong ccr;
4652 int i;
4654 if (!sig) {
4655 save_r2 = env->gpr[2];
4658 /* Restore general registers. */
4659 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4660 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
4661 return 1;
4664 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
4665 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
4666 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
4667 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
4668 return 1;
4669 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
4670 return 1;
4672 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4673 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4676 if (!sig) {
4677 env->gpr[2] = save_r2;
4679 /* Restore MSR. */
4680 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
4681 return 1;
4683 /* If doing signal return, restore the previous little-endian mode. */
4684 if (sig)
4685 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4687 /* Restore Altivec registers if necessary. */
4688 if (env->insns_flags & PPC_ALTIVEC) {
4689 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4690 ppc_avr_t *avr = &env->avr[i];
4691 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4693 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
4694 __get_user(avr->u64[1], &vreg->u64[1])) {
4695 return 1;
4698 /* Set MSR_VEC in the saved MSR value to indicate that
4699 frame->mc_vregs contains valid data. */
4700 if (__get_user(env->spr[SPR_VRSAVE],
4701 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
4702 return 1;
4705 /* Restore floating point registers. */
4706 if (env->insns_flags & PPC_FLOAT) {
4707 uint64_t fpscr;
4708 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4709 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
4710 return 1;
4713 if (__get_user(fpscr, &frame->mc_fregs[32]))
4714 return 1;
4715 env->fpscr = (uint32_t) fpscr;
4718 /* Save SPE registers. The kernel only saves the high half. */
4719 if (env->insns_flags & PPC_SPE) {
4720 #if defined(TARGET_PPC64)
4721 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4722 uint32_t hi;
4724 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
4725 return 1;
4727 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4729 #else
4730 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4731 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
4732 return 1;
4735 #endif
4736 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
4737 return 1;
4740 return 0;
4743 static void setup_frame(int sig, struct target_sigaction *ka,
4744 target_sigset_t *set, CPUPPCState *env)
4746 struct target_sigframe *frame;
4747 struct target_sigcontext *sc;
4748 target_ulong frame_addr, newsp;
4749 int err = 0;
4750 int signal;
4752 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4753 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4754 goto sigsegv;
4755 sc = &frame->sctx;
4757 signal = current_exec_domain_sig(sig);
4759 err |= __put_user(ka->_sa_handler, &sc->handler);
4760 err |= __put_user(set->sig[0], &sc->oldmask);
4761 #if defined(TARGET_PPC64)
4762 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4763 #else
4764 err |= __put_user(set->sig[1], &sc->_unused[3]);
4765 #endif
4766 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4767 err |= __put_user(sig, &sc->signal);
4769 /* Save user regs. */
4770 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4772 /* The kernel checks for the presence of a VDSO here. We don't
4773 emulate a vdso, so use a sigreturn system call. */
4774 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4776 /* Turn off all fp exceptions. */
4777 env->fpscr = 0;
4779 /* Create a stack frame for the caller of the handler. */
4780 newsp = frame_addr - SIGNAL_FRAMESIZE;
4781 err |= put_user(env->gpr[1], newsp, target_ulong);
4783 if (err)
4784 goto sigsegv;
4786 /* Set up registers for signal handler. */
4787 env->gpr[1] = newsp;
4788 env->gpr[3] = signal;
4789 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
4790 env->nip = (target_ulong) ka->_sa_handler;
4791 /* Signal handlers are entered in big-endian mode. */
4792 env->msr &= ~MSR_LE;
4794 unlock_user_struct(frame, frame_addr, 1);
4795 return;
4797 sigsegv:
4798 unlock_user_struct(frame, frame_addr, 1);
4799 qemu_log("segfaulting from setup_frame\n");
4800 force_sig(TARGET_SIGSEGV);
4803 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4804 target_siginfo_t *info,
4805 target_sigset_t *set, CPUPPCState *env)
4807 struct target_rt_sigframe *rt_sf;
4808 struct target_mcontext *frame;
4809 target_ulong rt_sf_addr, newsp = 0;
4810 int i, err = 0;
4811 int signal;
4813 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4814 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4815 goto sigsegv;
4817 signal = current_exec_domain_sig(sig);
4819 err |= copy_siginfo_to_user(&rt_sf->info, info);
4821 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4822 err |= __put_user(0, &rt_sf->uc.tuc_link);
4823 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4824 &rt_sf->uc.tuc_stack.ss_sp);
4825 err |= __put_user(sas_ss_flags(env->gpr[1]),
4826 &rt_sf->uc.tuc_stack.ss_flags);
4827 err |= __put_user(target_sigaltstack_used.ss_size,
4828 &rt_sf->uc.tuc_stack.ss_size);
4829 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4830 &rt_sf->uc.tuc_regs);
4831 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4832 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4835 frame = &rt_sf->uc.tuc_mcontext;
4836 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4838 /* The kernel checks for the presence of a VDSO here. We don't
4839 emulate a vdso, so use a sigreturn system call. */
4840 env->lr = (target_ulong) h2g(frame->tramp);
4842 /* Turn off all fp exceptions. */
4843 env->fpscr = 0;
4845 /* Create a stack frame for the caller of the handler. */
4846 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4847 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4849 if (err)
4850 goto sigsegv;
4852 /* Set up registers for signal handler. */
4853 env->gpr[1] = newsp;
4854 env->gpr[3] = (target_ulong) signal;
4855 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4856 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4857 env->gpr[6] = (target_ulong) h2g(rt_sf);
4858 env->nip = (target_ulong) ka->_sa_handler;
4859 /* Signal handlers are entered in big-endian mode. */
4860 env->msr &= ~MSR_LE;
4862 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4863 return;
4865 sigsegv:
4866 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4867 qemu_log("segfaulting from setup_rt_frame\n");
4868 force_sig(TARGET_SIGSEGV);
4872 long do_sigreturn(CPUPPCState *env)
4874 struct target_sigcontext *sc = NULL;
4875 struct target_mcontext *sr = NULL;
4876 target_ulong sr_addr = 0, sc_addr;
4877 sigset_t blocked;
4878 target_sigset_t set;
4880 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4881 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4882 goto sigsegv;
4884 #if defined(TARGET_PPC64)
4885 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4886 #else
4887 if(__get_user(set.sig[0], &sc->oldmask) ||
4888 __get_user(set.sig[1], &sc->_unused[3]))
4889 goto sigsegv;
4890 #endif
4891 target_to_host_sigset_internal(&blocked, &set);
4892 sigprocmask(SIG_SETMASK, &blocked, NULL);
4894 if (__get_user(sr_addr, &sc->regs))
4895 goto sigsegv;
4896 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4897 goto sigsegv;
4898 if (restore_user_regs(env, sr, 1))
4899 goto sigsegv;
4901 unlock_user_struct(sr, sr_addr, 1);
4902 unlock_user_struct(sc, sc_addr, 1);
4903 return -TARGET_QEMU_ESIGRETURN;
4905 sigsegv:
4906 unlock_user_struct(sr, sr_addr, 1);
4907 unlock_user_struct(sc, sc_addr, 1);
4908 qemu_log("segfaulting from do_sigreturn\n");
4909 force_sig(TARGET_SIGSEGV);
4910 return 0;
4913 /* See arch/powerpc/kernel/signal_32.c. */
4914 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4916 struct target_mcontext *mcp;
4917 target_ulong mcp_addr;
4918 sigset_t blocked;
4919 target_sigset_t set;
4921 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4922 sizeof (set)))
4923 return 1;
4925 #if defined(TARGET_PPC64)
4926 fprintf (stderr, "do_setcontext: not implemented\n");
4927 return 0;
4928 #else
4929 if (__get_user(mcp_addr, &ucp->tuc_regs))
4930 return 1;
4932 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4933 return 1;
4935 target_to_host_sigset_internal(&blocked, &set);
4936 sigprocmask(SIG_SETMASK, &blocked, NULL);
4937 if (restore_user_regs(env, mcp, sig))
4938 goto sigsegv;
4940 unlock_user_struct(mcp, mcp_addr, 1);
4941 return 0;
4943 sigsegv:
4944 unlock_user_struct(mcp, mcp_addr, 1);
4945 return 1;
4946 #endif
4949 long do_rt_sigreturn(CPUPPCState *env)
4951 struct target_rt_sigframe *rt_sf = NULL;
4952 target_ulong rt_sf_addr;
4954 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4955 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4956 goto sigsegv;
4958 if (do_setcontext(&rt_sf->uc, env, 1))
4959 goto sigsegv;
4961 do_sigaltstack(rt_sf_addr
4962 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4963 0, env->gpr[1]);
4965 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4966 return -TARGET_QEMU_ESIGRETURN;
4968 sigsegv:
4969 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4970 qemu_log("segfaulting from do_rt_sigreturn\n");
4971 force_sig(TARGET_SIGSEGV);
4972 return 0;
4975 #elif defined(TARGET_M68K)
4977 struct target_sigcontext {
4978 abi_ulong sc_mask;
4979 abi_ulong sc_usp;
4980 abi_ulong sc_d0;
4981 abi_ulong sc_d1;
4982 abi_ulong sc_a0;
4983 abi_ulong sc_a1;
4984 unsigned short sc_sr;
4985 abi_ulong sc_pc;
4988 struct target_sigframe
4990 abi_ulong pretcode;
4991 int sig;
4992 int code;
4993 abi_ulong psc;
4994 char retcode[8];
4995 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4996 struct target_sigcontext sc;
4999 typedef int target_greg_t;
5000 #define TARGET_NGREG 18
5001 typedef target_greg_t target_gregset_t[TARGET_NGREG];
5003 typedef struct target_fpregset {
5004 int f_fpcntl[3];
5005 int f_fpregs[8*3];
5006 } target_fpregset_t;
5008 struct target_mcontext {
5009 int version;
5010 target_gregset_t gregs;
5011 target_fpregset_t fpregs;
5014 #define TARGET_MCONTEXT_VERSION 2
5016 struct target_ucontext {
5017 abi_ulong tuc_flags;
5018 abi_ulong tuc_link;
5019 target_stack_t tuc_stack;
5020 struct target_mcontext tuc_mcontext;
5021 abi_long tuc_filler[80];
5022 target_sigset_t tuc_sigmask;
5025 struct target_rt_sigframe
5027 abi_ulong pretcode;
5028 int sig;
5029 abi_ulong pinfo;
5030 abi_ulong puc;
5031 char retcode[8];
5032 struct target_siginfo info;
5033 struct target_ucontext uc;
5036 static int
5037 setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
5038 abi_ulong mask)
5040 int err = 0;
5042 err |= __put_user(mask, &sc->sc_mask);
5043 err |= __put_user(env->aregs[7], &sc->sc_usp);
5044 err |= __put_user(env->dregs[0], &sc->sc_d0);
5045 err |= __put_user(env->dregs[1], &sc->sc_d1);
5046 err |= __put_user(env->aregs[0], &sc->sc_a0);
5047 err |= __put_user(env->aregs[1], &sc->sc_a1);
5048 err |= __put_user(env->sr, &sc->sc_sr);
5049 err |= __put_user(env->pc, &sc->sc_pc);
5051 return err;
5054 static int
5055 restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
5057 int err = 0;
5058 int temp;
5060 err |= __get_user(env->aregs[7], &sc->sc_usp);
5061 err |= __get_user(env->dregs[1], &sc->sc_d1);
5062 err |= __get_user(env->aregs[0], &sc->sc_a0);
5063 err |= __get_user(env->aregs[1], &sc->sc_a1);
5064 err |= __get_user(env->pc, &sc->sc_pc);
5065 err |= __get_user(temp, &sc->sc_sr);
5066 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5068 *pd0 = tswapl(sc->sc_d0);
5070 return err;
5074 * Determine which stack to use..
5076 static inline abi_ulong
5077 get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5078 size_t frame_size)
5080 unsigned long sp;
5082 sp = regs->aregs[7];
5084 /* This is the X/Open sanctioned signal stack switching. */
5085 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
5086 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5089 return ((sp - frame_size) & -8UL);
5092 static void setup_frame(int sig, struct target_sigaction *ka,
5093 target_sigset_t *set, CPUM68KState *env)
5095 struct target_sigframe *frame;
5096 abi_ulong frame_addr;
5097 abi_ulong retcode_addr;
5098 abi_ulong sc_addr;
5099 int err = 0;
5100 int i;
5102 frame_addr = get_sigframe(ka, env, sizeof *frame);
5103 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5104 goto give_sigsegv;
5106 err |= __put_user(sig, &frame->sig);
5108 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
5109 err |= __put_user(sc_addr, &frame->psc);
5111 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
5112 if (err)
5113 goto give_sigsegv;
5115 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5116 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
5117 goto give_sigsegv;
5120 /* Set up to return from userspace. */
5122 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5123 err |= __put_user(retcode_addr, &frame->pretcode);
5125 /* moveq #,d0; trap #0 */
5127 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5128 (long *)(frame->retcode));
5130 if (err)
5131 goto give_sigsegv;
5133 /* Set up to return from userspace */
5135 env->aregs[7] = frame_addr;
5136 env->pc = ka->_sa_handler;
5138 unlock_user_struct(frame, frame_addr, 1);
5139 return;
5141 give_sigsegv:
5142 unlock_user_struct(frame, frame_addr, 1);
5143 force_sig(TARGET_SIGSEGV);
5146 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5147 CPUM68KState *env)
5149 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5150 int err;
5152 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
5153 err |= __put_user(env->dregs[0], &gregs[0]);
5154 err |= __put_user(env->dregs[1], &gregs[1]);
5155 err |= __put_user(env->dregs[2], &gregs[2]);
5156 err |= __put_user(env->dregs[3], &gregs[3]);
5157 err |= __put_user(env->dregs[4], &gregs[4]);
5158 err |= __put_user(env->dregs[5], &gregs[5]);
5159 err |= __put_user(env->dregs[6], &gregs[6]);
5160 err |= __put_user(env->dregs[7], &gregs[7]);
5161 err |= __put_user(env->aregs[0], &gregs[8]);
5162 err |= __put_user(env->aregs[1], &gregs[9]);
5163 err |= __put_user(env->aregs[2], &gregs[10]);
5164 err |= __put_user(env->aregs[3], &gregs[11]);
5165 err |= __put_user(env->aregs[4], &gregs[12]);
5166 err |= __put_user(env->aregs[5], &gregs[13]);
5167 err |= __put_user(env->aregs[6], &gregs[14]);
5168 err |= __put_user(env->aregs[7], &gregs[15]);
5169 err |= __put_user(env->pc, &gregs[16]);
5170 err |= __put_user(env->sr, &gregs[17]);
5172 return err;
5175 static inline int target_rt_restore_ucontext(CPUM68KState *env,
5176 struct target_ucontext *uc,
5177 int *pd0)
5179 int temp;
5180 int err;
5181 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5183 err = __get_user(temp, &uc->tuc_mcontext.version);
5184 if (temp != TARGET_MCONTEXT_VERSION)
5185 goto badframe;
5187 /* restore passed registers */
5188 err |= __get_user(env->dregs[0], &gregs[0]);
5189 err |= __get_user(env->dregs[1], &gregs[1]);
5190 err |= __get_user(env->dregs[2], &gregs[2]);
5191 err |= __get_user(env->dregs[3], &gregs[3]);
5192 err |= __get_user(env->dregs[4], &gregs[4]);
5193 err |= __get_user(env->dregs[5], &gregs[5]);
5194 err |= __get_user(env->dregs[6], &gregs[6]);
5195 err |= __get_user(env->dregs[7], &gregs[7]);
5196 err |= __get_user(env->aregs[0], &gregs[8]);
5197 err |= __get_user(env->aregs[1], &gregs[9]);
5198 err |= __get_user(env->aregs[2], &gregs[10]);
5199 err |= __get_user(env->aregs[3], &gregs[11]);
5200 err |= __get_user(env->aregs[4], &gregs[12]);
5201 err |= __get_user(env->aregs[5], &gregs[13]);
5202 err |= __get_user(env->aregs[6], &gregs[14]);
5203 err |= __get_user(env->aregs[7], &gregs[15]);
5204 err |= __get_user(env->pc, &gregs[16]);
5205 err |= __get_user(temp, &gregs[17]);
5206 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5208 *pd0 = env->dregs[0];
5209 return err;
5211 badframe:
5212 return 1;
5215 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5216 target_siginfo_t *info,
5217 target_sigset_t *set, CPUM68KState *env)
5219 struct target_rt_sigframe *frame;
5220 abi_ulong frame_addr;
5221 abi_ulong retcode_addr;
5222 abi_ulong info_addr;
5223 abi_ulong uc_addr;
5224 int err = 0;
5225 int i;
5227 frame_addr = get_sigframe(ka, env, sizeof *frame);
5228 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5229 goto give_sigsegv;
5231 err |= __put_user(sig, &frame->sig);
5233 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5234 err |= __put_user(info_addr, &frame->pinfo);
5236 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5237 err |= __put_user(uc_addr, &frame->puc);
5239 err |= copy_siginfo_to_user(&frame->info, info);
5241 /* Create the ucontext */
5243 err |= __put_user(0, &frame->uc.tuc_flags);
5244 err |= __put_user(0, &frame->uc.tuc_link);
5245 err |= __put_user(target_sigaltstack_used.ss_sp,
5246 &frame->uc.tuc_stack.ss_sp);
5247 err |= __put_user(sas_ss_flags(env->aregs[7]),
5248 &frame->uc.tuc_stack.ss_flags);
5249 err |= __put_user(target_sigaltstack_used.ss_size,
5250 &frame->uc.tuc_stack.ss_size);
5251 err |= target_rt_setup_ucontext(&frame->uc, env);
5253 if (err)
5254 goto give_sigsegv;
5256 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5257 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
5258 goto give_sigsegv;
5261 /* Set up to return from userspace. */
5263 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5264 err |= __put_user(retcode_addr, &frame->pretcode);
5266 /* moveq #,d0; notb d0; trap #0 */
5268 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
5269 (long *)(frame->retcode + 0));
5270 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
5272 if (err)
5273 goto give_sigsegv;
5275 /* Set up to return from userspace */
5277 env->aregs[7] = frame_addr;
5278 env->pc = ka->_sa_handler;
5280 unlock_user_struct(frame, frame_addr, 1);
5281 return;
5283 give_sigsegv:
5284 unlock_user_struct(frame, frame_addr, 1);
5285 force_sig(TARGET_SIGSEGV);
5288 long do_sigreturn(CPUM68KState *env)
5290 struct target_sigframe *frame;
5291 abi_ulong frame_addr = env->aregs[7] - 4;
5292 target_sigset_t target_set;
5293 sigset_t set;
5294 int d0, i;
5296 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5297 goto badframe;
5299 /* set blocked signals */
5301 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
5302 goto badframe;
5304 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5305 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
5306 goto badframe;
5309 target_to_host_sigset_internal(&set, &target_set);
5310 sigprocmask(SIG_SETMASK, &set, NULL);
5312 /* restore registers */
5314 if (restore_sigcontext(env, &frame->sc, &d0))
5315 goto badframe;
5317 unlock_user_struct(frame, frame_addr, 0);
5318 return d0;
5320 badframe:
5321 unlock_user_struct(frame, frame_addr, 0);
5322 force_sig(TARGET_SIGSEGV);
5323 return 0;
5326 long do_rt_sigreturn(CPUM68KState *env)
5328 struct target_rt_sigframe *frame;
5329 abi_ulong frame_addr = env->aregs[7] - 4;
5330 target_sigset_t target_set;
5331 sigset_t set;
5332 int d0;
5334 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5335 goto badframe;
5337 target_to_host_sigset_internal(&set, &target_set);
5338 sigprocmask(SIG_SETMASK, &set, NULL);
5340 /* restore registers */
5342 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5343 goto badframe;
5345 if (do_sigaltstack(frame_addr +
5346 offsetof(struct target_rt_sigframe, uc.tuc_stack),
5347 0, get_sp_from_cpustate(env)) == -EFAULT)
5348 goto badframe;
5350 unlock_user_struct(frame, frame_addr, 0);
5351 return d0;
5353 badframe:
5354 unlock_user_struct(frame, frame_addr, 0);
5355 force_sig(TARGET_SIGSEGV);
5356 return 0;
5359 #elif defined(TARGET_ALPHA)
5361 struct target_sigcontext {
5362 abi_long sc_onstack;
5363 abi_long sc_mask;
5364 abi_long sc_pc;
5365 abi_long sc_ps;
5366 abi_long sc_regs[32];
5367 abi_long sc_ownedfp;
5368 abi_long sc_fpregs[32];
5369 abi_ulong sc_fpcr;
5370 abi_ulong sc_fp_control;
5371 abi_ulong sc_reserved1;
5372 abi_ulong sc_reserved2;
5373 abi_ulong sc_ssize;
5374 abi_ulong sc_sbase;
5375 abi_ulong sc_traparg_a0;
5376 abi_ulong sc_traparg_a1;
5377 abi_ulong sc_traparg_a2;
5378 abi_ulong sc_fp_trap_pc;
5379 abi_ulong sc_fp_trigger_sum;
5380 abi_ulong sc_fp_trigger_inst;
5383 struct target_ucontext {
5384 abi_ulong tuc_flags;
5385 abi_ulong tuc_link;
5386 abi_ulong tuc_osf_sigmask;
5387 target_stack_t tuc_stack;
5388 struct target_sigcontext tuc_mcontext;
5389 target_sigset_t tuc_sigmask;
5392 struct target_sigframe {
5393 struct target_sigcontext sc;
5394 unsigned int retcode[3];
5397 struct target_rt_sigframe {
5398 target_siginfo_t info;
5399 struct target_ucontext uc;
5400 unsigned int retcode[3];
5403 #define INSN_MOV_R30_R16 0x47fe0410
5404 #define INSN_LDI_R0 0x201f0000
5405 #define INSN_CALLSYS 0x00000083
5407 static int setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5408 abi_ulong frame_addr, target_sigset_t *set)
5410 int i, err = 0;
5412 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
5413 err |= __put_user(set->sig[0], &sc->sc_mask);
5414 err |= __put_user(env->pc, &sc->sc_pc);
5415 err |= __put_user(8, &sc->sc_ps);
5417 for (i = 0; i < 31; ++i) {
5418 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
5420 err |= __put_user(0, &sc->sc_regs[31]);
5422 for (i = 0; i < 31; ++i) {
5423 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
5425 err |= __put_user(0, &sc->sc_fpregs[31]);
5426 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5428 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5429 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5430 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5432 return err;
5435 static int restore_sigcontext(CPUAlphaState *env,
5436 struct target_sigcontext *sc)
5438 uint64_t fpcr;
5439 int i, err = 0;
5441 err |= __get_user(env->pc, &sc->sc_pc);
5443 for (i = 0; i < 31; ++i) {
5444 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
5446 for (i = 0; i < 31; ++i) {
5447 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
5450 err |= __get_user(fpcr, &sc->sc_fpcr);
5451 cpu_alpha_store_fpcr(env, fpcr);
5453 return err;
5456 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5457 CPUAlphaState *env,
5458 unsigned long framesize)
5460 abi_ulong sp = env->ir[IR_SP];
5462 /* This is the X/Open sanctioned signal stack switching. */
5463 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5464 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5466 return (sp - framesize) & -32;
5469 static void setup_frame(int sig, struct target_sigaction *ka,
5470 target_sigset_t *set, CPUAlphaState *env)
5472 abi_ulong frame_addr, r26;
5473 struct target_sigframe *frame;
5474 int err = 0;
5476 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5477 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5478 goto give_sigsegv;
5481 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
5483 if (ka->sa_restorer) {
5484 r26 = ka->sa_restorer;
5485 } else {
5486 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5487 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5488 &frame->retcode[1]);
5489 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5490 /* imb() */
5491 r26 = frame_addr;
5494 unlock_user_struct(frame, frame_addr, 1);
5496 if (err) {
5497 give_sigsegv:
5498 if (sig == TARGET_SIGSEGV) {
5499 ka->_sa_handler = TARGET_SIG_DFL;
5501 force_sig(TARGET_SIGSEGV);
5504 env->ir[IR_RA] = r26;
5505 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5506 env->ir[IR_A0] = sig;
5507 env->ir[IR_A1] = 0;
5508 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5509 env->ir[IR_SP] = frame_addr;
5512 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5513 target_siginfo_t *info,
5514 target_sigset_t *set, CPUAlphaState *env)
5516 abi_ulong frame_addr, r26;
5517 struct target_rt_sigframe *frame;
5518 int i, err = 0;
5520 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5521 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5522 goto give_sigsegv;
5525 err |= copy_siginfo_to_user(&frame->info, info);
5527 err |= __put_user(0, &frame->uc.tuc_flags);
5528 err |= __put_user(0, &frame->uc.tuc_link);
5529 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5530 err |= __put_user(target_sigaltstack_used.ss_sp,
5531 &frame->uc.tuc_stack.ss_sp);
5532 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
5533 &frame->uc.tuc_stack.ss_flags);
5534 err |= __put_user(target_sigaltstack_used.ss_size,
5535 &frame->uc.tuc_stack.ss_size);
5536 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5537 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5538 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5541 if (ka->sa_restorer) {
5542 r26 = ka->sa_restorer;
5543 } else {
5544 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5545 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5546 &frame->retcode[1]);
5547 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
5548 /* imb(); */
5549 r26 = frame_addr;
5552 if (err) {
5553 give_sigsegv:
5554 if (sig == TARGET_SIGSEGV) {
5555 ka->_sa_handler = TARGET_SIG_DFL;
5557 force_sig(TARGET_SIGSEGV);
5560 env->ir[IR_RA] = r26;
5561 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5562 env->ir[IR_A0] = sig;
5563 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5564 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5565 env->ir[IR_SP] = frame_addr;
5568 long do_sigreturn(CPUAlphaState *env)
5570 struct target_sigcontext *sc;
5571 abi_ulong sc_addr = env->ir[IR_A0];
5572 target_sigset_t target_set;
5573 sigset_t set;
5575 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5576 goto badframe;
5579 target_sigemptyset(&target_set);
5580 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
5581 goto badframe;
5584 target_to_host_sigset_internal(&set, &target_set);
5585 sigprocmask(SIG_SETMASK, &set, NULL);
5587 if (restore_sigcontext(env, sc)) {
5588 goto badframe;
5590 unlock_user_struct(sc, sc_addr, 0);
5591 return env->ir[IR_V0];
5593 badframe:
5594 unlock_user_struct(sc, sc_addr, 0);
5595 force_sig(TARGET_SIGSEGV);
5598 long do_rt_sigreturn(CPUAlphaState *env)
5600 abi_ulong frame_addr = env->ir[IR_A0];
5601 struct target_rt_sigframe *frame;
5602 sigset_t set;
5604 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5605 goto badframe;
5607 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5608 sigprocmask(SIG_SETMASK, &set, NULL);
5610 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
5611 goto badframe;
5613 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5614 uc.tuc_stack),
5615 0, env->ir[IR_SP]) == -EFAULT) {
5616 goto badframe;
5619 unlock_user_struct(frame, frame_addr, 0);
5620 return env->ir[IR_V0];
5623 badframe:
5624 unlock_user_struct(frame, frame_addr, 0);
5625 force_sig(TARGET_SIGSEGV);
5628 #else
5630 static void setup_frame(int sig, struct target_sigaction *ka,
5631 target_sigset_t *set, CPUArchState *env)
5633 fprintf(stderr, "setup_frame: not implemented\n");
5636 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5637 target_siginfo_t *info,
5638 target_sigset_t *set, CPUArchState *env)
5640 fprintf(stderr, "setup_rt_frame: not implemented\n");
5643 long do_sigreturn(CPUArchState *env)
5645 fprintf(stderr, "do_sigreturn: not implemented\n");
5646 return -TARGET_ENOSYS;
5649 long do_rt_sigreturn(CPUArchState *env)
5651 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5652 return -TARGET_ENOSYS;
5655 #endif
5657 void process_pending_signals(CPUArchState *cpu_env)
5659 CPUState *cpu = ENV_GET_CPU(cpu_env);
5660 int sig;
5661 abi_ulong handler;
5662 sigset_t set, old_set;
5663 target_sigset_t target_old_set;
5664 struct emulated_sigtable *k;
5665 struct target_sigaction *sa;
5666 struct sigqueue *q;
5667 TaskState *ts = cpu_env->opaque;
5669 if (!ts->signal_pending)
5670 return;
5672 /* FIXME: This is not threadsafe. */
5673 k = ts->sigtab;
5674 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5675 if (k->pending)
5676 goto handle_signal;
5677 k++;
5679 /* if no signal is pending, just return */
5680 ts->signal_pending = 0;
5681 return;
5683 handle_signal:
5684 #ifdef DEBUG_SIGNAL
5685 fprintf(stderr, "qemu: process signal %d\n", sig);
5686 #endif
5687 /* dequeue signal */
5688 q = k->first;
5689 k->first = q->next;
5690 if (!k->first)
5691 k->pending = 0;
5693 sig = gdb_handlesig(cpu, sig);
5694 if (!sig) {
5695 sa = NULL;
5696 handler = TARGET_SIG_IGN;
5697 } else {
5698 sa = &sigact_table[sig - 1];
5699 handler = sa->_sa_handler;
5702 if (handler == TARGET_SIG_DFL) {
5703 /* default handler : ignore some signal. The other are job control or fatal */
5704 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5705 kill(getpid(),SIGSTOP);
5706 } else if (sig != TARGET_SIGCHLD &&
5707 sig != TARGET_SIGURG &&
5708 sig != TARGET_SIGWINCH &&
5709 sig != TARGET_SIGCONT) {
5710 force_sig(sig);
5712 } else if (handler == TARGET_SIG_IGN) {
5713 /* ignore sig */
5714 } else if (handler == TARGET_SIG_ERR) {
5715 force_sig(sig);
5716 } else {
5717 /* compute the blocked signals during the handler execution */
5718 target_to_host_sigset(&set, &sa->sa_mask);
5719 /* SA_NODEFER indicates that the current signal should not be
5720 blocked during the handler */
5721 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5722 sigaddset(&set, target_to_host_signal(sig));
5724 /* block signals in the handler using Linux */
5725 sigprocmask(SIG_BLOCK, &set, &old_set);
5726 /* save the previous blocked signal state to restore it at the
5727 end of the signal execution (see do_sigreturn) */
5728 host_to_target_sigset_internal(&target_old_set, &old_set);
5730 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5731 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5733 CPUX86State *env = cpu_env;
5734 if (env->eflags & VM_MASK)
5735 save_v86_state(env);
5737 #endif
5738 /* prepare the stack frame of the virtual CPU */
5739 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5740 /* These targets do not have traditional signals. */
5741 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5742 #else
5743 if (sa->sa_flags & TARGET_SA_SIGINFO)
5744 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5745 else
5746 setup_frame(sig, sa, &target_old_set, cpu_env);
5747 #endif
5748 if (sa->sa_flags & TARGET_SA_RESETHAND)
5749 sa->_sa_handler = TARGET_SIG_DFL;
5751 if (q != &k->info)
5752 free_sigqueue(cpu_env, q);