sheepdog: support creating images on remote hosts
[qemu/cris-port.git] / linux-user / signal.c
blob0664770c94fef3498c86afad41d743dbb340251e
1 /*
2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/ucontext.h>
28 #include <sys/resource.h>
30 #include "qemu.h"
31 #include "qemu-common.h"
32 #include "target_signal.h"
34 //#define DEBUG_SIGNAL
36 static struct target_sigaltstack target_sigaltstack_used = {
37 .ss_sp = 0,
38 .ss_size = 0,
39 .ss_flags = TARGET_SS_DISABLE,
42 static struct target_sigaction sigact_table[TARGET_NSIG];
44 static void host_signal_handler(int host_signum, siginfo_t *info,
45 void *puc);
47 static uint8_t host_to_target_signal_table[_NSIG] = {
48 [SIGHUP] = TARGET_SIGHUP,
49 [SIGINT] = TARGET_SIGINT,
50 [SIGQUIT] = TARGET_SIGQUIT,
51 [SIGILL] = TARGET_SIGILL,
52 [SIGTRAP] = TARGET_SIGTRAP,
53 [SIGABRT] = TARGET_SIGABRT,
54 /* [SIGIOT] = TARGET_SIGIOT,*/
55 [SIGBUS] = TARGET_SIGBUS,
56 [SIGFPE] = TARGET_SIGFPE,
57 [SIGKILL] = TARGET_SIGKILL,
58 [SIGUSR1] = TARGET_SIGUSR1,
59 [SIGSEGV] = TARGET_SIGSEGV,
60 [SIGUSR2] = TARGET_SIGUSR2,
61 [SIGPIPE] = TARGET_SIGPIPE,
62 [SIGALRM] = TARGET_SIGALRM,
63 [SIGTERM] = TARGET_SIGTERM,
64 #ifdef SIGSTKFLT
65 [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 #endif
67 [SIGCHLD] = TARGET_SIGCHLD,
68 [SIGCONT] = TARGET_SIGCONT,
69 [SIGSTOP] = TARGET_SIGSTOP,
70 [SIGTSTP] = TARGET_SIGTSTP,
71 [SIGTTIN] = TARGET_SIGTTIN,
72 [SIGTTOU] = TARGET_SIGTTOU,
73 [SIGURG] = TARGET_SIGURG,
74 [SIGXCPU] = TARGET_SIGXCPU,
75 [SIGXFSZ] = TARGET_SIGXFSZ,
76 [SIGVTALRM] = TARGET_SIGVTALRM,
77 [SIGPROF] = TARGET_SIGPROF,
78 [SIGWINCH] = TARGET_SIGWINCH,
79 [SIGIO] = TARGET_SIGIO,
80 [SIGPWR] = TARGET_SIGPWR,
81 [SIGSYS] = TARGET_SIGSYS,
82 /* next signals stay the same */
83 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
85 To fix this properly we need to do manual signal delivery multiplexed
86 over a single host signal. */
87 [__SIGRTMIN] = __SIGRTMAX,
88 [__SIGRTMAX] = __SIGRTMIN,
90 static uint8_t target_to_host_signal_table[_NSIG];
92 static inline int on_sig_stack(unsigned long sp)
94 return (sp - target_sigaltstack_used.ss_sp
95 < target_sigaltstack_used.ss_size);
98 static inline int sas_ss_flags(unsigned long sp)
100 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
101 : on_sig_stack(sp) ? SS_ONSTACK : 0);
104 int host_to_target_signal(int sig)
106 if (sig >= _NSIG)
107 return sig;
108 return host_to_target_signal_table[sig];
111 int target_to_host_signal(int sig)
113 if (sig >= _NSIG)
114 return sig;
115 return target_to_host_signal_table[sig];
118 static inline void target_sigemptyset(target_sigset_t *set)
120 memset(set, 0, sizeof(*set));
123 static inline void target_sigaddset(target_sigset_t *set, int signum)
125 signum--;
126 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
127 set->sig[signum / TARGET_NSIG_BPW] |= mask;
130 static inline int target_sigismember(const target_sigset_t *set, int signum)
132 signum--;
133 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
134 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
137 static void host_to_target_sigset_internal(target_sigset_t *d,
138 const sigset_t *s)
140 int i;
141 target_sigemptyset(d);
142 for (i = 1; i <= TARGET_NSIG; i++) {
143 if (sigismember(s, i)) {
144 target_sigaddset(d, host_to_target_signal(i));
149 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
151 target_sigset_t d1;
152 int i;
154 host_to_target_sigset_internal(&d1, s);
155 for(i = 0;i < TARGET_NSIG_WORDS; i++)
156 d->sig[i] = tswapl(d1.sig[i]);
159 static void target_to_host_sigset_internal(sigset_t *d,
160 const target_sigset_t *s)
162 int i;
163 sigemptyset(d);
164 for (i = 1; i <= TARGET_NSIG; i++) {
165 if (target_sigismember(s, i)) {
166 sigaddset(d, target_to_host_signal(i));
171 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
173 target_sigset_t s1;
174 int i;
176 for(i = 0;i < TARGET_NSIG_WORDS; i++)
177 s1.sig[i] = tswapl(s->sig[i]);
178 target_to_host_sigset_internal(d, &s1);
181 void host_to_target_old_sigset(abi_ulong *old_sigset,
182 const sigset_t *sigset)
184 target_sigset_t d;
185 host_to_target_sigset(&d, sigset);
186 *old_sigset = d.sig[0];
189 void target_to_host_old_sigset(sigset_t *sigset,
190 const abi_ulong *old_sigset)
192 target_sigset_t d;
193 int i;
195 d.sig[0] = *old_sigset;
196 for(i = 1;i < TARGET_NSIG_WORDS; i++)
197 d.sig[i] = 0;
198 target_to_host_sigset(sigset, &d);
201 /* siginfo conversion */
203 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
204 const siginfo_t *info)
206 int sig;
207 sig = host_to_target_signal(info->si_signo);
208 tinfo->si_signo = sig;
209 tinfo->si_errno = 0;
210 tinfo->si_code = info->si_code;
211 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
212 sig == SIGBUS || sig == SIGTRAP) {
213 /* should never come here, but who knows. The information for
214 the target is irrelevant */
215 tinfo->_sifields._sigfault._addr = 0;
216 } else if (sig == SIGIO) {
217 tinfo->_sifields._sigpoll._fd = info->si_fd;
218 } else if (sig >= TARGET_SIGRTMIN) {
219 tinfo->_sifields._rt._pid = info->si_pid;
220 tinfo->_sifields._rt._uid = info->si_uid;
221 /* XXX: potential problem if 64 bit */
222 tinfo->_sifields._rt._sigval.sival_ptr =
223 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
227 static void tswap_siginfo(target_siginfo_t *tinfo,
228 const target_siginfo_t *info)
230 int sig;
231 sig = info->si_signo;
232 tinfo->si_signo = tswap32(sig);
233 tinfo->si_errno = tswap32(info->si_errno);
234 tinfo->si_code = tswap32(info->si_code);
235 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
236 sig == SIGBUS || sig == SIGTRAP) {
237 tinfo->_sifields._sigfault._addr =
238 tswapl(info->_sifields._sigfault._addr);
239 } else if (sig == SIGIO) {
240 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
241 } else if (sig >= TARGET_SIGRTMIN) {
242 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
243 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
244 tinfo->_sifields._rt._sigval.sival_ptr =
245 tswapl(info->_sifields._rt._sigval.sival_ptr);
250 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
252 host_to_target_siginfo_noswap(tinfo, info);
253 tswap_siginfo(tinfo, tinfo);
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
258 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
260 info->si_signo = tswap32(tinfo->si_signo);
261 info->si_errno = tswap32(tinfo->si_errno);
262 info->si_code = tswap32(tinfo->si_code);
263 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
264 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
265 info->si_value.sival_ptr =
266 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
269 static int fatal_signal (int sig)
271 switch (sig) {
272 case TARGET_SIGCHLD:
273 case TARGET_SIGURG:
274 case TARGET_SIGWINCH:
275 /* Ignored by default. */
276 return 0;
277 case TARGET_SIGCONT:
278 case TARGET_SIGSTOP:
279 case TARGET_SIGTSTP:
280 case TARGET_SIGTTIN:
281 case TARGET_SIGTTOU:
282 /* Job control signals. */
283 return 0;
284 default:
285 return 1;
289 /* returns 1 if given signal should dump core if not handled */
290 static int core_dump_signal(int sig)
292 switch (sig) {
293 case TARGET_SIGABRT:
294 case TARGET_SIGFPE:
295 case TARGET_SIGILL:
296 case TARGET_SIGQUIT:
297 case TARGET_SIGSEGV:
298 case TARGET_SIGTRAP:
299 case TARGET_SIGBUS:
300 return (1);
301 default:
302 return (0);
306 void signal_init(void)
308 struct sigaction act;
309 struct sigaction oact;
310 int i, j;
311 int host_sig;
313 /* generate signal conversion tables */
314 for(i = 1; i < _NSIG; i++) {
315 if (host_to_target_signal_table[i] == 0)
316 host_to_target_signal_table[i] = i;
318 for(i = 1; i < _NSIG; i++) {
319 j = host_to_target_signal_table[i];
320 target_to_host_signal_table[j] = i;
323 /* set all host signal handlers. ALL signals are blocked during
324 the handlers to serialize them. */
325 memset(sigact_table, 0, sizeof(sigact_table));
327 sigfillset(&act.sa_mask);
328 act.sa_flags = SA_SIGINFO;
329 act.sa_sigaction = host_signal_handler;
330 for(i = 1; i <= TARGET_NSIG; i++) {
331 host_sig = target_to_host_signal(i);
332 sigaction(host_sig, NULL, &oact);
333 if (oact.sa_sigaction == (void *)SIG_IGN) {
334 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
335 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
336 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
338 /* If there's already a handler installed then something has
339 gone horribly wrong, so don't even try to handle that case. */
340 /* Install some handlers for our own use. We need at least
341 SIGSEGV and SIGBUS, to detect exceptions. We can not just
342 trap all signals because it affects syscall interrupt
343 behavior. But do trap all default-fatal signals. */
344 if (fatal_signal (i))
345 sigaction(host_sig, &act, NULL);
349 /* signal queue handling */
351 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
353 TaskState *ts = env->opaque;
354 struct sigqueue *q = ts->first_free;
355 if (!q)
356 return NULL;
357 ts->first_free = q->next;
358 return q;
361 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
363 TaskState *ts = env->opaque;
364 q->next = ts->first_free;
365 ts->first_free = q;
368 /* abort execution with signal */
369 static void QEMU_NORETURN force_sig(int target_sig)
371 TaskState *ts = (TaskState *)thread_env->opaque;
372 int host_sig, core_dumped = 0;
373 struct sigaction act;
374 host_sig = target_to_host_signal(target_sig);
375 gdb_signalled(thread_env, target_sig);
377 /* dump core if supported by target binary format */
378 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
379 stop_all_tasks();
380 core_dumped =
381 ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
383 if (core_dumped) {
384 /* we already dumped the core of target process, we don't want
385 * a coredump of qemu itself */
386 struct rlimit nodump;
387 getrlimit(RLIMIT_CORE, &nodump);
388 nodump.rlim_cur=0;
389 setrlimit(RLIMIT_CORE, &nodump);
390 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
391 target_sig, strsignal(host_sig), "core dumped" );
394 /* The proper exit code for dieing from an uncaught signal is
395 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
396 * a negative value. To get the proper exit code we need to
397 * actually die from an uncaught signal. Here the default signal
398 * handler is installed, we send ourself a signal and we wait for
399 * it to arrive. */
400 sigfillset(&act.sa_mask);
401 act.sa_handler = SIG_DFL;
402 sigaction(host_sig, &act, NULL);
404 /* For some reason raise(host_sig) doesn't send the signal when
405 * statically linked on x86-64. */
406 kill(getpid(), host_sig);
408 /* Make sure the signal isn't masked (just reuse the mask inside
409 of act) */
410 sigdelset(&act.sa_mask, host_sig);
411 sigsuspend(&act.sa_mask);
413 /* unreachable */
414 abort();
417 /* queue a signal so that it will be send to the virtual CPU as soon
418 as possible */
419 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
421 TaskState *ts = env->opaque;
422 struct emulated_sigtable *k;
423 struct sigqueue *q, **pq;
424 abi_ulong handler;
425 int queue;
427 #if defined(DEBUG_SIGNAL)
428 fprintf(stderr, "queue_signal: sig=%d\n",
429 sig);
430 #endif
431 k = &ts->sigtab[sig - 1];
432 queue = gdb_queuesig ();
433 handler = sigact_table[sig - 1]._sa_handler;
434 if (!queue && handler == TARGET_SIG_DFL) {
435 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
436 kill(getpid(),SIGSTOP);
437 return 0;
438 } else
439 /* default handler : ignore some signal. The other are fatal */
440 if (sig != TARGET_SIGCHLD &&
441 sig != TARGET_SIGURG &&
442 sig != TARGET_SIGWINCH &&
443 sig != TARGET_SIGCONT) {
444 force_sig(sig);
445 } else {
446 return 0; /* indicate ignored */
448 } else if (!queue && handler == TARGET_SIG_IGN) {
449 /* ignore signal */
450 return 0;
451 } else if (!queue && handler == TARGET_SIG_ERR) {
452 force_sig(sig);
453 } else {
454 pq = &k->first;
455 if (sig < TARGET_SIGRTMIN) {
456 /* if non real time signal, we queue exactly one signal */
457 if (!k->pending)
458 q = &k->info;
459 else
460 return 0;
461 } else {
462 if (!k->pending) {
463 /* first signal */
464 q = &k->info;
465 } else {
466 q = alloc_sigqueue(env);
467 if (!q)
468 return -EAGAIN;
469 while (*pq != NULL)
470 pq = &(*pq)->next;
473 *pq = q;
474 q->info = *info;
475 q->next = NULL;
476 k->pending = 1;
477 /* signal that a new signal is pending */
478 ts->signal_pending = 1;
479 return 1; /* indicates that the signal was queued */
483 static void host_signal_handler(int host_signum, siginfo_t *info,
484 void *puc)
486 int sig;
487 target_siginfo_t tinfo;
489 /* the CPU emulator uses some host signals to detect exceptions,
490 we forward to it some signals */
491 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
492 && info->si_code > 0) {
493 if (cpu_signal_handler(host_signum, info, puc))
494 return;
497 /* get target signal number */
498 sig = host_to_target_signal(host_signum);
499 if (sig < 1 || sig > TARGET_NSIG)
500 return;
501 #if defined(DEBUG_SIGNAL)
502 fprintf(stderr, "qemu: got signal %d\n", sig);
503 #endif
504 host_to_target_siginfo_noswap(&tinfo, info);
505 if (queue_signal(thread_env, sig, &tinfo) == 1) {
506 /* interrupt the virtual CPU as soon as possible */
507 cpu_exit(thread_env);
511 /* do_sigaltstack() returns target values and errnos. */
512 /* compare linux/kernel/signal.c:do_sigaltstack() */
513 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
515 int ret;
516 struct target_sigaltstack oss;
518 /* XXX: test errors */
519 if(uoss_addr)
521 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
522 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
523 __put_user(sas_ss_flags(sp), &oss.ss_flags);
526 if(uss_addr)
528 struct target_sigaltstack *uss;
529 struct target_sigaltstack ss;
531 ret = -TARGET_EFAULT;
532 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
533 || __get_user(ss.ss_sp, &uss->ss_sp)
534 || __get_user(ss.ss_size, &uss->ss_size)
535 || __get_user(ss.ss_flags, &uss->ss_flags))
536 goto out;
537 unlock_user_struct(uss, uss_addr, 0);
539 ret = -TARGET_EPERM;
540 if (on_sig_stack(sp))
541 goto out;
543 ret = -TARGET_EINVAL;
544 if (ss.ss_flags != TARGET_SS_DISABLE
545 && ss.ss_flags != TARGET_SS_ONSTACK
546 && ss.ss_flags != 0)
547 goto out;
549 if (ss.ss_flags == TARGET_SS_DISABLE) {
550 ss.ss_size = 0;
551 ss.ss_sp = 0;
552 } else {
553 ret = -TARGET_ENOMEM;
554 if (ss.ss_size < MINSIGSTKSZ)
555 goto out;
558 target_sigaltstack_used.ss_sp = ss.ss_sp;
559 target_sigaltstack_used.ss_size = ss.ss_size;
562 if (uoss_addr) {
563 ret = -TARGET_EFAULT;
564 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
565 goto out;
568 ret = 0;
569 out:
570 return ret;
573 /* do_sigaction() return host values and errnos */
574 int do_sigaction(int sig, const struct target_sigaction *act,
575 struct target_sigaction *oact)
577 struct target_sigaction *k;
578 struct sigaction act1;
579 int host_sig;
580 int ret = 0;
582 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
583 return -EINVAL;
584 k = &sigact_table[sig - 1];
585 #if defined(DEBUG_SIGNAL)
586 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
587 sig, act, oact);
588 #endif
589 if (oact) {
590 oact->_sa_handler = tswapl(k->_sa_handler);
591 oact->sa_flags = tswapl(k->sa_flags);
592 #if !defined(TARGET_MIPS)
593 oact->sa_restorer = tswapl(k->sa_restorer);
594 #endif
595 oact->sa_mask = k->sa_mask;
597 if (act) {
598 /* FIXME: This is not threadsafe. */
599 k->_sa_handler = tswapl(act->_sa_handler);
600 k->sa_flags = tswapl(act->sa_flags);
601 #if !defined(TARGET_MIPS)
602 k->sa_restorer = tswapl(act->sa_restorer);
603 #endif
604 k->sa_mask = act->sa_mask;
606 /* we update the host linux signal state */
607 host_sig = target_to_host_signal(sig);
608 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
609 sigfillset(&act1.sa_mask);
610 act1.sa_flags = SA_SIGINFO;
611 if (k->sa_flags & TARGET_SA_RESTART)
612 act1.sa_flags |= SA_RESTART;
613 /* NOTE: it is important to update the host kernel signal
614 ignore state to avoid getting unexpected interrupted
615 syscalls */
616 if (k->_sa_handler == TARGET_SIG_IGN) {
617 act1.sa_sigaction = (void *)SIG_IGN;
618 } else if (k->_sa_handler == TARGET_SIG_DFL) {
619 if (fatal_signal (sig))
620 act1.sa_sigaction = host_signal_handler;
621 else
622 act1.sa_sigaction = (void *)SIG_DFL;
623 } else {
624 act1.sa_sigaction = host_signal_handler;
626 ret = sigaction(host_sig, &act1, NULL);
629 return ret;
632 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
633 const target_siginfo_t *info)
635 tswap_siginfo(tinfo, info);
636 return 0;
639 static inline int current_exec_domain_sig(int sig)
641 return /* current->exec_domain && current->exec_domain->signal_invmap
642 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
645 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
647 /* from the Linux kernel */
649 struct target_fpreg {
650 uint16_t significand[4];
651 uint16_t exponent;
654 struct target_fpxreg {
655 uint16_t significand[4];
656 uint16_t exponent;
657 uint16_t padding[3];
660 struct target_xmmreg {
661 abi_ulong element[4];
664 struct target_fpstate {
665 /* Regular FPU environment */
666 abi_ulong cw;
667 abi_ulong sw;
668 abi_ulong tag;
669 abi_ulong ipoff;
670 abi_ulong cssel;
671 abi_ulong dataoff;
672 abi_ulong datasel;
673 struct target_fpreg _st[8];
674 uint16_t status;
675 uint16_t magic; /* 0xffff = regular FPU data only */
677 /* FXSR FPU environment */
678 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
679 abi_ulong mxcsr;
680 abi_ulong reserved;
681 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
682 struct target_xmmreg _xmm[8];
683 abi_ulong padding[56];
686 #define X86_FXSR_MAGIC 0x0000
688 struct target_sigcontext {
689 uint16_t gs, __gsh;
690 uint16_t fs, __fsh;
691 uint16_t es, __esh;
692 uint16_t ds, __dsh;
693 abi_ulong edi;
694 abi_ulong esi;
695 abi_ulong ebp;
696 abi_ulong esp;
697 abi_ulong ebx;
698 abi_ulong edx;
699 abi_ulong ecx;
700 abi_ulong eax;
701 abi_ulong trapno;
702 abi_ulong err;
703 abi_ulong eip;
704 uint16_t cs, __csh;
705 abi_ulong eflags;
706 abi_ulong esp_at_signal;
707 uint16_t ss, __ssh;
708 abi_ulong fpstate; /* pointer */
709 abi_ulong oldmask;
710 abi_ulong cr2;
713 struct target_ucontext {
714 abi_ulong tuc_flags;
715 abi_ulong tuc_link;
716 target_stack_t tuc_stack;
717 struct target_sigcontext tuc_mcontext;
718 target_sigset_t tuc_sigmask; /* mask last for extensibility */
721 struct sigframe
723 abi_ulong pretcode;
724 int sig;
725 struct target_sigcontext sc;
726 struct target_fpstate fpstate;
727 abi_ulong extramask[TARGET_NSIG_WORDS-1];
728 char retcode[8];
731 struct rt_sigframe
733 abi_ulong pretcode;
734 int sig;
735 abi_ulong pinfo;
736 abi_ulong puc;
737 struct target_siginfo info;
738 struct target_ucontext uc;
739 struct target_fpstate fpstate;
740 char retcode[8];
744 * Set up a signal frame.
747 /* XXX: save x87 state */
748 static int
749 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
750 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
752 int err = 0;
753 uint16_t magic;
755 /* already locked in setup_frame() */
756 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
757 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
758 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
759 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
760 err |= __put_user(env->regs[R_EDI], &sc->edi);
761 err |= __put_user(env->regs[R_ESI], &sc->esi);
762 err |= __put_user(env->regs[R_EBP], &sc->ebp);
763 err |= __put_user(env->regs[R_ESP], &sc->esp);
764 err |= __put_user(env->regs[R_EBX], &sc->ebx);
765 err |= __put_user(env->regs[R_EDX], &sc->edx);
766 err |= __put_user(env->regs[R_ECX], &sc->ecx);
767 err |= __put_user(env->regs[R_EAX], &sc->eax);
768 err |= __put_user(env->exception_index, &sc->trapno);
769 err |= __put_user(env->error_code, &sc->err);
770 err |= __put_user(env->eip, &sc->eip);
771 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
772 err |= __put_user(env->eflags, &sc->eflags);
773 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
774 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
776 cpu_x86_fsave(env, fpstate_addr, 1);
777 fpstate->status = fpstate->sw;
778 magic = 0xffff;
779 err |= __put_user(magic, &fpstate->magic);
780 err |= __put_user(fpstate_addr, &sc->fpstate);
782 /* non-iBCS2 extensions.. */
783 err |= __put_user(mask, &sc->oldmask);
784 err |= __put_user(env->cr[2], &sc->cr2);
785 return err;
789 * Determine which stack to use..
792 static inline abi_ulong
793 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
795 unsigned long esp;
797 /* Default to using normal stack */
798 esp = env->regs[R_ESP];
799 /* This is the X/Open sanctioned signal stack switching. */
800 if (ka->sa_flags & TARGET_SA_ONSTACK) {
801 if (sas_ss_flags(esp) == 0)
802 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
805 /* This is the legacy signal stack switching. */
806 else
807 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
808 !(ka->sa_flags & TARGET_SA_RESTORER) &&
809 ka->sa_restorer) {
810 esp = (unsigned long) ka->sa_restorer;
812 return (esp - frame_size) & -8ul;
815 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
816 static void setup_frame(int sig, struct target_sigaction *ka,
817 target_sigset_t *set, CPUX86State *env)
819 abi_ulong frame_addr;
820 struct sigframe *frame;
821 int i, err = 0;
823 frame_addr = get_sigframe(ka, env, sizeof(*frame));
825 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
826 goto give_sigsegv;
828 err |= __put_user(current_exec_domain_sig(sig),
829 &frame->sig);
830 if (err)
831 goto give_sigsegv;
833 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
834 frame_addr + offsetof(struct sigframe, fpstate));
835 if (err)
836 goto give_sigsegv;
838 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
839 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
840 goto give_sigsegv;
843 /* Set up to return from userspace. If provided, use a stub
844 already in userspace. */
845 if (ka->sa_flags & TARGET_SA_RESTORER) {
846 err |= __put_user(ka->sa_restorer, &frame->pretcode);
847 } else {
848 uint16_t val16;
849 abi_ulong retcode_addr;
850 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
851 err |= __put_user(retcode_addr, &frame->pretcode);
852 /* This is popl %eax ; movl $,%eax ; int $0x80 */
853 val16 = 0xb858;
854 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
855 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
856 val16 = 0x80cd;
857 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
860 if (err)
861 goto give_sigsegv;
863 /* Set up registers for signal handler */
864 env->regs[R_ESP] = frame_addr;
865 env->eip = ka->_sa_handler;
867 cpu_x86_load_seg(env, R_DS, __USER_DS);
868 cpu_x86_load_seg(env, R_ES, __USER_DS);
869 cpu_x86_load_seg(env, R_SS, __USER_DS);
870 cpu_x86_load_seg(env, R_CS, __USER_CS);
871 env->eflags &= ~TF_MASK;
873 unlock_user_struct(frame, frame_addr, 1);
875 return;
877 give_sigsegv:
878 unlock_user_struct(frame, frame_addr, 1);
879 if (sig == TARGET_SIGSEGV)
880 ka->_sa_handler = TARGET_SIG_DFL;
881 force_sig(TARGET_SIGSEGV /* , current */);
884 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
885 static void setup_rt_frame(int sig, struct target_sigaction *ka,
886 target_siginfo_t *info,
887 target_sigset_t *set, CPUX86State *env)
889 abi_ulong frame_addr, addr;
890 struct rt_sigframe *frame;
891 int i, err = 0;
893 frame_addr = get_sigframe(ka, env, sizeof(*frame));
895 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
896 goto give_sigsegv;
898 err |= __put_user(current_exec_domain_sig(sig),
899 &frame->sig);
900 addr = frame_addr + offsetof(struct rt_sigframe, info);
901 err |= __put_user(addr, &frame->pinfo);
902 addr = frame_addr + offsetof(struct rt_sigframe, uc);
903 err |= __put_user(addr, &frame->puc);
904 err |= copy_siginfo_to_user(&frame->info, info);
905 if (err)
906 goto give_sigsegv;
908 /* Create the ucontext. */
909 err |= __put_user(0, &frame->uc.tuc_flags);
910 err |= __put_user(0, &frame->uc.tuc_link);
911 err |= __put_user(target_sigaltstack_used.ss_sp,
912 &frame->uc.tuc_stack.ss_sp);
913 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
914 &frame->uc.tuc_stack.ss_flags);
915 err |= __put_user(target_sigaltstack_used.ss_size,
916 &frame->uc.tuc_stack.ss_size);
917 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
918 env, set->sig[0],
919 frame_addr + offsetof(struct rt_sigframe, fpstate));
920 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
921 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
922 goto give_sigsegv;
925 /* Set up to return from userspace. If provided, use a stub
926 already in userspace. */
927 if (ka->sa_flags & TARGET_SA_RESTORER) {
928 err |= __put_user(ka->sa_restorer, &frame->pretcode);
929 } else {
930 uint16_t val16;
931 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
932 err |= __put_user(addr, &frame->pretcode);
933 /* This is movl $,%eax ; int $0x80 */
934 err |= __put_user(0xb8, (char *)(frame->retcode+0));
935 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
936 val16 = 0x80cd;
937 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
940 if (err)
941 goto give_sigsegv;
943 /* Set up registers for signal handler */
944 env->regs[R_ESP] = frame_addr;
945 env->eip = ka->_sa_handler;
947 cpu_x86_load_seg(env, R_DS, __USER_DS);
948 cpu_x86_load_seg(env, R_ES, __USER_DS);
949 cpu_x86_load_seg(env, R_SS, __USER_DS);
950 cpu_x86_load_seg(env, R_CS, __USER_CS);
951 env->eflags &= ~TF_MASK;
953 unlock_user_struct(frame, frame_addr, 1);
955 return;
957 give_sigsegv:
958 unlock_user_struct(frame, frame_addr, 1);
959 if (sig == TARGET_SIGSEGV)
960 ka->_sa_handler = TARGET_SIG_DFL;
961 force_sig(TARGET_SIGSEGV /* , current */);
964 static int
965 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
967 unsigned int err = 0;
968 abi_ulong fpstate_addr;
969 unsigned int tmpflags;
971 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
972 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
973 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
974 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
976 env->regs[R_EDI] = tswapl(sc->edi);
977 env->regs[R_ESI] = tswapl(sc->esi);
978 env->regs[R_EBP] = tswapl(sc->ebp);
979 env->regs[R_ESP] = tswapl(sc->esp);
980 env->regs[R_EBX] = tswapl(sc->ebx);
981 env->regs[R_EDX] = tswapl(sc->edx);
982 env->regs[R_ECX] = tswapl(sc->ecx);
983 env->eip = tswapl(sc->eip);
985 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
986 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
988 tmpflags = tswapl(sc->eflags);
989 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
990 // regs->orig_eax = -1; /* disable syscall checks */
992 fpstate_addr = tswapl(sc->fpstate);
993 if (fpstate_addr != 0) {
994 if (!access_ok(VERIFY_READ, fpstate_addr,
995 sizeof(struct target_fpstate)))
996 goto badframe;
997 cpu_x86_frstor(env, fpstate_addr, 1);
1000 *peax = tswapl(sc->eax);
1001 return err;
1002 badframe:
1003 return 1;
1006 long do_sigreturn(CPUX86State *env)
1008 struct sigframe *frame;
1009 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1010 target_sigset_t target_set;
1011 sigset_t set;
1012 int eax, i;
1014 #if defined(DEBUG_SIGNAL)
1015 fprintf(stderr, "do_sigreturn\n");
1016 #endif
1017 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1018 goto badframe;
1019 /* set blocked signals */
1020 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
1021 goto badframe;
1022 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1023 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
1024 goto badframe;
1027 target_to_host_sigset_internal(&set, &target_set);
1028 sigprocmask(SIG_SETMASK, &set, NULL);
1030 /* restore registers */
1031 if (restore_sigcontext(env, &frame->sc, &eax))
1032 goto badframe;
1033 unlock_user_struct(frame, frame_addr, 0);
1034 return eax;
1036 badframe:
1037 unlock_user_struct(frame, frame_addr, 0);
1038 force_sig(TARGET_SIGSEGV);
1039 return 0;
1042 long do_rt_sigreturn(CPUX86State *env)
1044 abi_ulong frame_addr;
1045 struct rt_sigframe *frame;
1046 sigset_t set;
1047 int eax;
1049 frame_addr = env->regs[R_ESP] - 4;
1050 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1051 goto badframe;
1052 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1053 sigprocmask(SIG_SETMASK, &set, NULL);
1055 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1056 goto badframe;
1058 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1059 get_sp_from_cpustate(env)) == -EFAULT)
1060 goto badframe;
1062 unlock_user_struct(frame, frame_addr, 0);
1063 return eax;
1065 badframe:
1066 unlock_user_struct(frame, frame_addr, 0);
1067 force_sig(TARGET_SIGSEGV);
1068 return 0;
1071 #elif defined(TARGET_ARM)
1073 struct target_sigcontext {
1074 abi_ulong trap_no;
1075 abi_ulong error_code;
1076 abi_ulong oldmask;
1077 abi_ulong arm_r0;
1078 abi_ulong arm_r1;
1079 abi_ulong arm_r2;
1080 abi_ulong arm_r3;
1081 abi_ulong arm_r4;
1082 abi_ulong arm_r5;
1083 abi_ulong arm_r6;
1084 abi_ulong arm_r7;
1085 abi_ulong arm_r8;
1086 abi_ulong arm_r9;
1087 abi_ulong arm_r10;
1088 abi_ulong arm_fp;
1089 abi_ulong arm_ip;
1090 abi_ulong arm_sp;
1091 abi_ulong arm_lr;
1092 abi_ulong arm_pc;
1093 abi_ulong arm_cpsr;
1094 abi_ulong fault_address;
1097 struct target_ucontext_v1 {
1098 abi_ulong tuc_flags;
1099 abi_ulong tuc_link;
1100 target_stack_t tuc_stack;
1101 struct target_sigcontext tuc_mcontext;
1102 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1105 struct target_ucontext_v2 {
1106 abi_ulong tuc_flags;
1107 abi_ulong tuc_link;
1108 target_stack_t tuc_stack;
1109 struct target_sigcontext tuc_mcontext;
1110 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1111 char __unused[128 - sizeof(target_sigset_t)];
1112 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1115 struct target_user_vfp {
1116 uint64_t fpregs[32];
1117 abi_ulong fpscr;
1120 struct target_user_vfp_exc {
1121 abi_ulong fpexc;
1122 abi_ulong fpinst;
1123 abi_ulong fpinst2;
1126 struct target_vfp_sigframe {
1127 abi_ulong magic;
1128 abi_ulong size;
1129 struct target_user_vfp ufp;
1130 struct target_user_vfp_exc ufp_exc;
1131 } __attribute__((__aligned__(8)));
1133 struct target_iwmmxt_sigframe {
1134 abi_ulong magic;
1135 abi_ulong size;
1136 uint64_t regs[16];
1137 /* Note that not all the coprocessor control registers are stored here */
1138 uint32_t wcssf;
1139 uint32_t wcasf;
1140 uint32_t wcgr0;
1141 uint32_t wcgr1;
1142 uint32_t wcgr2;
1143 uint32_t wcgr3;
1144 } __attribute__((__aligned__(8)));
1146 #define TARGET_VFP_MAGIC 0x56465001
1147 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1149 struct sigframe_v1
1151 struct target_sigcontext sc;
1152 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1153 abi_ulong retcode;
1156 struct sigframe_v2
1158 struct target_ucontext_v2 uc;
1159 abi_ulong retcode;
1162 struct rt_sigframe_v1
1164 abi_ulong pinfo;
1165 abi_ulong puc;
1166 struct target_siginfo info;
1167 struct target_ucontext_v1 uc;
1168 abi_ulong retcode;
1171 struct rt_sigframe_v2
1173 struct target_siginfo info;
1174 struct target_ucontext_v2 uc;
1175 abi_ulong retcode;
1178 #define TARGET_CONFIG_CPU_32 1
1181 * For ARM syscalls, we encode the syscall number into the instruction.
1183 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1184 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1187 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1188 * need two 16-bit instructions.
1190 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1191 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1193 static const abi_ulong retcodes[4] = {
1194 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1195 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1199 #define __get_user_error(x,p,e) __get_user(x, p)
1201 static inline int valid_user_regs(CPUState *regs)
1203 return 1;
1206 static void
1207 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1208 CPUState *env, abi_ulong mask)
1210 __put_user(env->regs[0], &sc->arm_r0);
1211 __put_user(env->regs[1], &sc->arm_r1);
1212 __put_user(env->regs[2], &sc->arm_r2);
1213 __put_user(env->regs[3], &sc->arm_r3);
1214 __put_user(env->regs[4], &sc->arm_r4);
1215 __put_user(env->regs[5], &sc->arm_r5);
1216 __put_user(env->regs[6], &sc->arm_r6);
1217 __put_user(env->regs[7], &sc->arm_r7);
1218 __put_user(env->regs[8], &sc->arm_r8);
1219 __put_user(env->regs[9], &sc->arm_r9);
1220 __put_user(env->regs[10], &sc->arm_r10);
1221 __put_user(env->regs[11], &sc->arm_fp);
1222 __put_user(env->regs[12], &sc->arm_ip);
1223 __put_user(env->regs[13], &sc->arm_sp);
1224 __put_user(env->regs[14], &sc->arm_lr);
1225 __put_user(env->regs[15], &sc->arm_pc);
1226 #ifdef TARGET_CONFIG_CPU_32
1227 __put_user(cpsr_read(env), &sc->arm_cpsr);
1228 #endif
1230 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1231 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1232 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1233 __put_user(mask, &sc->oldmask);
1236 static inline abi_ulong
1237 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1239 unsigned long sp = regs->regs[13];
1242 * This is the X/Open sanctioned signal stack switching.
1244 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1245 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1247 * ATPCS B01 mandates 8-byte alignment
1249 return (sp - framesize) & ~7;
1252 static int
1253 setup_return(CPUState *env, struct target_sigaction *ka,
1254 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1256 abi_ulong handler = ka->_sa_handler;
1257 abi_ulong retcode;
1258 int thumb = handler & 1;
1259 uint32_t cpsr = cpsr_read(env);
1261 cpsr &= ~CPSR_IT;
1262 if (thumb) {
1263 cpsr |= CPSR_T;
1264 } else {
1265 cpsr &= ~CPSR_T;
1268 if (ka->sa_flags & TARGET_SA_RESTORER) {
1269 retcode = ka->sa_restorer;
1270 } else {
1271 unsigned int idx = thumb;
1273 if (ka->sa_flags & TARGET_SA_SIGINFO)
1274 idx += 2;
1276 if (__put_user(retcodes[idx], rc))
1277 return 1;
1278 #if 0
1279 flush_icache_range((abi_ulong)rc,
1280 (abi_ulong)(rc + 1));
1281 #endif
1282 retcode = rc_addr + thumb;
1285 env->regs[0] = usig;
1286 env->regs[13] = frame_addr;
1287 env->regs[14] = retcode;
1288 env->regs[15] = handler & (thumb ? ~1 : ~3);
1289 cpsr_write(env, cpsr, 0xffffffff);
1291 return 0;
1294 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env)
1296 int i;
1297 struct target_vfp_sigframe *vfpframe;
1298 vfpframe = (struct target_vfp_sigframe *)regspace;
1299 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1300 __put_user(sizeof(*vfpframe), &vfpframe->size);
1301 for (i = 0; i < 32; i++) {
1302 __put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1304 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1305 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1306 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1307 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1308 return (abi_ulong*)(vfpframe+1);
1311 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace, CPUState *env)
1313 int i;
1314 struct target_iwmmxt_sigframe *iwmmxtframe;
1315 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1316 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1317 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1318 for (i = 0; i < 16; i++) {
1319 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1321 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1322 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1323 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1324 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1325 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1326 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1327 return (abi_ulong*)(iwmmxtframe+1);
1330 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1331 target_sigset_t *set, CPUState *env)
1333 struct target_sigaltstack stack;
1334 int i;
1335 abi_ulong *regspace;
1337 /* Clear all the bits of the ucontext we don't use. */
1338 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1340 memset(&stack, 0, sizeof(stack));
1341 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1342 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1343 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1344 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1346 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1347 /* Save coprocessor signal frame. */
1348 regspace = uc->tuc_regspace;
1349 if (arm_feature(env, ARM_FEATURE_VFP)) {
1350 regspace = setup_sigframe_v2_vfp(regspace, env);
1352 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1353 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1356 /* Write terminating magic word */
1357 __put_user(0, regspace);
1359 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1360 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1364 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1365 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1366 target_sigset_t *set, CPUState *regs)
1368 struct sigframe_v1 *frame;
1369 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1370 int i;
1372 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1373 return;
1375 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1377 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1378 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1379 goto end;
1382 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1383 frame_addr + offsetof(struct sigframe_v1, retcode));
1385 end:
1386 unlock_user_struct(frame, frame_addr, 1);
1389 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1390 target_sigset_t *set, CPUState *regs)
1392 struct sigframe_v2 *frame;
1393 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1395 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1396 return;
1398 setup_sigframe_v2(&frame->uc, set, regs);
1400 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1401 frame_addr + offsetof(struct sigframe_v2, retcode));
1403 unlock_user_struct(frame, frame_addr, 1);
1406 static void setup_frame(int usig, struct target_sigaction *ka,
1407 target_sigset_t *set, CPUState *regs)
1409 if (get_osversion() >= 0x020612) {
1410 setup_frame_v2(usig, ka, set, regs);
1411 } else {
1412 setup_frame_v1(usig, ka, set, regs);
1416 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1417 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1418 target_siginfo_t *info,
1419 target_sigset_t *set, CPUState *env)
1421 struct rt_sigframe_v1 *frame;
1422 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1423 struct target_sigaltstack stack;
1424 int i;
1425 abi_ulong info_addr, uc_addr;
1427 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1428 return /* 1 */;
1430 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1431 __put_user(info_addr, &frame->pinfo);
1432 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1433 __put_user(uc_addr, &frame->puc);
1434 copy_siginfo_to_user(&frame->info, info);
1436 /* Clear all the bits of the ucontext we don't use. */
1437 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1439 memset(&stack, 0, sizeof(stack));
1440 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1441 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1442 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1443 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1445 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1446 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1447 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1448 goto end;
1451 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1452 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1454 env->regs[1] = info_addr;
1455 env->regs[2] = uc_addr;
1457 end:
1458 unlock_user_struct(frame, frame_addr, 1);
1461 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1462 target_siginfo_t *info,
1463 target_sigset_t *set, CPUState *env)
1465 struct rt_sigframe_v2 *frame;
1466 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1467 abi_ulong info_addr, uc_addr;
1469 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1470 return /* 1 */;
1472 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1473 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1474 copy_siginfo_to_user(&frame->info, info);
1476 setup_sigframe_v2(&frame->uc, set, env);
1478 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1479 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1481 env->regs[1] = info_addr;
1482 env->regs[2] = uc_addr;
1484 unlock_user_struct(frame, frame_addr, 1);
1487 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1488 target_siginfo_t *info,
1489 target_sigset_t *set, CPUState *env)
1491 if (get_osversion() >= 0x020612) {
1492 setup_rt_frame_v2(usig, ka, info, set, env);
1493 } else {
1494 setup_rt_frame_v1(usig, ka, info, set, env);
1498 static int
1499 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1501 int err = 0;
1502 uint32_t cpsr;
1504 __get_user_error(env->regs[0], &sc->arm_r0, err);
1505 __get_user_error(env->regs[1], &sc->arm_r1, err);
1506 __get_user_error(env->regs[2], &sc->arm_r2, err);
1507 __get_user_error(env->regs[3], &sc->arm_r3, err);
1508 __get_user_error(env->regs[4], &sc->arm_r4, err);
1509 __get_user_error(env->regs[5], &sc->arm_r5, err);
1510 __get_user_error(env->regs[6], &sc->arm_r6, err);
1511 __get_user_error(env->regs[7], &sc->arm_r7, err);
1512 __get_user_error(env->regs[8], &sc->arm_r8, err);
1513 __get_user_error(env->regs[9], &sc->arm_r9, err);
1514 __get_user_error(env->regs[10], &sc->arm_r10, err);
1515 __get_user_error(env->regs[11], &sc->arm_fp, err);
1516 __get_user_error(env->regs[12], &sc->arm_ip, err);
1517 __get_user_error(env->regs[13], &sc->arm_sp, err);
1518 __get_user_error(env->regs[14], &sc->arm_lr, err);
1519 __get_user_error(env->regs[15], &sc->arm_pc, err);
1520 #ifdef TARGET_CONFIG_CPU_32
1521 __get_user_error(cpsr, &sc->arm_cpsr, err);
1522 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1523 #endif
1525 err |= !valid_user_regs(env);
1527 return err;
1530 static long do_sigreturn_v1(CPUState *env)
1532 abi_ulong frame_addr;
1533 struct sigframe_v1 *frame;
1534 target_sigset_t set;
1535 sigset_t host_set;
1536 int i;
1539 * Since we stacked the signal on a 64-bit boundary,
1540 * then 'sp' should be word aligned here. If it's
1541 * not, then the user is trying to mess with us.
1543 if (env->regs[13] & 7)
1544 goto badframe;
1546 frame_addr = env->regs[13];
1547 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1548 goto badframe;
1550 if (__get_user(set.sig[0], &frame->sc.oldmask))
1551 goto badframe;
1552 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1553 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1554 goto badframe;
1557 target_to_host_sigset_internal(&host_set, &set);
1558 sigprocmask(SIG_SETMASK, &host_set, NULL);
1560 if (restore_sigcontext(env, &frame->sc))
1561 goto badframe;
1563 #if 0
1564 /* Send SIGTRAP if we're single-stepping */
1565 if (ptrace_cancel_bpt(current))
1566 send_sig(SIGTRAP, current, 1);
1567 #endif
1568 unlock_user_struct(frame, frame_addr, 0);
1569 return env->regs[0];
1571 badframe:
1572 unlock_user_struct(frame, frame_addr, 0);
1573 force_sig(TARGET_SIGSEGV /* , current */);
1574 return 0;
1577 static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace)
1579 int i;
1580 abi_ulong magic, sz;
1581 uint32_t fpscr, fpexc;
1582 struct target_vfp_sigframe *vfpframe;
1583 vfpframe = (struct target_vfp_sigframe *)regspace;
1585 __get_user(magic, &vfpframe->magic);
1586 __get_user(sz, &vfpframe->size);
1587 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1588 return 0;
1590 for (i = 0; i < 32; i++) {
1591 __get_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
1593 __get_user(fpscr, &vfpframe->ufp.fpscr);
1594 vfp_set_fpscr(env, fpscr);
1595 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1596 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1597 * and the exception flag is cleared
1599 fpexc |= (1 << 30);
1600 fpexc &= ~((1 << 31) | (1 << 28));
1601 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1602 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1603 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1604 return (abi_ulong*)(vfpframe + 1);
1607 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUState *env, abi_ulong *regspace)
1609 int i;
1610 abi_ulong magic, sz;
1611 struct target_iwmmxt_sigframe *iwmmxtframe;
1612 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1614 __get_user(magic, &iwmmxtframe->magic);
1615 __get_user(sz, &iwmmxtframe->size);
1616 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1617 return 0;
1619 for (i = 0; i < 16; i++) {
1620 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1622 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1623 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1624 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1625 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1626 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1627 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1628 return (abi_ulong*)(iwmmxtframe + 1);
1631 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1632 struct target_ucontext_v2 *uc)
1634 sigset_t host_set;
1635 abi_ulong *regspace;
1637 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1638 sigprocmask(SIG_SETMASK, &host_set, NULL);
1640 if (restore_sigcontext(env, &uc->tuc_mcontext))
1641 return 1;
1643 /* Restore coprocessor signal frame */
1644 regspace = uc->tuc_regspace;
1645 if (arm_feature(env, ARM_FEATURE_VFP)) {
1646 regspace = restore_sigframe_v2_vfp(env, regspace);
1647 if (!regspace) {
1648 return 1;
1651 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1652 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1653 if (!regspace) {
1654 return 1;
1658 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1659 return 1;
1661 #if 0
1662 /* Send SIGTRAP if we're single-stepping */
1663 if (ptrace_cancel_bpt(current))
1664 send_sig(SIGTRAP, current, 1);
1665 #endif
1667 return 0;
1670 static long do_sigreturn_v2(CPUState *env)
1672 abi_ulong frame_addr;
1673 struct sigframe_v2 *frame;
1676 * Since we stacked the signal on a 64-bit boundary,
1677 * then 'sp' should be word aligned here. If it's
1678 * not, then the user is trying to mess with us.
1680 if (env->regs[13] & 7)
1681 goto badframe;
1683 frame_addr = env->regs[13];
1684 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1685 goto badframe;
1687 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1688 goto badframe;
1690 unlock_user_struct(frame, frame_addr, 0);
1691 return env->regs[0];
1693 badframe:
1694 unlock_user_struct(frame, frame_addr, 0);
1695 force_sig(TARGET_SIGSEGV /* , current */);
1696 return 0;
1699 long do_sigreturn(CPUState *env)
1701 if (get_osversion() >= 0x020612) {
1702 return do_sigreturn_v2(env);
1703 } else {
1704 return do_sigreturn_v1(env);
1708 static long do_rt_sigreturn_v1(CPUState *env)
1710 abi_ulong frame_addr;
1711 struct rt_sigframe_v1 *frame;
1712 sigset_t host_set;
1715 * Since we stacked the signal on a 64-bit boundary,
1716 * then 'sp' should be word aligned here. If it's
1717 * not, then the user is trying to mess with us.
1719 if (env->regs[13] & 7)
1720 goto badframe;
1722 frame_addr = env->regs[13];
1723 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1724 goto badframe;
1726 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1727 sigprocmask(SIG_SETMASK, &host_set, NULL);
1729 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1730 goto badframe;
1732 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1733 goto badframe;
1735 #if 0
1736 /* Send SIGTRAP if we're single-stepping */
1737 if (ptrace_cancel_bpt(current))
1738 send_sig(SIGTRAP, current, 1);
1739 #endif
1740 unlock_user_struct(frame, frame_addr, 0);
1741 return env->regs[0];
1743 badframe:
1744 unlock_user_struct(frame, frame_addr, 0);
1745 force_sig(TARGET_SIGSEGV /* , current */);
1746 return 0;
1749 static long do_rt_sigreturn_v2(CPUState *env)
1751 abi_ulong frame_addr;
1752 struct rt_sigframe_v2 *frame;
1755 * Since we stacked the signal on a 64-bit boundary,
1756 * then 'sp' should be word aligned here. If it's
1757 * not, then the user is trying to mess with us.
1759 if (env->regs[13] & 7)
1760 goto badframe;
1762 frame_addr = env->regs[13];
1763 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1764 goto badframe;
1766 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1767 goto badframe;
1769 unlock_user_struct(frame, frame_addr, 0);
1770 return env->regs[0];
1772 badframe:
1773 unlock_user_struct(frame, frame_addr, 0);
1774 force_sig(TARGET_SIGSEGV /* , current */);
1775 return 0;
1778 long do_rt_sigreturn(CPUState *env)
1780 if (get_osversion() >= 0x020612) {
1781 return do_rt_sigreturn_v2(env);
1782 } else {
1783 return do_rt_sigreturn_v1(env);
1787 #elif defined(TARGET_SPARC)
1789 #define __SUNOS_MAXWIN 31
1791 /* This is what SunOS does, so shall I. */
1792 struct target_sigcontext {
1793 abi_ulong sigc_onstack; /* state to restore */
1795 abi_ulong sigc_mask; /* sigmask to restore */
1796 abi_ulong sigc_sp; /* stack pointer */
1797 abi_ulong sigc_pc; /* program counter */
1798 abi_ulong sigc_npc; /* next program counter */
1799 abi_ulong sigc_psr; /* for condition codes etc */
1800 abi_ulong sigc_g1; /* User uses these two registers */
1801 abi_ulong sigc_o0; /* within the trampoline code. */
1803 /* Now comes information regarding the users window set
1804 * at the time of the signal.
1806 abi_ulong sigc_oswins; /* outstanding windows */
1808 /* stack ptrs for each regwin buf */
1809 char *sigc_spbuf[__SUNOS_MAXWIN];
1811 /* Windows to restore after signal */
1812 struct {
1813 abi_ulong locals[8];
1814 abi_ulong ins[8];
1815 } sigc_wbuf[__SUNOS_MAXWIN];
1817 /* A Sparc stack frame */
1818 struct sparc_stackf {
1819 abi_ulong locals[8];
1820 abi_ulong ins[6];
1821 struct sparc_stackf *fp;
1822 abi_ulong callers_pc;
1823 char *structptr;
1824 abi_ulong xargs[6];
1825 abi_ulong xxargs[1];
1828 typedef struct {
1829 struct {
1830 abi_ulong psr;
1831 abi_ulong pc;
1832 abi_ulong npc;
1833 abi_ulong y;
1834 abi_ulong u_regs[16]; /* globals and ins */
1835 } si_regs;
1836 int si_mask;
1837 } __siginfo_t;
1839 typedef struct {
1840 unsigned long si_float_regs [32];
1841 unsigned long si_fsr;
1842 unsigned long si_fpqdepth;
1843 struct {
1844 unsigned long *insn_addr;
1845 unsigned long insn;
1846 } si_fpqueue [16];
1847 } qemu_siginfo_fpu_t;
1850 struct target_signal_frame {
1851 struct sparc_stackf ss;
1852 __siginfo_t info;
1853 abi_ulong fpu_save;
1854 abi_ulong insns[2] __attribute__ ((aligned (8)));
1855 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1856 abi_ulong extra_size; /* Should be 0 */
1857 qemu_siginfo_fpu_t fpu_state;
1859 struct target_rt_signal_frame {
1860 struct sparc_stackf ss;
1861 siginfo_t info;
1862 abi_ulong regs[20];
1863 sigset_t mask;
1864 abi_ulong fpu_save;
1865 unsigned int insns[2];
1866 stack_t stack;
1867 unsigned int extra_size; /* Should be 0 */
1868 qemu_siginfo_fpu_t fpu_state;
1871 #define UREG_O0 16
1872 #define UREG_O6 22
1873 #define UREG_I0 0
1874 #define UREG_I1 1
1875 #define UREG_I2 2
1876 #define UREG_I3 3
1877 #define UREG_I4 4
1878 #define UREG_I5 5
1879 #define UREG_I6 6
1880 #define UREG_I7 7
1881 #define UREG_L0 8
1882 #define UREG_FP UREG_I6
1883 #define UREG_SP UREG_O6
1885 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1886 CPUState *env, unsigned long framesize)
1888 abi_ulong sp;
1890 sp = env->regwptr[UREG_FP];
1892 /* This is the X/Open sanctioned signal stack switching. */
1893 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1894 if (!on_sig_stack(sp)
1895 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1896 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1898 return sp - framesize;
1901 static int
1902 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1904 int err = 0, i;
1906 err |= __put_user(env->psr, &si->si_regs.psr);
1907 err |= __put_user(env->pc, &si->si_regs.pc);
1908 err |= __put_user(env->npc, &si->si_regs.npc);
1909 err |= __put_user(env->y, &si->si_regs.y);
1910 for (i=0; i < 8; i++) {
1911 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1913 for (i=0; i < 8; i++) {
1914 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1916 err |= __put_user(mask, &si->si_mask);
1917 return err;
1920 #if 0
1921 static int
1922 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1923 CPUState *env, unsigned long mask)
1925 int err = 0;
1927 err |= __put_user(mask, &sc->sigc_mask);
1928 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1929 err |= __put_user(env->pc, &sc->sigc_pc);
1930 err |= __put_user(env->npc, &sc->sigc_npc);
1931 err |= __put_user(env->psr, &sc->sigc_psr);
1932 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1933 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1935 return err;
1937 #endif
1938 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1940 static void setup_frame(int sig, struct target_sigaction *ka,
1941 target_sigset_t *set, CPUState *env)
1943 abi_ulong sf_addr;
1944 struct target_signal_frame *sf;
1945 int sigframe_size, err, i;
1947 /* 1. Make sure everything is clean */
1948 //synchronize_user_stack();
1950 sigframe_size = NF_ALIGNEDSZ;
1951 sf_addr = get_sigframe(ka, env, sigframe_size);
1953 sf = lock_user(VERIFY_WRITE, sf_addr,
1954 sizeof(struct target_signal_frame), 0);
1955 if (!sf)
1956 goto sigsegv;
1958 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1959 #if 0
1960 if (invalid_frame_pointer(sf, sigframe_size))
1961 goto sigill_and_return;
1962 #endif
1963 /* 2. Save the current process state */
1964 err = setup___siginfo(&sf->info, env, set->sig[0]);
1965 err |= __put_user(0, &sf->extra_size);
1967 //err |= save_fpu_state(regs, &sf->fpu_state);
1968 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1970 err |= __put_user(set->sig[0], &sf->info.si_mask);
1971 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1972 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1975 for (i = 0; i < 8; i++) {
1976 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1978 for (i = 0; i < 8; i++) {
1979 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1981 if (err)
1982 goto sigsegv;
1984 /* 3. signal handler back-trampoline and parameters */
1985 env->regwptr[UREG_FP] = sf_addr;
1986 env->regwptr[UREG_I0] = sig;
1987 env->regwptr[UREG_I1] = sf_addr +
1988 offsetof(struct target_signal_frame, info);
1989 env->regwptr[UREG_I2] = sf_addr +
1990 offsetof(struct target_signal_frame, info);
1992 /* 4. signal handler */
1993 env->pc = ka->_sa_handler;
1994 env->npc = (env->pc + 4);
1995 /* 5. return to kernel instructions */
1996 if (ka->sa_restorer)
1997 env->regwptr[UREG_I7] = ka->sa_restorer;
1998 else {
1999 uint32_t val32;
2001 env->regwptr[UREG_I7] = sf_addr +
2002 offsetof(struct target_signal_frame, insns) - 2 * 4;
2004 /* mov __NR_sigreturn, %g1 */
2005 val32 = 0x821020d8;
2006 err |= __put_user(val32, &sf->insns[0]);
2008 /* t 0x10 */
2009 val32 = 0x91d02010;
2010 err |= __put_user(val32, &sf->insns[1]);
2011 if (err)
2012 goto sigsegv;
2014 /* Flush instruction space. */
2015 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2016 // tb_flush(env);
2018 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2019 return;
2020 #if 0
2021 sigill_and_return:
2022 force_sig(TARGET_SIGILL);
2023 #endif
2024 sigsegv:
2025 //fprintf(stderr, "force_sig\n");
2026 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2027 force_sig(TARGET_SIGSEGV);
2029 static inline int
2030 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
2032 int err;
2033 #if 0
2034 #ifdef CONFIG_SMP
2035 if (current->flags & PF_USEDFPU)
2036 regs->psr &= ~PSR_EF;
2037 #else
2038 if (current == last_task_used_math) {
2039 last_task_used_math = 0;
2040 regs->psr &= ~PSR_EF;
2042 #endif
2043 current->used_math = 1;
2044 current->flags &= ~PF_USEDFPU;
2045 #endif
2046 #if 0
2047 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
2048 return -EFAULT;
2049 #endif
2051 #if 0
2052 /* XXX: incorrect */
2053 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
2054 (sizeof(unsigned long) * 32));
2055 #endif
2056 err |= __get_user(env->fsr, &fpu->si_fsr);
2057 #if 0
2058 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
2059 if (current->thread.fpqdepth != 0)
2060 err |= __copy_from_user(&current->thread.fpqueue[0],
2061 &fpu->si_fpqueue[0],
2062 ((sizeof(unsigned long) +
2063 (sizeof(unsigned long *)))*16));
2064 #endif
2065 return err;
2069 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2070 target_siginfo_t *info,
2071 target_sigset_t *set, CPUState *env)
2073 fprintf(stderr, "setup_rt_frame: not implemented\n");
2076 long do_sigreturn(CPUState *env)
2078 abi_ulong sf_addr;
2079 struct target_signal_frame *sf;
2080 uint32_t up_psr, pc, npc;
2081 target_sigset_t set;
2082 sigset_t host_set;
2083 abi_ulong fpu_save_addr;
2084 int err, i;
2086 sf_addr = env->regwptr[UREG_FP];
2087 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2088 goto segv_and_exit;
2089 #if 0
2090 fprintf(stderr, "sigreturn\n");
2091 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2092 #endif
2093 //cpu_dump_state(env, stderr, fprintf, 0);
2095 /* 1. Make sure we are not getting garbage from the user */
2097 if (sf_addr & 3)
2098 goto segv_and_exit;
2100 err = __get_user(pc, &sf->info.si_regs.pc);
2101 err |= __get_user(npc, &sf->info.si_regs.npc);
2103 if ((pc | npc) & 3)
2104 goto segv_and_exit;
2106 /* 2. Restore the state */
2107 err |= __get_user(up_psr, &sf->info.si_regs.psr);
2109 /* User can only change condition codes and FPU enabling in %psr. */
2110 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2111 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2113 env->pc = pc;
2114 env->npc = npc;
2115 err |= __get_user(env->y, &sf->info.si_regs.y);
2116 for (i=0; i < 8; i++) {
2117 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2119 for (i=0; i < 8; i++) {
2120 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2123 err |= __get_user(fpu_save_addr, &sf->fpu_save);
2125 //if (fpu_save)
2126 // err |= restore_fpu_state(env, fpu_save);
2128 /* This is pretty much atomic, no amount locking would prevent
2129 * the races which exist anyways.
2131 err |= __get_user(set.sig[0], &sf->info.si_mask);
2132 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2133 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
2136 target_to_host_sigset_internal(&host_set, &set);
2137 sigprocmask(SIG_SETMASK, &host_set, NULL);
2139 if (err)
2140 goto segv_and_exit;
2141 unlock_user_struct(sf, sf_addr, 0);
2142 return env->regwptr[0];
2144 segv_and_exit:
2145 unlock_user_struct(sf, sf_addr, 0);
2146 force_sig(TARGET_SIGSEGV);
2149 long do_rt_sigreturn(CPUState *env)
2151 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2152 return -TARGET_ENOSYS;
2155 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2156 #define MC_TSTATE 0
2157 #define MC_PC 1
2158 #define MC_NPC 2
2159 #define MC_Y 3
2160 #define MC_G1 4
2161 #define MC_G2 5
2162 #define MC_G3 6
2163 #define MC_G4 7
2164 #define MC_G5 8
2165 #define MC_G6 9
2166 #define MC_G7 10
2167 #define MC_O0 11
2168 #define MC_O1 12
2169 #define MC_O2 13
2170 #define MC_O3 14
2171 #define MC_O4 15
2172 #define MC_O5 16
2173 #define MC_O6 17
2174 #define MC_O7 18
2175 #define MC_NGREG 19
2177 typedef abi_ulong target_mc_greg_t;
2178 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2180 struct target_mc_fq {
2181 abi_ulong *mcfq_addr;
2182 uint32_t mcfq_insn;
2185 struct target_mc_fpu {
2186 union {
2187 uint32_t sregs[32];
2188 uint64_t dregs[32];
2189 //uint128_t qregs[16];
2190 } mcfpu_fregs;
2191 abi_ulong mcfpu_fsr;
2192 abi_ulong mcfpu_fprs;
2193 abi_ulong mcfpu_gsr;
2194 struct target_mc_fq *mcfpu_fq;
2195 unsigned char mcfpu_qcnt;
2196 unsigned char mcfpu_qentsz;
2197 unsigned char mcfpu_enab;
2199 typedef struct target_mc_fpu target_mc_fpu_t;
2201 typedef struct {
2202 target_mc_gregset_t mc_gregs;
2203 target_mc_greg_t mc_fp;
2204 target_mc_greg_t mc_i7;
2205 target_mc_fpu_t mc_fpregs;
2206 } target_mcontext_t;
2208 struct target_ucontext {
2209 struct target_ucontext *tuc_link;
2210 abi_ulong tuc_flags;
2211 target_sigset_t tuc_sigmask;
2212 target_mcontext_t tuc_mcontext;
2215 /* A V9 register window */
2216 struct target_reg_window {
2217 abi_ulong locals[8];
2218 abi_ulong ins[8];
2221 #define TARGET_STACK_BIAS 2047
2223 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2224 void sparc64_set_context(CPUSPARCState *env)
2226 abi_ulong ucp_addr;
2227 struct target_ucontext *ucp;
2228 target_mc_gregset_t *grp;
2229 abi_ulong pc, npc, tstate;
2230 abi_ulong fp, i7, w_addr;
2231 unsigned char fenab;
2232 int err;
2233 unsigned int i;
2235 ucp_addr = env->regwptr[UREG_I0];
2236 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2237 goto do_sigsegv;
2238 grp = &ucp->tuc_mcontext.mc_gregs;
2239 err = __get_user(pc, &((*grp)[MC_PC]));
2240 err |= __get_user(npc, &((*grp)[MC_NPC]));
2241 if (err || ((pc | npc) & 3))
2242 goto do_sigsegv;
2243 if (env->regwptr[UREG_I1]) {
2244 target_sigset_t target_set;
2245 sigset_t set;
2247 if (TARGET_NSIG_WORDS == 1) {
2248 if (__get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]))
2249 goto do_sigsegv;
2250 } else {
2251 abi_ulong *src, *dst;
2252 src = ucp->tuc_sigmask.sig;
2253 dst = target_set.sig;
2254 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2255 i++, dst++, src++)
2256 err |= __get_user(*dst, src);
2257 if (err)
2258 goto do_sigsegv;
2260 target_to_host_sigset_internal(&set, &target_set);
2261 sigprocmask(SIG_SETMASK, &set, NULL);
2263 env->pc = pc;
2264 env->npc = npc;
2265 err |= __get_user(env->y, &((*grp)[MC_Y]));
2266 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2267 env->asi = (tstate >> 24) & 0xff;
2268 cpu_put_ccr(env, tstate >> 32);
2269 cpu_put_cwp64(env, tstate & 0x1f);
2270 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2271 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2272 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2273 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2274 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2275 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2276 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2277 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2278 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2279 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2280 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2281 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2282 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2283 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2284 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2286 err |= __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2287 err |= __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2289 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2290 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2291 abi_ulong) != 0)
2292 goto do_sigsegv;
2293 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2294 abi_ulong) != 0)
2295 goto do_sigsegv;
2296 err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2297 err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2299 uint32_t *src, *dst;
2300 src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2301 dst = env->fpr;
2302 /* XXX: check that the CPU storage is the same as user context */
2303 for (i = 0; i < 64; i++, dst++, src++)
2304 err |= __get_user(*dst, src);
2306 err |= __get_user(env->fsr,
2307 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2308 err |= __get_user(env->gsr,
2309 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2310 if (err)
2311 goto do_sigsegv;
2312 unlock_user_struct(ucp, ucp_addr, 0);
2313 return;
2314 do_sigsegv:
2315 unlock_user_struct(ucp, ucp_addr, 0);
2316 force_sig(TARGET_SIGSEGV);
2319 void sparc64_get_context(CPUSPARCState *env)
2321 abi_ulong ucp_addr;
2322 struct target_ucontext *ucp;
2323 target_mc_gregset_t *grp;
2324 target_mcontext_t *mcp;
2325 abi_ulong fp, i7, w_addr;
2326 int err;
2327 unsigned int i;
2328 target_sigset_t target_set;
2329 sigset_t set;
2331 ucp_addr = env->regwptr[UREG_I0];
2332 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2333 goto do_sigsegv;
2335 mcp = &ucp->tuc_mcontext;
2336 grp = &mcp->mc_gregs;
2338 /* Skip over the trap instruction, first. */
2339 env->pc = env->npc;
2340 env->npc += 4;
2342 err = 0;
2344 sigprocmask(0, NULL, &set);
2345 host_to_target_sigset_internal(&target_set, &set);
2346 if (TARGET_NSIG_WORDS == 1) {
2347 err |= __put_user(target_set.sig[0],
2348 (abi_ulong *)&ucp->tuc_sigmask);
2349 } else {
2350 abi_ulong *src, *dst;
2351 src = target_set.sig;
2352 dst = ucp->tuc_sigmask.sig;
2353 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2354 i++, dst++, src++)
2355 err |= __put_user(*src, dst);
2356 if (err)
2357 goto do_sigsegv;
2360 /* XXX: tstate must be saved properly */
2361 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2362 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2363 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2364 err |= __put_user(env->y, &((*grp)[MC_Y]));
2365 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2366 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2367 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2368 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2369 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2370 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2371 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2372 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2373 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2374 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2375 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2376 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2377 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2378 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2379 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2381 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2382 fp = i7 = 0;
2383 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2384 abi_ulong) != 0)
2385 goto do_sigsegv;
2386 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2387 abi_ulong) != 0)
2388 goto do_sigsegv;
2389 err |= __put_user(fp, &(mcp->mc_fp));
2390 err |= __put_user(i7, &(mcp->mc_i7));
2393 uint32_t *src, *dst;
2394 src = env->fpr;
2395 dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2396 /* XXX: check that the CPU storage is the same as user context */
2397 for (i = 0; i < 64; i++, dst++, src++)
2398 err |= __put_user(*src, dst);
2400 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2401 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2402 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2404 if (err)
2405 goto do_sigsegv;
2406 unlock_user_struct(ucp, ucp_addr, 1);
2407 return;
2408 do_sigsegv:
2409 unlock_user_struct(ucp, ucp_addr, 1);
2410 force_sig(TARGET_SIGSEGV);
2412 #endif
2413 #elif defined(TARGET_ABI_MIPSN64)
2415 # warning signal handling not implemented
2417 static void setup_frame(int sig, struct target_sigaction *ka,
2418 target_sigset_t *set, CPUState *env)
2420 fprintf(stderr, "setup_frame: not implemented\n");
2423 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2424 target_siginfo_t *info,
2425 target_sigset_t *set, CPUState *env)
2427 fprintf(stderr, "setup_rt_frame: not implemented\n");
2430 long do_sigreturn(CPUState *env)
2432 fprintf(stderr, "do_sigreturn: not implemented\n");
2433 return -TARGET_ENOSYS;
2436 long do_rt_sigreturn(CPUState *env)
2438 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2439 return -TARGET_ENOSYS;
2442 #elif defined(TARGET_ABI_MIPSN32)
2444 # warning signal handling not implemented
2446 static void setup_frame(int sig, struct target_sigaction *ka,
2447 target_sigset_t *set, CPUState *env)
2449 fprintf(stderr, "setup_frame: not implemented\n");
2452 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2453 target_siginfo_t *info,
2454 target_sigset_t *set, CPUState *env)
2456 fprintf(stderr, "setup_rt_frame: not implemented\n");
2459 long do_sigreturn(CPUState *env)
2461 fprintf(stderr, "do_sigreturn: not implemented\n");
2462 return -TARGET_ENOSYS;
2465 long do_rt_sigreturn(CPUState *env)
2467 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2468 return -TARGET_ENOSYS;
2471 #elif defined(TARGET_ABI_MIPSO32)
2473 struct target_sigcontext {
2474 uint32_t sc_regmask; /* Unused */
2475 uint32_t sc_status;
2476 uint64_t sc_pc;
2477 uint64_t sc_regs[32];
2478 uint64_t sc_fpregs[32];
2479 uint32_t sc_ownedfp; /* Unused */
2480 uint32_t sc_fpc_csr;
2481 uint32_t sc_fpc_eir; /* Unused */
2482 uint32_t sc_used_math;
2483 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2484 uint32_t pad0;
2485 uint64_t sc_mdhi;
2486 uint64_t sc_mdlo;
2487 target_ulong sc_hi1; /* Was sc_cause */
2488 target_ulong sc_lo1; /* Was sc_badvaddr */
2489 target_ulong sc_hi2; /* Was sc_sigset[4] */
2490 target_ulong sc_lo2;
2491 target_ulong sc_hi3;
2492 target_ulong sc_lo3;
2495 struct sigframe {
2496 uint32_t sf_ass[4]; /* argument save space for o32 */
2497 uint32_t sf_code[2]; /* signal trampoline */
2498 struct target_sigcontext sf_sc;
2499 target_sigset_t sf_mask;
2502 struct target_ucontext {
2503 target_ulong tuc_flags;
2504 target_ulong tuc_link;
2505 target_stack_t tuc_stack;
2506 target_ulong pad0;
2507 struct target_sigcontext tuc_mcontext;
2508 target_sigset_t tuc_sigmask;
2511 struct target_rt_sigframe {
2512 uint32_t rs_ass[4]; /* argument save space for o32 */
2513 uint32_t rs_code[2]; /* signal trampoline */
2514 struct target_siginfo rs_info;
2515 struct target_ucontext rs_uc;
2518 /* Install trampoline to jump back from signal handler */
2519 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2521 int err;
2524 * Set up the return code ...
2526 * li v0, __NR__foo_sigreturn
2527 * syscall
2530 err = __put_user(0x24020000 + syscall, tramp + 0);
2531 err |= __put_user(0x0000000c , tramp + 1);
2532 /* flush_cache_sigtramp((unsigned long) tramp); */
2533 return err;
2536 static inline int
2537 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2539 int err = 0;
2541 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2543 #define save_gp_reg(i) do { \
2544 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2545 } while(0)
2546 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2547 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2548 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2549 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2550 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2551 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2552 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2553 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2554 save_gp_reg(31);
2555 #undef save_gp_reg
2557 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2558 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2560 /* Not used yet, but might be useful if we ever have DSP suppport */
2561 #if 0
2562 if (cpu_has_dsp) {
2563 err |= __put_user(mfhi1(), &sc->sc_hi1);
2564 err |= __put_user(mflo1(), &sc->sc_lo1);
2565 err |= __put_user(mfhi2(), &sc->sc_hi2);
2566 err |= __put_user(mflo2(), &sc->sc_lo2);
2567 err |= __put_user(mfhi3(), &sc->sc_hi3);
2568 err |= __put_user(mflo3(), &sc->sc_lo3);
2569 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2571 /* same with 64 bit */
2572 #ifdef CONFIG_64BIT
2573 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2574 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2575 if (cpu_has_dsp) {
2576 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2577 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2578 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2579 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2580 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2581 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2582 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2584 #endif
2585 #endif
2587 #if 0
2588 err |= __put_user(!!used_math(), &sc->sc_used_math);
2590 if (!used_math())
2591 goto out;
2594 * Save FPU state to signal context. Signal handler will "inherit"
2595 * current FPU state.
2597 preempt_disable();
2599 if (!is_fpu_owner()) {
2600 own_fpu();
2601 restore_fp(current);
2603 err |= save_fp_context(sc);
2605 preempt_enable();
2606 out:
2607 #endif
2608 return err;
2611 static inline int
2612 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2614 int err = 0;
2616 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2618 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2619 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2621 #define restore_gp_reg(i) do { \
2622 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2623 } while(0)
2624 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2625 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2626 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2627 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2628 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2629 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2630 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2631 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2632 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2633 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2634 restore_gp_reg(31);
2635 #undef restore_gp_reg
2637 #if 0
2638 if (cpu_has_dsp) {
2639 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2640 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2641 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2642 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2643 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2644 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2645 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2647 #ifdef CONFIG_64BIT
2648 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2649 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2650 if (cpu_has_dsp) {
2651 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2652 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2653 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2654 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2655 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2656 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2657 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2659 #endif
2661 err |= __get_user(used_math, &sc->sc_used_math);
2662 conditional_used_math(used_math);
2664 preempt_disable();
2666 if (used_math()) {
2667 /* restore fpu context if we have used it before */
2668 own_fpu();
2669 err |= restore_fp_context(sc);
2670 } else {
2671 /* signal handler may have used FPU. Give it up. */
2672 lose_fpu();
2675 preempt_enable();
2676 #endif
2677 return err;
2680 * Determine which stack to use..
2682 static inline abi_ulong
2683 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2685 unsigned long sp;
2687 /* Default to using normal stack */
2688 sp = regs->active_tc.gpr[29];
2691 * FPU emulator may have it's own trampoline active just
2692 * above the user stack, 16-bytes before the next lowest
2693 * 16 byte boundary. Try to avoid trashing it.
2695 sp -= 32;
2697 /* This is the X/Open sanctioned signal stack switching. */
2698 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2699 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2702 return (sp - frame_size) & ~7;
2705 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2706 static void setup_frame(int sig, struct target_sigaction * ka,
2707 target_sigset_t *set, CPUState *regs)
2709 struct sigframe *frame;
2710 abi_ulong frame_addr;
2711 int i;
2713 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2714 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2715 goto give_sigsegv;
2717 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2719 if(setup_sigcontext(regs, &frame->sf_sc))
2720 goto give_sigsegv;
2722 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2723 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2724 goto give_sigsegv;
2728 * Arguments to signal handler:
2730 * a0 = signal number
2731 * a1 = 0 (should be cause)
2732 * a2 = pointer to struct sigcontext
2734 * $25 and PC point to the signal handler, $29 points to the
2735 * struct sigframe.
2737 regs->active_tc.gpr[ 4] = sig;
2738 regs->active_tc.gpr[ 5] = 0;
2739 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2740 regs->active_tc.gpr[29] = frame_addr;
2741 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2742 /* The original kernel code sets CP0_EPC to the handler
2743 * since it returns to userland using eret
2744 * we cannot do this here, and we must set PC directly */
2745 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2746 unlock_user_struct(frame, frame_addr, 1);
2747 return;
2749 give_sigsegv:
2750 unlock_user_struct(frame, frame_addr, 1);
2751 force_sig(TARGET_SIGSEGV/*, current*/);
2752 return;
2755 long do_sigreturn(CPUState *regs)
2757 struct sigframe *frame;
2758 abi_ulong frame_addr;
2759 sigset_t blocked;
2760 target_sigset_t target_set;
2761 int i;
2763 #if defined(DEBUG_SIGNAL)
2764 fprintf(stderr, "do_sigreturn\n");
2765 #endif
2766 frame_addr = regs->active_tc.gpr[29];
2767 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2768 goto badframe;
2770 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2771 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2772 goto badframe;
2775 target_to_host_sigset_internal(&blocked, &target_set);
2776 sigprocmask(SIG_SETMASK, &blocked, NULL);
2778 if (restore_sigcontext(regs, &frame->sf_sc))
2779 goto badframe;
2781 #if 0
2783 * Don't let your children do this ...
2785 __asm__ __volatile__(
2786 "move\t$29, %0\n\t"
2787 "j\tsyscall_exit"
2788 :/* no outputs */
2789 :"r" (&regs));
2790 /* Unreached */
2791 #endif
2793 regs->active_tc.PC = regs->CP0_EPC;
2794 /* I am not sure this is right, but it seems to work
2795 * maybe a problem with nested signals ? */
2796 regs->CP0_EPC = 0;
2797 return -TARGET_QEMU_ESIGRETURN;
2799 badframe:
2800 force_sig(TARGET_SIGSEGV/*, current*/);
2801 return 0;
2804 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2805 target_siginfo_t *info,
2806 target_sigset_t *set, CPUState *env)
2808 struct target_rt_sigframe *frame;
2809 abi_ulong frame_addr;
2810 int i;
2812 frame_addr = get_sigframe(ka, env, sizeof(*frame));
2813 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2814 goto give_sigsegv;
2816 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
2818 copy_siginfo_to_user(&frame->rs_info, info);
2820 __put_user(0, &frame->rs_uc.tuc_flags);
2821 __put_user(0, &frame->rs_uc.tuc_link);
2822 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
2823 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
2824 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
2825 &frame->rs_uc.tuc_stack.ss_flags);
2827 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
2829 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2830 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
2834 * Arguments to signal handler:
2836 * a0 = signal number
2837 * a1 = pointer to struct siginfo
2838 * a2 = pointer to struct ucontext
2840 * $25 and PC point to the signal handler, $29 points to the
2841 * struct sigframe.
2843 env->active_tc.gpr[ 4] = sig;
2844 env->active_tc.gpr[ 5] = frame_addr
2845 + offsetof(struct target_rt_sigframe, rs_info);
2846 env->active_tc.gpr[ 6] = frame_addr
2847 + offsetof(struct target_rt_sigframe, rs_uc);
2848 env->active_tc.gpr[29] = frame_addr;
2849 env->active_tc.gpr[31] = frame_addr
2850 + offsetof(struct target_rt_sigframe, rs_code);
2851 /* The original kernel code sets CP0_EPC to the handler
2852 * since it returns to userland using eret
2853 * we cannot do this here, and we must set PC directly */
2854 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
2855 unlock_user_struct(frame, frame_addr, 1);
2856 return;
2858 give_sigsegv:
2859 unlock_user_struct(frame, frame_addr, 1);
2860 force_sig(TARGET_SIGSEGV/*, current*/);
2861 return;
2864 long do_rt_sigreturn(CPUState *env)
2866 struct target_rt_sigframe *frame;
2867 abi_ulong frame_addr;
2868 sigset_t blocked;
2870 #if defined(DEBUG_SIGNAL)
2871 fprintf(stderr, "do_rt_sigreturn\n");
2872 #endif
2873 frame_addr = env->active_tc.gpr[29];
2874 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2875 goto badframe;
2877 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
2878 sigprocmask(SIG_SETMASK, &blocked, NULL);
2880 if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
2881 goto badframe;
2883 if (do_sigaltstack(frame_addr +
2884 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
2885 0, get_sp_from_cpustate(env)) == -EFAULT)
2886 goto badframe;
2888 env->active_tc.PC = env->CP0_EPC;
2889 /* I am not sure this is right, but it seems to work
2890 * maybe a problem with nested signals ? */
2891 env->CP0_EPC = 0;
2892 return -TARGET_QEMU_ESIGRETURN;
2894 badframe:
2895 force_sig(TARGET_SIGSEGV/*, current*/);
2896 return 0;
2899 #elif defined(TARGET_SH4)
2902 * code and data structures from linux kernel:
2903 * include/asm-sh/sigcontext.h
2904 * arch/sh/kernel/signal.c
2907 struct target_sigcontext {
2908 target_ulong oldmask;
2910 /* CPU registers */
2911 target_ulong sc_gregs[16];
2912 target_ulong sc_pc;
2913 target_ulong sc_pr;
2914 target_ulong sc_sr;
2915 target_ulong sc_gbr;
2916 target_ulong sc_mach;
2917 target_ulong sc_macl;
2919 /* FPU registers */
2920 target_ulong sc_fpregs[16];
2921 target_ulong sc_xfpregs[16];
2922 unsigned int sc_fpscr;
2923 unsigned int sc_fpul;
2924 unsigned int sc_ownedfp;
2927 struct target_sigframe
2929 struct target_sigcontext sc;
2930 target_ulong extramask[TARGET_NSIG_WORDS-1];
2931 uint16_t retcode[3];
2935 struct target_ucontext {
2936 target_ulong tuc_flags;
2937 struct target_ucontext *tuc_link;
2938 target_stack_t tuc_stack;
2939 struct target_sigcontext tuc_mcontext;
2940 target_sigset_t tuc_sigmask; /* mask last for extensibility */
2943 struct target_rt_sigframe
2945 struct target_siginfo info;
2946 struct target_ucontext uc;
2947 uint16_t retcode[3];
2951 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2952 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2954 static abi_ulong get_sigframe(struct target_sigaction *ka,
2955 unsigned long sp, size_t frame_size)
2957 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2958 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2961 return (sp - frame_size) & -8ul;
2964 static int setup_sigcontext(struct target_sigcontext *sc,
2965 CPUState *regs, unsigned long mask)
2967 int err = 0;
2968 int i;
2970 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2971 COPY(gregs[0]); COPY(gregs[1]);
2972 COPY(gregs[2]); COPY(gregs[3]);
2973 COPY(gregs[4]); COPY(gregs[5]);
2974 COPY(gregs[6]); COPY(gregs[7]);
2975 COPY(gregs[8]); COPY(gregs[9]);
2976 COPY(gregs[10]); COPY(gregs[11]);
2977 COPY(gregs[12]); COPY(gregs[13]);
2978 COPY(gregs[14]); COPY(gregs[15]);
2979 COPY(gbr); COPY(mach);
2980 COPY(macl); COPY(pr);
2981 COPY(sr); COPY(pc);
2982 #undef COPY
2984 for (i=0; i<16; i++) {
2985 err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
2987 err |= __put_user(regs->fpscr, &sc->sc_fpscr);
2988 err |= __put_user(regs->fpul, &sc->sc_fpul);
2990 /* non-iBCS2 extensions.. */
2991 err |= __put_user(mask, &sc->oldmask);
2993 return err;
2996 static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
2997 target_ulong *r0_p)
2999 unsigned int err = 0;
3000 int i;
3002 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
3003 COPY(gregs[1]);
3004 COPY(gregs[2]); COPY(gregs[3]);
3005 COPY(gregs[4]); COPY(gregs[5]);
3006 COPY(gregs[6]); COPY(gregs[7]);
3007 COPY(gregs[8]); COPY(gregs[9]);
3008 COPY(gregs[10]); COPY(gregs[11]);
3009 COPY(gregs[12]); COPY(gregs[13]);
3010 COPY(gregs[14]); COPY(gregs[15]);
3011 COPY(gbr); COPY(mach);
3012 COPY(macl); COPY(pr);
3013 COPY(sr); COPY(pc);
3014 #undef COPY
3016 for (i=0; i<16; i++) {
3017 err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3019 err |= __get_user(regs->fpscr, &sc->sc_fpscr);
3020 err |= __get_user(regs->fpul, &sc->sc_fpul);
3022 regs->tra = -1; /* disable syscall checks */
3023 err |= __get_user(*r0_p, &sc->sc_gregs[0]);
3024 return err;
3027 static void setup_frame(int sig, struct target_sigaction *ka,
3028 target_sigset_t *set, CPUState *regs)
3030 struct target_sigframe *frame;
3031 abi_ulong frame_addr;
3032 int i;
3033 int err = 0;
3034 int signal;
3036 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3037 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3038 goto give_sigsegv;
3040 signal = current_exec_domain_sig(sig);
3042 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
3044 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3045 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
3048 /* Set up to return from userspace. If provided, use a stub
3049 already in userspace. */
3050 if (ka->sa_flags & TARGET_SA_RESTORER) {
3051 regs->pr = (unsigned long) ka->sa_restorer;
3052 } else {
3053 /* Generate return code (system call to sigreturn) */
3054 err |= __put_user(MOVW(2), &frame->retcode[0]);
3055 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3056 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3057 regs->pr = (unsigned long) frame->retcode;
3060 if (err)
3061 goto give_sigsegv;
3063 /* Set up registers for signal handler */
3064 regs->gregs[15] = (unsigned long) frame;
3065 regs->gregs[4] = signal; /* Arg for signal handler */
3066 regs->gregs[5] = 0;
3067 regs->gregs[6] = (unsigned long) &frame->sc;
3068 regs->pc = (unsigned long) ka->_sa_handler;
3070 unlock_user_struct(frame, frame_addr, 1);
3071 return;
3073 give_sigsegv:
3074 unlock_user_struct(frame, frame_addr, 1);
3075 force_sig(TARGET_SIGSEGV);
3078 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3079 target_siginfo_t *info,
3080 target_sigset_t *set, CPUState *regs)
3082 struct target_rt_sigframe *frame;
3083 abi_ulong frame_addr;
3084 int i;
3085 int err = 0;
3086 int signal;
3088 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3089 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3090 goto give_sigsegv;
3092 signal = current_exec_domain_sig(sig);
3094 err |= copy_siginfo_to_user(&frame->info, info);
3096 /* Create the ucontext. */
3097 err |= __put_user(0, &frame->uc.tuc_flags);
3098 err |= __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3099 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3100 &frame->uc.tuc_stack.ss_sp);
3101 err |= __put_user(sas_ss_flags(regs->gregs[15]),
3102 &frame->uc.tuc_stack.ss_flags);
3103 err |= __put_user(target_sigaltstack_used.ss_size,
3104 &frame->uc.tuc_stack.ss_size);
3105 err |= setup_sigcontext(&frame->uc.tuc_mcontext,
3106 regs, set->sig[0]);
3107 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3108 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3111 /* Set up to return from userspace. If provided, use a stub
3112 already in userspace. */
3113 if (ka->sa_flags & TARGET_SA_RESTORER) {
3114 regs->pr = (unsigned long) ka->sa_restorer;
3115 } else {
3116 /* Generate return code (system call to sigreturn) */
3117 err |= __put_user(MOVW(2), &frame->retcode[0]);
3118 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
3119 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3120 regs->pr = (unsigned long) frame->retcode;
3123 if (err)
3124 goto give_sigsegv;
3126 /* Set up registers for signal handler */
3127 regs->gregs[15] = (unsigned long) frame;
3128 regs->gregs[4] = signal; /* Arg for signal handler */
3129 regs->gregs[5] = (unsigned long) &frame->info;
3130 regs->gregs[6] = (unsigned long) &frame->uc;
3131 regs->pc = (unsigned long) ka->_sa_handler;
3133 unlock_user_struct(frame, frame_addr, 1);
3134 return;
3136 give_sigsegv:
3137 unlock_user_struct(frame, frame_addr, 1);
3138 force_sig(TARGET_SIGSEGV);
3141 long do_sigreturn(CPUState *regs)
3143 struct target_sigframe *frame;
3144 abi_ulong frame_addr;
3145 sigset_t blocked;
3146 target_sigset_t target_set;
3147 target_ulong r0;
3148 int i;
3149 int err = 0;
3151 #if defined(DEBUG_SIGNAL)
3152 fprintf(stderr, "do_sigreturn\n");
3153 #endif
3154 frame_addr = regs->gregs[15];
3155 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3156 goto badframe;
3158 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
3159 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3160 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
3163 if (err)
3164 goto badframe;
3166 target_to_host_sigset_internal(&blocked, &target_set);
3167 sigprocmask(SIG_SETMASK, &blocked, NULL);
3169 if (restore_sigcontext(regs, &frame->sc, &r0))
3170 goto badframe;
3172 unlock_user_struct(frame, frame_addr, 0);
3173 return r0;
3175 badframe:
3176 unlock_user_struct(frame, frame_addr, 0);
3177 force_sig(TARGET_SIGSEGV);
3178 return 0;
3181 long do_rt_sigreturn(CPUState *regs)
3183 struct target_rt_sigframe *frame;
3184 abi_ulong frame_addr;
3185 sigset_t blocked;
3186 target_ulong r0;
3188 #if defined(DEBUG_SIGNAL)
3189 fprintf(stderr, "do_rt_sigreturn\n");
3190 #endif
3191 frame_addr = regs->gregs[15];
3192 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3193 goto badframe;
3195 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3196 sigprocmask(SIG_SETMASK, &blocked, NULL);
3198 if (restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0))
3199 goto badframe;
3201 if (do_sigaltstack(frame_addr +
3202 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3203 0, get_sp_from_cpustate(regs)) == -EFAULT)
3204 goto badframe;
3206 unlock_user_struct(frame, frame_addr, 0);
3207 return r0;
3209 badframe:
3210 unlock_user_struct(frame, frame_addr, 0);
3211 force_sig(TARGET_SIGSEGV);
3212 return 0;
3214 #elif defined(TARGET_MICROBLAZE)
3216 struct target_sigcontext {
3217 struct target_pt_regs regs; /* needs to be first */
3218 uint32_t oldmask;
3221 struct target_stack_t {
3222 abi_ulong ss_sp;
3223 int ss_flags;
3224 unsigned int ss_size;
3227 struct target_ucontext {
3228 abi_ulong tuc_flags;
3229 abi_ulong tuc_link;
3230 struct target_stack_t tuc_stack;
3231 struct target_sigcontext tuc_mcontext;
3232 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3235 /* Signal frames. */
3236 struct target_signal_frame {
3237 struct target_ucontext uc;
3238 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3239 uint32_t tramp[2];
3242 struct rt_signal_frame {
3243 struct siginfo info;
3244 struct ucontext uc;
3245 uint32_t tramp[2];
3248 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3250 __put_user(env->regs[0], &sc->regs.r0);
3251 __put_user(env->regs[1], &sc->regs.r1);
3252 __put_user(env->regs[2], &sc->regs.r2);
3253 __put_user(env->regs[3], &sc->regs.r3);
3254 __put_user(env->regs[4], &sc->regs.r4);
3255 __put_user(env->regs[5], &sc->regs.r5);
3256 __put_user(env->regs[6], &sc->regs.r6);
3257 __put_user(env->regs[7], &sc->regs.r7);
3258 __put_user(env->regs[8], &sc->regs.r8);
3259 __put_user(env->regs[9], &sc->regs.r9);
3260 __put_user(env->regs[10], &sc->regs.r10);
3261 __put_user(env->regs[11], &sc->regs.r11);
3262 __put_user(env->regs[12], &sc->regs.r12);
3263 __put_user(env->regs[13], &sc->regs.r13);
3264 __put_user(env->regs[14], &sc->regs.r14);
3265 __put_user(env->regs[15], &sc->regs.r15);
3266 __put_user(env->regs[16], &sc->regs.r16);
3267 __put_user(env->regs[17], &sc->regs.r17);
3268 __put_user(env->regs[18], &sc->regs.r18);
3269 __put_user(env->regs[19], &sc->regs.r19);
3270 __put_user(env->regs[20], &sc->regs.r20);
3271 __put_user(env->regs[21], &sc->regs.r21);
3272 __put_user(env->regs[22], &sc->regs.r22);
3273 __put_user(env->regs[23], &sc->regs.r23);
3274 __put_user(env->regs[24], &sc->regs.r24);
3275 __put_user(env->regs[25], &sc->regs.r25);
3276 __put_user(env->regs[26], &sc->regs.r26);
3277 __put_user(env->regs[27], &sc->regs.r27);
3278 __put_user(env->regs[28], &sc->regs.r28);
3279 __put_user(env->regs[29], &sc->regs.r29);
3280 __put_user(env->regs[30], &sc->regs.r30);
3281 __put_user(env->regs[31], &sc->regs.r31);
3282 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3285 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3287 __get_user(env->regs[0], &sc->regs.r0);
3288 __get_user(env->regs[1], &sc->regs.r1);
3289 __get_user(env->regs[2], &sc->regs.r2);
3290 __get_user(env->regs[3], &sc->regs.r3);
3291 __get_user(env->regs[4], &sc->regs.r4);
3292 __get_user(env->regs[5], &sc->regs.r5);
3293 __get_user(env->regs[6], &sc->regs.r6);
3294 __get_user(env->regs[7], &sc->regs.r7);
3295 __get_user(env->regs[8], &sc->regs.r8);
3296 __get_user(env->regs[9], &sc->regs.r9);
3297 __get_user(env->regs[10], &sc->regs.r10);
3298 __get_user(env->regs[11], &sc->regs.r11);
3299 __get_user(env->regs[12], &sc->regs.r12);
3300 __get_user(env->regs[13], &sc->regs.r13);
3301 __get_user(env->regs[14], &sc->regs.r14);
3302 __get_user(env->regs[15], &sc->regs.r15);
3303 __get_user(env->regs[16], &sc->regs.r16);
3304 __get_user(env->regs[17], &sc->regs.r17);
3305 __get_user(env->regs[18], &sc->regs.r18);
3306 __get_user(env->regs[19], &sc->regs.r19);
3307 __get_user(env->regs[20], &sc->regs.r20);
3308 __get_user(env->regs[21], &sc->regs.r21);
3309 __get_user(env->regs[22], &sc->regs.r22);
3310 __get_user(env->regs[23], &sc->regs.r23);
3311 __get_user(env->regs[24], &sc->regs.r24);
3312 __get_user(env->regs[25], &sc->regs.r25);
3313 __get_user(env->regs[26], &sc->regs.r26);
3314 __get_user(env->regs[27], &sc->regs.r27);
3315 __get_user(env->regs[28], &sc->regs.r28);
3316 __get_user(env->regs[29], &sc->regs.r29);
3317 __get_user(env->regs[30], &sc->regs.r30);
3318 __get_user(env->regs[31], &sc->regs.r31);
3319 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3322 static abi_ulong get_sigframe(struct target_sigaction *ka,
3323 CPUState *env, int frame_size)
3325 abi_ulong sp = env->regs[1];
3327 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3328 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3330 return ((sp - frame_size) & -8UL);
3333 static void setup_frame(int sig, struct target_sigaction *ka,
3334 target_sigset_t *set, CPUState *env)
3336 struct target_signal_frame *frame;
3337 abi_ulong frame_addr;
3338 int err = 0;
3339 int i;
3341 frame_addr = get_sigframe(ka, env, sizeof *frame);
3342 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3343 goto badframe;
3345 /* Save the mask. */
3346 err |= __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3347 if (err)
3348 goto badframe;
3350 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3351 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3352 goto badframe;
3355 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3357 /* Set up to return from userspace. If provided, use a stub
3358 already in userspace. */
3359 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3360 if (ka->sa_flags & TARGET_SA_RESTORER) {
3361 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3362 } else {
3363 uint32_t t;
3364 /* Note, these encodings are _big endian_! */
3365 /* addi r12, r0, __NR_sigreturn */
3366 t = 0x31800000UL | TARGET_NR_sigreturn;
3367 err |= __put_user(t, frame->tramp + 0);
3368 /* brki r14, 0x8 */
3369 t = 0xb9cc0008UL;
3370 err |= __put_user(t, frame->tramp + 1);
3372 /* Return from sighandler will jump to the tramp.
3373 Negative 8 offset because return is rtsd r15, 8 */
3374 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3377 if (err)
3378 goto badframe;
3380 /* Set up registers for signal handler */
3381 env->regs[1] = (unsigned long) frame;
3382 /* Signal handler args: */
3383 env->regs[5] = sig; /* Arg 0: signum */
3384 env->regs[6] = 0;
3385 env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
3387 /* Offset of 4 to handle microblaze rtid r14, 0 */
3388 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3390 unlock_user_struct(frame, frame_addr, 1);
3391 return;
3392 badframe:
3393 unlock_user_struct(frame, frame_addr, 1);
3394 force_sig(TARGET_SIGSEGV);
3397 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3398 target_siginfo_t *info,
3399 target_sigset_t *set, CPUState *env)
3401 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3404 long do_sigreturn(CPUState *env)
3406 struct target_signal_frame *frame;
3407 abi_ulong frame_addr;
3408 target_sigset_t target_set;
3409 sigset_t set;
3410 int i;
3412 frame_addr = env->regs[R_SP];
3413 /* Make sure the guest isn't playing games. */
3414 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3415 goto badframe;
3417 /* Restore blocked signals */
3418 if (__get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask))
3419 goto badframe;
3420 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3421 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3422 goto badframe;
3424 target_to_host_sigset_internal(&set, &target_set);
3425 sigprocmask(SIG_SETMASK, &set, NULL);
3427 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3428 /* We got here through a sigreturn syscall, our path back is via an
3429 rtb insn so setup r14 for that. */
3430 env->regs[14] = env->sregs[SR_PC];
3432 unlock_user_struct(frame, frame_addr, 0);
3433 return env->regs[10];
3434 badframe:
3435 unlock_user_struct(frame, frame_addr, 0);
3436 force_sig(TARGET_SIGSEGV);
3439 long do_rt_sigreturn(CPUState *env)
3441 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3442 return -TARGET_ENOSYS;
3445 #elif defined(TARGET_CRIS)
3447 struct target_sigcontext {
3448 struct target_pt_regs regs; /* needs to be first */
3449 uint32_t oldmask;
3450 uint32_t usp; /* usp before stacking this gunk on it */
3453 /* Signal frames. */
3454 struct target_signal_frame {
3455 struct target_sigcontext sc;
3456 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3457 uint8_t retcode[8]; /* Trampoline code. */
3460 struct rt_signal_frame {
3461 struct siginfo *pinfo;
3462 void *puc;
3463 struct siginfo info;
3464 struct ucontext uc;
3465 uint8_t retcode[8]; /* Trampoline code. */
3468 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
3470 __put_user(env->regs[0], &sc->regs.r0);
3471 __put_user(env->regs[1], &sc->regs.r1);
3472 __put_user(env->regs[2], &sc->regs.r2);
3473 __put_user(env->regs[3], &sc->regs.r3);
3474 __put_user(env->regs[4], &sc->regs.r4);
3475 __put_user(env->regs[5], &sc->regs.r5);
3476 __put_user(env->regs[6], &sc->regs.r6);
3477 __put_user(env->regs[7], &sc->regs.r7);
3478 __put_user(env->regs[8], &sc->regs.r8);
3479 __put_user(env->regs[9], &sc->regs.r9);
3480 __put_user(env->regs[10], &sc->regs.r10);
3481 __put_user(env->regs[11], &sc->regs.r11);
3482 __put_user(env->regs[12], &sc->regs.r12);
3483 __put_user(env->regs[13], &sc->regs.r13);
3484 __put_user(env->regs[14], &sc->usp);
3485 __put_user(env->regs[15], &sc->regs.acr);
3486 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3487 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3488 __put_user(env->pc, &sc->regs.erp);
3491 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
3493 __get_user(env->regs[0], &sc->regs.r0);
3494 __get_user(env->regs[1], &sc->regs.r1);
3495 __get_user(env->regs[2], &sc->regs.r2);
3496 __get_user(env->regs[3], &sc->regs.r3);
3497 __get_user(env->regs[4], &sc->regs.r4);
3498 __get_user(env->regs[5], &sc->regs.r5);
3499 __get_user(env->regs[6], &sc->regs.r6);
3500 __get_user(env->regs[7], &sc->regs.r7);
3501 __get_user(env->regs[8], &sc->regs.r8);
3502 __get_user(env->regs[9], &sc->regs.r9);
3503 __get_user(env->regs[10], &sc->regs.r10);
3504 __get_user(env->regs[11], &sc->regs.r11);
3505 __get_user(env->regs[12], &sc->regs.r12);
3506 __get_user(env->regs[13], &sc->regs.r13);
3507 __get_user(env->regs[14], &sc->usp);
3508 __get_user(env->regs[15], &sc->regs.acr);
3509 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3510 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3511 __get_user(env->pc, &sc->regs.erp);
3514 static abi_ulong get_sigframe(CPUState *env, int framesize)
3516 abi_ulong sp;
3517 /* Align the stack downwards to 4. */
3518 sp = (env->regs[R_SP] & ~3);
3519 return sp - framesize;
3522 static void setup_frame(int sig, struct target_sigaction *ka,
3523 target_sigset_t *set, CPUState *env)
3525 struct target_signal_frame *frame;
3526 abi_ulong frame_addr;
3527 int err = 0;
3528 int i;
3530 frame_addr = get_sigframe(env, sizeof *frame);
3531 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3532 goto badframe;
3535 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3536 * use this trampoline anymore but it sets it up for GDB.
3537 * In QEMU, using the trampoline simplifies things a bit so we use it.
3539 * This is movu.w __NR_sigreturn, r9; break 13;
3541 err |= __put_user(0x9c5f, frame->retcode+0);
3542 err |= __put_user(TARGET_NR_sigreturn,
3543 frame->retcode+2);
3544 err |= __put_user(0xe93d, frame->retcode+4);
3546 /* Save the mask. */
3547 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3548 if (err)
3549 goto badframe;
3551 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3552 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3553 goto badframe;
3556 setup_sigcontext(&frame->sc, env);
3558 /* Move the stack and setup the arguments for the handler. */
3559 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3560 env->regs[10] = sig;
3561 env->pc = (unsigned long) ka->_sa_handler;
3562 /* Link SRP so the guest returns through the trampoline. */
3563 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3565 unlock_user_struct(frame, frame_addr, 1);
3566 return;
3567 badframe:
3568 unlock_user_struct(frame, frame_addr, 1);
3569 force_sig(TARGET_SIGSEGV);
3572 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3573 target_siginfo_t *info,
3574 target_sigset_t *set, CPUState *env)
3576 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3579 long do_sigreturn(CPUState *env)
3581 struct target_signal_frame *frame;
3582 abi_ulong frame_addr;
3583 target_sigset_t target_set;
3584 sigset_t set;
3585 int i;
3587 frame_addr = env->regs[R_SP];
3588 /* Make sure the guest isn't playing games. */
3589 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3590 goto badframe;
3592 /* Restore blocked signals */
3593 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3594 goto badframe;
3595 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3596 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3597 goto badframe;
3599 target_to_host_sigset_internal(&set, &target_set);
3600 sigprocmask(SIG_SETMASK, &set, NULL);
3602 restore_sigcontext(&frame->sc, env);
3603 unlock_user_struct(frame, frame_addr, 0);
3604 return env->regs[10];
3605 badframe:
3606 unlock_user_struct(frame, frame_addr, 0);
3607 force_sig(TARGET_SIGSEGV);
3610 long do_rt_sigreturn(CPUState *env)
3612 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3613 return -TARGET_ENOSYS;
3616 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
3618 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
3619 the signal handling is different enough that we haven't implemented
3620 support for PPC64 yet. Hence the restriction above.
3622 There are various #if'd blocks for code for TARGET_PPC64. These
3623 blocks should go away so that we can successfully run 32-bit and
3624 64-bit binaries on a QEMU configured for PPC64. */
3626 /* Size of dummy stack frame allocated when calling signal handler.
3627 See arch/powerpc/include/asm/ptrace.h. */
3628 #if defined(TARGET_PPC64)
3629 #define SIGNAL_FRAMESIZE 128
3630 #else
3631 #define SIGNAL_FRAMESIZE 64
3632 #endif
3634 /* See arch/powerpc/include/asm/sigcontext.h. */
3635 struct target_sigcontext {
3636 target_ulong _unused[4];
3637 int32_t signal;
3638 #if defined(TARGET_PPC64)
3639 int32_t pad0;
3640 #endif
3641 target_ulong handler;
3642 target_ulong oldmask;
3643 target_ulong regs; /* struct pt_regs __user * */
3644 /* TODO: PPC64 includes extra bits here. */
3647 /* Indices for target_mcontext.mc_gregs, below.
3648 See arch/powerpc/include/asm/ptrace.h for details. */
3649 enum {
3650 TARGET_PT_R0 = 0,
3651 TARGET_PT_R1 = 1,
3652 TARGET_PT_R2 = 2,
3653 TARGET_PT_R3 = 3,
3654 TARGET_PT_R4 = 4,
3655 TARGET_PT_R5 = 5,
3656 TARGET_PT_R6 = 6,
3657 TARGET_PT_R7 = 7,
3658 TARGET_PT_R8 = 8,
3659 TARGET_PT_R9 = 9,
3660 TARGET_PT_R10 = 10,
3661 TARGET_PT_R11 = 11,
3662 TARGET_PT_R12 = 12,
3663 TARGET_PT_R13 = 13,
3664 TARGET_PT_R14 = 14,
3665 TARGET_PT_R15 = 15,
3666 TARGET_PT_R16 = 16,
3667 TARGET_PT_R17 = 17,
3668 TARGET_PT_R18 = 18,
3669 TARGET_PT_R19 = 19,
3670 TARGET_PT_R20 = 20,
3671 TARGET_PT_R21 = 21,
3672 TARGET_PT_R22 = 22,
3673 TARGET_PT_R23 = 23,
3674 TARGET_PT_R24 = 24,
3675 TARGET_PT_R25 = 25,
3676 TARGET_PT_R26 = 26,
3677 TARGET_PT_R27 = 27,
3678 TARGET_PT_R28 = 28,
3679 TARGET_PT_R29 = 29,
3680 TARGET_PT_R30 = 30,
3681 TARGET_PT_R31 = 31,
3682 TARGET_PT_NIP = 32,
3683 TARGET_PT_MSR = 33,
3684 TARGET_PT_ORIG_R3 = 34,
3685 TARGET_PT_CTR = 35,
3686 TARGET_PT_LNK = 36,
3687 TARGET_PT_XER = 37,
3688 TARGET_PT_CCR = 38,
3689 /* Yes, there are two registers with #39. One is 64-bit only. */
3690 TARGET_PT_MQ = 39,
3691 TARGET_PT_SOFTE = 39,
3692 TARGET_PT_TRAP = 40,
3693 TARGET_PT_DAR = 41,
3694 TARGET_PT_DSISR = 42,
3695 TARGET_PT_RESULT = 43,
3696 TARGET_PT_REGS_COUNT = 44
3699 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
3700 on 64-bit PPC, sigcontext and mcontext are one and the same. */
3701 struct target_mcontext {
3702 target_ulong mc_gregs[48];
3703 /* Includes fpscr. */
3704 uint64_t mc_fregs[33];
3705 target_ulong mc_pad[2];
3706 /* We need to handle Altivec and SPE at the same time, which no
3707 kernel needs to do. Fortunately, the kernel defines this bit to
3708 be Altivec-register-large all the time, rather than trying to
3709 twiddle it based on the specific platform. */
3710 union {
3711 /* SPE vector registers. One extra for SPEFSCR. */
3712 uint32_t spe[33];
3713 /* Altivec vector registers. The packing of VSCR and VRSAVE
3714 varies depending on whether we're PPC64 or not: PPC64 splits
3715 them apart; PPC32 stuffs them together. */
3716 #if defined(TARGET_PPC64)
3717 #define QEMU_NVRREG 34
3718 #else
3719 #define QEMU_NVRREG 33
3720 #endif
3721 ppc_avr_t altivec[QEMU_NVRREG];
3722 #undef QEMU_NVRREG
3723 } mc_vregs __attribute__((__aligned__(16)));
3726 struct target_ucontext {
3727 target_ulong tuc_flags;
3728 target_ulong tuc_link; /* struct ucontext __user * */
3729 struct target_sigaltstack tuc_stack;
3730 #if !defined(TARGET_PPC64)
3731 int32_t tuc_pad[7];
3732 target_ulong tuc_regs; /* struct mcontext __user *
3733 points to uc_mcontext field */
3734 #endif
3735 target_sigset_t tuc_sigmask;
3736 #if defined(TARGET_PPC64)
3737 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
3738 struct target_sigcontext tuc_mcontext;
3739 #else
3740 int32_t tuc_maskext[30];
3741 int32_t tuc_pad2[3];
3742 struct target_mcontext tuc_mcontext;
3743 #endif
3746 /* See arch/powerpc/kernel/signal_32.c. */
3747 struct target_sigframe {
3748 struct target_sigcontext sctx;
3749 struct target_mcontext mctx;
3750 int32_t abigap[56];
3753 struct target_rt_sigframe {
3754 struct target_siginfo info;
3755 struct target_ucontext uc;
3756 int32_t abigap[56];
3759 /* We use the mc_pad field for the signal return trampoline. */
3760 #define tramp mc_pad
3762 /* See arch/powerpc/kernel/signal.c. */
3763 static target_ulong get_sigframe(struct target_sigaction *ka,
3764 CPUState *env,
3765 int frame_size)
3767 target_ulong oldsp, newsp;
3769 oldsp = env->gpr[1];
3771 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
3772 (sas_ss_flags(oldsp))) {
3773 oldsp = (target_sigaltstack_used.ss_sp
3774 + target_sigaltstack_used.ss_size);
3777 newsp = (oldsp - frame_size) & ~0xFUL;
3779 return newsp;
3782 static int save_user_regs(CPUState *env, struct target_mcontext *frame,
3783 int sigret)
3785 target_ulong msr = env->msr;
3786 int i;
3787 target_ulong ccr = 0;
3789 /* In general, the kernel attempts to be intelligent about what it
3790 needs to save for Altivec/FP/SPE registers. We don't care that
3791 much, so we just go ahead and save everything. */
3793 /* Save general registers. */
3794 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3795 if (__put_user(env->gpr[i], &frame->mc_gregs[i])) {
3796 return 1;
3799 if (__put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3800 || __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3801 || __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3802 || __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3803 return 1;
3805 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3806 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
3808 if (__put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3809 return 1;
3811 /* Save Altivec registers if necessary. */
3812 if (env->insns_flags & PPC_ALTIVEC) {
3813 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3814 ppc_avr_t *avr = &env->avr[i];
3815 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3817 if (__put_user(avr->u64[0], &vreg->u64[0]) ||
3818 __put_user(avr->u64[1], &vreg->u64[1])) {
3819 return 1;
3822 /* Set MSR_VR in the saved MSR value to indicate that
3823 frame->mc_vregs contains valid data. */
3824 msr |= MSR_VR;
3825 if (__put_user((uint32_t)env->spr[SPR_VRSAVE],
3826 &frame->mc_vregs.altivec[32].u32[3]))
3827 return 1;
3830 /* Save floating point registers. */
3831 if (env->insns_flags & PPC_FLOAT) {
3832 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3833 if (__put_user(env->fpr[i], &frame->mc_fregs[i])) {
3834 return 1;
3837 if (__put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]))
3838 return 1;
3841 /* Save SPE registers. The kernel only saves the high half. */
3842 if (env->insns_flags & PPC_SPE) {
3843 #if defined(TARGET_PPC64)
3844 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3845 if (__put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i])) {
3846 return 1;
3849 #else
3850 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3851 if (__put_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3852 return 1;
3855 #endif
3856 /* Set MSR_SPE in the saved MSR value to indicate that
3857 frame->mc_vregs contains valid data. */
3858 msr |= MSR_SPE;
3859 if (__put_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3860 return 1;
3863 /* Store MSR. */
3864 if (__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3865 return 1;
3867 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
3868 if (sigret) {
3869 if (__put_user(0x38000000UL | sigret, &frame->tramp[0]) ||
3870 __put_user(0x44000002UL, &frame->tramp[1])) {
3871 return 1;
3875 return 0;
3878 static int restore_user_regs(CPUState *env,
3879 struct target_mcontext *frame, int sig)
3881 target_ulong save_r2 = 0;
3882 target_ulong msr;
3883 target_ulong ccr;
3885 int i;
3887 if (!sig) {
3888 save_r2 = env->gpr[2];
3891 /* Restore general registers. */
3892 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3893 if (__get_user(env->gpr[i], &frame->mc_gregs[i])) {
3894 return 1;
3897 if (__get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP])
3898 || __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR])
3899 || __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK])
3900 || __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]))
3901 return 1;
3902 if (__get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]))
3903 return 1;
3905 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
3906 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
3909 if (!sig) {
3910 env->gpr[2] = save_r2;
3912 /* Restore MSR. */
3913 if (__get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]))
3914 return 1;
3916 /* If doing signal return, restore the previous little-endian mode. */
3917 if (sig)
3918 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
3920 /* Restore Altivec registers if necessary. */
3921 if (env->insns_flags & PPC_ALTIVEC) {
3922 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
3923 ppc_avr_t *avr = &env->avr[i];
3924 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
3926 if (__get_user(avr->u64[0], &vreg->u64[0]) ||
3927 __get_user(avr->u64[1], &vreg->u64[1])) {
3928 return 1;
3931 /* Set MSR_VEC in the saved MSR value to indicate that
3932 frame->mc_vregs contains valid data. */
3933 if (__get_user(env->spr[SPR_VRSAVE],
3934 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3])))
3935 return 1;
3938 /* Restore floating point registers. */
3939 if (env->insns_flags & PPC_FLOAT) {
3940 uint64_t fpscr;
3941 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
3942 if (__get_user(env->fpr[i], &frame->mc_fregs[i])) {
3943 return 1;
3946 if (__get_user(fpscr, &frame->mc_fregs[32]))
3947 return 1;
3948 env->fpscr = (uint32_t) fpscr;
3951 /* Save SPE registers. The kernel only saves the high half. */
3952 if (env->insns_flags & PPC_SPE) {
3953 #if defined(TARGET_PPC64)
3954 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
3955 uint32_t hi;
3957 if (__get_user(hi, &frame->mc_vregs.spe[i])) {
3958 return 1;
3960 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
3962 #else
3963 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
3964 if (__get_user(env->gprh[i], &frame->mc_vregs.spe[i])) {
3965 return 1;
3968 #endif
3969 if (__get_user(env->spe_fscr, &frame->mc_vregs.spe[32]))
3970 return 1;
3973 return 0;
3976 static void setup_frame(int sig, struct target_sigaction *ka,
3977 target_sigset_t *set, CPUState *env)
3979 struct target_sigframe *frame;
3980 struct target_sigcontext *sc;
3981 target_ulong frame_addr, newsp;
3982 int err = 0;
3983 int signal;
3985 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3986 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3987 goto sigsegv;
3988 sc = &frame->sctx;
3990 signal = current_exec_domain_sig(sig);
3992 err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
3993 err |= __put_user(set->sig[0], &sc->oldmask);
3994 #if defined(TARGET_PPC64)
3995 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
3996 #else
3997 err |= __put_user(set->sig[1], &sc->_unused[3]);
3998 #endif
3999 err |= __put_user(h2g(&frame->mctx), &sc->regs);
4000 err |= __put_user(sig, &sc->signal);
4002 /* Save user regs. */
4003 err |= save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4005 /* The kernel checks for the presence of a VDSO here. We don't
4006 emulate a vdso, so use a sigreturn system call. */
4007 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4009 /* Turn off all fp exceptions. */
4010 env->fpscr = 0;
4012 /* Create a stack frame for the caller of the handler. */
4013 newsp = frame_addr - SIGNAL_FRAMESIZE;
4014 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4016 if (err)
4017 goto sigsegv;
4019 /* Set up registers for signal handler. */
4020 env->gpr[1] = newsp;
4021 env->gpr[3] = signal;
4022 env->gpr[4] = (target_ulong) h2g(sc);
4023 env->nip = (target_ulong) ka->_sa_handler;
4024 /* Signal handlers are entered in big-endian mode. */
4025 env->msr &= ~MSR_LE;
4027 unlock_user_struct(frame, frame_addr, 1);
4028 return;
4030 sigsegv:
4031 unlock_user_struct(frame, frame_addr, 1);
4032 if (logfile)
4033 fprintf (logfile, "segfaulting from setup_frame\n");
4034 force_sig(TARGET_SIGSEGV);
4037 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4038 target_siginfo_t *info,
4039 target_sigset_t *set, CPUState *env)
4041 struct target_rt_sigframe *rt_sf;
4042 struct target_mcontext *frame;
4043 target_ulong rt_sf_addr, newsp = 0;
4044 int i, err = 0;
4045 int signal;
4047 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4048 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4049 goto sigsegv;
4051 signal = current_exec_domain_sig(sig);
4053 err |= copy_siginfo_to_user(&rt_sf->info, info);
4055 err |= __put_user(0, &rt_sf->uc.tuc_flags);
4056 err |= __put_user(0, &rt_sf->uc.tuc_link);
4057 err |= __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4058 &rt_sf->uc.tuc_stack.ss_sp);
4059 err |= __put_user(sas_ss_flags(env->gpr[1]),
4060 &rt_sf->uc.tuc_stack.ss_flags);
4061 err |= __put_user(target_sigaltstack_used.ss_size,
4062 &rt_sf->uc.tuc_stack.ss_size);
4063 err |= __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4064 &rt_sf->uc.tuc_regs);
4065 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4066 err |= __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4069 frame = &rt_sf->uc.tuc_mcontext;
4070 err |= save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4072 /* The kernel checks for the presence of a VDSO here. We don't
4073 emulate a vdso, so use a sigreturn system call. */
4074 env->lr = (target_ulong) h2g(frame->tramp);
4076 /* Turn off all fp exceptions. */
4077 env->fpscr = 0;
4079 /* Create a stack frame for the caller of the handler. */
4080 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4081 err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4083 if (err)
4084 goto sigsegv;
4086 /* Set up registers for signal handler. */
4087 env->gpr[1] = newsp;
4088 env->gpr[3] = (target_ulong) signal;
4089 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4090 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4091 env->gpr[6] = (target_ulong) h2g(rt_sf);
4092 env->nip = (target_ulong) ka->_sa_handler;
4093 /* Signal handlers are entered in big-endian mode. */
4094 env->msr &= ~MSR_LE;
4096 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4097 return;
4099 sigsegv:
4100 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4101 if (logfile)
4102 fprintf (logfile, "segfaulting from setup_rt_frame\n");
4103 force_sig(TARGET_SIGSEGV);
4107 long do_sigreturn(CPUState *env)
4109 struct target_sigcontext *sc = NULL;
4110 struct target_mcontext *sr = NULL;
4111 target_ulong sr_addr, sc_addr;
4112 sigset_t blocked;
4113 target_sigset_t set;
4115 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4116 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4117 goto sigsegv;
4119 #if defined(TARGET_PPC64)
4120 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4121 #else
4122 if(__get_user(set.sig[0], &sc->oldmask) ||
4123 __get_user(set.sig[1], &sc->_unused[3]))
4124 goto sigsegv;
4125 #endif
4126 target_to_host_sigset_internal(&blocked, &set);
4127 sigprocmask(SIG_SETMASK, &blocked, NULL);
4129 if (__get_user(sr_addr, &sc->regs))
4130 goto sigsegv;
4131 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4132 goto sigsegv;
4133 if (restore_user_regs(env, sr, 1))
4134 goto sigsegv;
4136 unlock_user_struct(sr, sr_addr, 1);
4137 unlock_user_struct(sc, sc_addr, 1);
4138 return -TARGET_QEMU_ESIGRETURN;
4140 sigsegv:
4141 unlock_user_struct(sr, sr_addr, 1);
4142 unlock_user_struct(sc, sc_addr, 1);
4143 if (logfile)
4144 fprintf (logfile, "segfaulting from do_sigreturn\n");
4145 force_sig(TARGET_SIGSEGV);
4146 return 0;
4149 /* See arch/powerpc/kernel/signal_32.c. */
4150 static int do_setcontext(struct target_ucontext *ucp, CPUState *env, int sig)
4152 struct target_mcontext *mcp;
4153 target_ulong mcp_addr;
4154 sigset_t blocked;
4155 target_sigset_t set;
4157 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4158 sizeof (set)))
4159 return 1;
4161 #if defined(TARGET_PPC64)
4162 fprintf (stderr, "do_setcontext: not implemented\n");
4163 return 0;
4164 #else
4165 if (__get_user(mcp_addr, &ucp->tuc_regs))
4166 return 1;
4168 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4169 return 1;
4171 target_to_host_sigset_internal(&blocked, &set);
4172 sigprocmask(SIG_SETMASK, &blocked, NULL);
4173 if (restore_user_regs(env, mcp, sig))
4174 goto sigsegv;
4176 unlock_user_struct(mcp, mcp_addr, 1);
4177 return 0;
4179 sigsegv:
4180 unlock_user_struct(mcp, mcp_addr, 1);
4181 return 1;
4182 #endif
4185 long do_rt_sigreturn(CPUState *env)
4187 struct target_rt_sigframe *rt_sf = NULL;
4188 target_ulong rt_sf_addr;
4190 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4191 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4192 goto sigsegv;
4194 if (do_setcontext(&rt_sf->uc, env, 1))
4195 goto sigsegv;
4197 do_sigaltstack(rt_sf_addr
4198 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4199 0, env->gpr[1]);
4201 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4202 return -TARGET_QEMU_ESIGRETURN;
4204 sigsegv:
4205 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4206 if (logfile)
4207 fprintf (logfile, "segfaulting from do_rt_sigreturn\n");
4208 force_sig(TARGET_SIGSEGV);
4209 return 0;
4212 #elif defined(TARGET_M68K)
4214 struct target_sigcontext {
4215 abi_ulong sc_mask;
4216 abi_ulong sc_usp;
4217 abi_ulong sc_d0;
4218 abi_ulong sc_d1;
4219 abi_ulong sc_a0;
4220 abi_ulong sc_a1;
4221 unsigned short sc_sr;
4222 abi_ulong sc_pc;
4225 struct target_sigframe
4227 abi_ulong pretcode;
4228 int sig;
4229 int code;
4230 abi_ulong psc;
4231 char retcode[8];
4232 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4233 struct target_sigcontext sc;
4236 typedef int target_greg_t;
4237 #define TARGET_NGREG 18
4238 typedef target_greg_t target_gregset_t[TARGET_NGREG];
4240 typedef struct target_fpregset {
4241 int f_fpcntl[3];
4242 int f_fpregs[8*3];
4243 } target_fpregset_t;
4245 struct target_mcontext {
4246 int version;
4247 target_gregset_t gregs;
4248 target_fpregset_t fpregs;
4251 #define TARGET_MCONTEXT_VERSION 2
4253 struct target_ucontext {
4254 abi_ulong tuc_flags;
4255 abi_ulong tuc_link;
4256 target_stack_t tuc_stack;
4257 struct target_mcontext tuc_mcontext;
4258 abi_long tuc_filler[80];
4259 target_sigset_t tuc_sigmask;
4262 struct target_rt_sigframe
4264 abi_ulong pretcode;
4265 int sig;
4266 abi_ulong pinfo;
4267 abi_ulong puc;
4268 char retcode[8];
4269 struct target_siginfo info;
4270 struct target_ucontext uc;
4273 static int
4274 setup_sigcontext(struct target_sigcontext *sc, CPUState *env, abi_ulong mask)
4276 int err = 0;
4278 err |= __put_user(mask, &sc->sc_mask);
4279 err |= __put_user(env->aregs[7], &sc->sc_usp);
4280 err |= __put_user(env->dregs[0], &sc->sc_d0);
4281 err |= __put_user(env->dregs[1], &sc->sc_d1);
4282 err |= __put_user(env->aregs[0], &sc->sc_a0);
4283 err |= __put_user(env->aregs[1], &sc->sc_a1);
4284 err |= __put_user(env->sr, &sc->sc_sr);
4285 err |= __put_user(env->pc, &sc->sc_pc);
4287 return err;
4290 static int
4291 restore_sigcontext(CPUState *env, struct target_sigcontext *sc, int *pd0)
4293 int err = 0;
4294 int temp;
4296 err |= __get_user(env->aregs[7], &sc->sc_usp);
4297 err |= __get_user(env->dregs[1], &sc->sc_d1);
4298 err |= __get_user(env->aregs[0], &sc->sc_a0);
4299 err |= __get_user(env->aregs[1], &sc->sc_a1);
4300 err |= __get_user(env->pc, &sc->sc_pc);
4301 err |= __get_user(temp, &sc->sc_sr);
4302 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4304 *pd0 = tswapl(sc->sc_d0);
4306 return err;
4310 * Determine which stack to use..
4312 static inline abi_ulong
4313 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
4315 unsigned long sp;
4317 sp = regs->aregs[7];
4319 /* This is the X/Open sanctioned signal stack switching. */
4320 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4321 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4324 return ((sp - frame_size) & -8UL);
4327 static void setup_frame(int sig, struct target_sigaction *ka,
4328 target_sigset_t *set, CPUState *env)
4330 struct target_sigframe *frame;
4331 abi_ulong frame_addr;
4332 abi_ulong retcode_addr;
4333 abi_ulong sc_addr;
4334 int err = 0;
4335 int i;
4337 frame_addr = get_sigframe(ka, env, sizeof *frame);
4338 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4339 goto give_sigsegv;
4341 err |= __put_user(sig, &frame->sig);
4343 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4344 err |= __put_user(sc_addr, &frame->psc);
4346 err |= setup_sigcontext(&frame->sc, env, set->sig[0]);
4347 if (err)
4348 goto give_sigsegv;
4350 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4351 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
4352 goto give_sigsegv;
4355 /* Set up to return from userspace. */
4357 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4358 err |= __put_user(retcode_addr, &frame->pretcode);
4360 /* moveq #,d0; trap #0 */
4362 err |= __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
4363 (long *)(frame->retcode));
4365 if (err)
4366 goto give_sigsegv;
4368 /* Set up to return from userspace */
4370 env->aregs[7] = frame_addr;
4371 env->pc = ka->_sa_handler;
4373 unlock_user_struct(frame, frame_addr, 1);
4374 return;
4376 give_sigsegv:
4377 unlock_user_struct(frame, frame_addr, 1);
4378 force_sig(TARGET_SIGSEGV);
4381 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
4382 CPUState *env)
4384 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4385 int err;
4387 err = __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
4388 err |= __put_user(env->dregs[0], &gregs[0]);
4389 err |= __put_user(env->dregs[1], &gregs[1]);
4390 err |= __put_user(env->dregs[2], &gregs[2]);
4391 err |= __put_user(env->dregs[3], &gregs[3]);
4392 err |= __put_user(env->dregs[4], &gregs[4]);
4393 err |= __put_user(env->dregs[5], &gregs[5]);
4394 err |= __put_user(env->dregs[6], &gregs[6]);
4395 err |= __put_user(env->dregs[7], &gregs[7]);
4396 err |= __put_user(env->aregs[0], &gregs[8]);
4397 err |= __put_user(env->aregs[1], &gregs[9]);
4398 err |= __put_user(env->aregs[2], &gregs[10]);
4399 err |= __put_user(env->aregs[3], &gregs[11]);
4400 err |= __put_user(env->aregs[4], &gregs[12]);
4401 err |= __put_user(env->aregs[5], &gregs[13]);
4402 err |= __put_user(env->aregs[6], &gregs[14]);
4403 err |= __put_user(env->aregs[7], &gregs[15]);
4404 err |= __put_user(env->pc, &gregs[16]);
4405 err |= __put_user(env->sr, &gregs[17]);
4407 return err;
4410 static inline int target_rt_restore_ucontext(CPUState *env,
4411 struct target_ucontext *uc,
4412 int *pd0)
4414 int temp;
4415 int err;
4416 target_greg_t *gregs = uc->tuc_mcontext.gregs;
4418 err = __get_user(temp, &uc->tuc_mcontext.version);
4419 if (temp != TARGET_MCONTEXT_VERSION)
4420 goto badframe;
4422 /* restore passed registers */
4423 err |= __get_user(env->dregs[0], &gregs[0]);
4424 err |= __get_user(env->dregs[1], &gregs[1]);
4425 err |= __get_user(env->dregs[2], &gregs[2]);
4426 err |= __get_user(env->dregs[3], &gregs[3]);
4427 err |= __get_user(env->dregs[4], &gregs[4]);
4428 err |= __get_user(env->dregs[5], &gregs[5]);
4429 err |= __get_user(env->dregs[6], &gregs[6]);
4430 err |= __get_user(env->dregs[7], &gregs[7]);
4431 err |= __get_user(env->aregs[0], &gregs[8]);
4432 err |= __get_user(env->aregs[1], &gregs[9]);
4433 err |= __get_user(env->aregs[2], &gregs[10]);
4434 err |= __get_user(env->aregs[3], &gregs[11]);
4435 err |= __get_user(env->aregs[4], &gregs[12]);
4436 err |= __get_user(env->aregs[5], &gregs[13]);
4437 err |= __get_user(env->aregs[6], &gregs[14]);
4438 err |= __get_user(env->aregs[7], &gregs[15]);
4439 err |= __get_user(env->pc, &gregs[16]);
4440 err |= __get_user(temp, &gregs[17]);
4441 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4443 *pd0 = env->dregs[0];
4444 return err;
4446 badframe:
4447 return 1;
4450 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4451 target_siginfo_t *info,
4452 target_sigset_t *set, CPUState *env)
4454 struct target_rt_sigframe *frame;
4455 abi_ulong frame_addr;
4456 abi_ulong retcode_addr;
4457 abi_ulong info_addr;
4458 abi_ulong uc_addr;
4459 int err = 0;
4460 int i;
4462 frame_addr = get_sigframe(ka, env, sizeof *frame);
4463 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4464 goto give_sigsegv;
4466 err |= __put_user(sig, &frame->sig);
4468 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
4469 err |= __put_user(info_addr, &frame->pinfo);
4471 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
4472 err |= __put_user(uc_addr, &frame->puc);
4474 err |= copy_siginfo_to_user(&frame->info, info);
4476 /* Create the ucontext */
4478 err |= __put_user(0, &frame->uc.tuc_flags);
4479 err |= __put_user(0, &frame->uc.tuc_link);
4480 err |= __put_user(target_sigaltstack_used.ss_sp,
4481 &frame->uc.tuc_stack.ss_sp);
4482 err |= __put_user(sas_ss_flags(env->aregs[7]),
4483 &frame->uc.tuc_stack.ss_flags);
4484 err |= __put_user(target_sigaltstack_used.ss_size,
4485 &frame->uc.tuc_stack.ss_size);
4486 err |= target_rt_setup_ucontext(&frame->uc, env);
4488 if (err)
4489 goto give_sigsegv;
4491 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4492 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
4493 goto give_sigsegv;
4496 /* Set up to return from userspace. */
4498 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4499 err |= __put_user(retcode_addr, &frame->pretcode);
4501 /* moveq #,d0; notb d0; trap #0 */
4503 err |= __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
4504 (long *)(frame->retcode + 0));
4505 err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
4507 if (err)
4508 goto give_sigsegv;
4510 /* Set up to return from userspace */
4512 env->aregs[7] = frame_addr;
4513 env->pc = ka->_sa_handler;
4515 unlock_user_struct(frame, frame_addr, 1);
4516 return;
4518 give_sigsegv:
4519 unlock_user_struct(frame, frame_addr, 1);
4520 force_sig(TARGET_SIGSEGV);
4523 long do_sigreturn(CPUState *env)
4525 struct target_sigframe *frame;
4526 abi_ulong frame_addr = env->aregs[7] - 4;
4527 target_sigset_t target_set;
4528 sigset_t set;
4529 int d0, i;
4531 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4532 goto badframe;
4534 /* set blocked signals */
4536 if (__get_user(target_set.sig[0], &frame->sc.sc_mask))
4537 goto badframe;
4539 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4540 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
4541 goto badframe;
4544 target_to_host_sigset_internal(&set, &target_set);
4545 sigprocmask(SIG_SETMASK, &set, NULL);
4547 /* restore registers */
4549 if (restore_sigcontext(env, &frame->sc, &d0))
4550 goto badframe;
4552 unlock_user_struct(frame, frame_addr, 0);
4553 return d0;
4555 badframe:
4556 unlock_user_struct(frame, frame_addr, 0);
4557 force_sig(TARGET_SIGSEGV);
4558 return 0;
4561 long do_rt_sigreturn(CPUState *env)
4563 struct target_rt_sigframe *frame;
4564 abi_ulong frame_addr = env->aregs[7] - 4;
4565 target_sigset_t target_set;
4566 sigset_t set;
4567 int d0;
4569 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
4570 goto badframe;
4572 target_to_host_sigset_internal(&set, &target_set);
4573 sigprocmask(SIG_SETMASK, &set, NULL);
4575 /* restore registers */
4577 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
4578 goto badframe;
4580 if (do_sigaltstack(frame_addr +
4581 offsetof(struct target_rt_sigframe, uc.tuc_stack),
4582 0, get_sp_from_cpustate(env)) == -EFAULT)
4583 goto badframe;
4585 unlock_user_struct(frame, frame_addr, 0);
4586 return d0;
4588 badframe:
4589 unlock_user_struct(frame, frame_addr, 0);
4590 force_sig(TARGET_SIGSEGV);
4591 return 0;
4594 #elif defined(TARGET_ALPHA)
4596 struct target_sigcontext {
4597 abi_long sc_onstack;
4598 abi_long sc_mask;
4599 abi_long sc_pc;
4600 abi_long sc_ps;
4601 abi_long sc_regs[32];
4602 abi_long sc_ownedfp;
4603 abi_long sc_fpregs[32];
4604 abi_ulong sc_fpcr;
4605 abi_ulong sc_fp_control;
4606 abi_ulong sc_reserved1;
4607 abi_ulong sc_reserved2;
4608 abi_ulong sc_ssize;
4609 abi_ulong sc_sbase;
4610 abi_ulong sc_traparg_a0;
4611 abi_ulong sc_traparg_a1;
4612 abi_ulong sc_traparg_a2;
4613 abi_ulong sc_fp_trap_pc;
4614 abi_ulong sc_fp_trigger_sum;
4615 abi_ulong sc_fp_trigger_inst;
4618 struct target_ucontext {
4619 abi_ulong tuc_flags;
4620 abi_ulong tuc_link;
4621 abi_ulong tuc_osf_sigmask;
4622 target_stack_t tuc_stack;
4623 struct target_sigcontext tuc_mcontext;
4624 target_sigset_t tuc_sigmask;
4627 struct target_sigframe {
4628 struct target_sigcontext sc;
4629 unsigned int retcode[3];
4632 struct target_rt_sigframe {
4633 target_siginfo_t info;
4634 struct target_ucontext uc;
4635 unsigned int retcode[3];
4638 #define INSN_MOV_R30_R16 0x47fe0410
4639 #define INSN_LDI_R0 0x201f0000
4640 #define INSN_CALLSYS 0x00000083
4642 static int setup_sigcontext(struct target_sigcontext *sc, CPUState *env,
4643 abi_ulong frame_addr, target_sigset_t *set)
4645 int i, err = 0;
4647 err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4648 err |= __put_user(set->sig[0], &sc->sc_mask);
4649 err |= __put_user(env->pc, &sc->sc_pc);
4650 err |= __put_user(8, &sc->sc_ps);
4652 for (i = 0; i < 31; ++i) {
4653 err |= __put_user(env->ir[i], &sc->sc_regs[i]);
4655 err |= __put_user(0, &sc->sc_regs[31]);
4657 for (i = 0; i < 31; ++i) {
4658 err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
4660 err |= __put_user(0, &sc->sc_fpregs[31]);
4661 err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
4663 err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
4664 err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
4665 err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
4667 return err;
4670 static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
4672 uint64_t fpcr;
4673 int i, err = 0;
4675 err |= __get_user(env->pc, &sc->sc_pc);
4677 for (i = 0; i < 31; ++i) {
4678 err |= __get_user(env->ir[i], &sc->sc_regs[i]);
4680 for (i = 0; i < 31; ++i) {
4681 err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
4684 err |= __get_user(fpcr, &sc->sc_fpcr);
4685 cpu_alpha_store_fpcr(env, fpcr);
4687 return err;
4690 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
4691 CPUState *env, unsigned long framesize)
4693 abi_ulong sp = env->ir[IR_SP];
4695 /* This is the X/Open sanctioned signal stack switching. */
4696 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
4697 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4699 return (sp - framesize) & -32;
4702 static void setup_frame(int sig, struct target_sigaction *ka,
4703 target_sigset_t *set, CPUState *env)
4705 abi_ulong frame_addr, r26;
4706 struct target_sigframe *frame;
4707 int err = 0;
4709 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4710 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4711 goto give_sigsegv;
4714 err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
4716 if (ka->sa_restorer) {
4717 r26 = ka->sa_restorer;
4718 } else {
4719 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4720 err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
4721 &frame->retcode[1]);
4722 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4723 /* imb() */
4724 r26 = frame_addr;
4727 unlock_user_struct(frame, frame_addr, 1);
4729 if (err) {
4730 give_sigsegv:
4731 if (sig == TARGET_SIGSEGV) {
4732 ka->_sa_handler = TARGET_SIG_DFL;
4734 force_sig(TARGET_SIGSEGV);
4737 env->ir[IR_RA] = r26;
4738 env->ir[IR_PV] = env->pc = ka->_sa_handler;
4739 env->ir[IR_A0] = sig;
4740 env->ir[IR_A1] = 0;
4741 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
4742 env->ir[IR_SP] = frame_addr;
4745 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4746 target_siginfo_t *info,
4747 target_sigset_t *set, CPUState *env)
4749 abi_ulong frame_addr, r26;
4750 struct target_rt_sigframe *frame;
4751 int i, err = 0;
4753 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4754 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4755 goto give_sigsegv;
4758 err |= copy_siginfo_to_user(&frame->info, info);
4760 err |= __put_user(0, &frame->uc.tuc_flags);
4761 err |= __put_user(0, &frame->uc.tuc_link);
4762 err |= __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
4763 err |= __put_user(target_sigaltstack_used.ss_sp,
4764 &frame->uc.tuc_stack.ss_sp);
4765 err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
4766 &frame->uc.tuc_stack.ss_flags);
4767 err |= __put_user(target_sigaltstack_used.ss_size,
4768 &frame->uc.tuc_stack.ss_size);
4769 err |= setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
4770 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
4771 err |= __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
4774 if (ka->sa_restorer) {
4775 r26 = ka->sa_restorer;
4776 } else {
4777 err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4778 err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
4779 &frame->retcode[1]);
4780 err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4781 /* imb(); */
4782 r26 = frame_addr;
4785 if (err) {
4786 give_sigsegv:
4787 if (sig == TARGET_SIGSEGV) {
4788 ka->_sa_handler = TARGET_SIG_DFL;
4790 force_sig(TARGET_SIGSEGV);
4793 env->ir[IR_RA] = r26;
4794 env->ir[IR_PV] = env->pc = ka->_sa_handler;
4795 env->ir[IR_A0] = sig;
4796 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
4797 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
4798 env->ir[IR_SP] = frame_addr;
4801 long do_sigreturn(CPUState *env)
4803 struct target_sigcontext *sc;
4804 abi_ulong sc_addr = env->ir[IR_A0];
4805 target_sigset_t target_set;
4806 sigset_t set;
4808 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
4809 goto badframe;
4812 target_sigemptyset(&target_set);
4813 if (__get_user(target_set.sig[0], &sc->sc_mask)) {
4814 goto badframe;
4817 target_to_host_sigset_internal(&set, &target_set);
4818 sigprocmask(SIG_SETMASK, &set, NULL);
4820 if (restore_sigcontext(env, sc)) {
4821 goto badframe;
4823 unlock_user_struct(sc, sc_addr, 0);
4824 return env->ir[IR_V0];
4826 badframe:
4827 unlock_user_struct(sc, sc_addr, 0);
4828 force_sig(TARGET_SIGSEGV);
4831 long do_rt_sigreturn(CPUState *env)
4833 abi_ulong frame_addr = env->ir[IR_A0];
4834 struct target_rt_sigframe *frame;
4835 sigset_t set;
4837 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4838 goto badframe;
4840 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4841 sigprocmask(SIG_SETMASK, &set, NULL);
4843 if (restore_sigcontext(env, &frame->uc.tuc_mcontext)) {
4844 goto badframe;
4846 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
4847 uc.tuc_stack),
4848 0, env->ir[IR_SP]) == -EFAULT) {
4849 goto badframe;
4852 unlock_user_struct(frame, frame_addr, 0);
4853 return env->ir[IR_V0];
4856 badframe:
4857 unlock_user_struct(frame, frame_addr, 0);
4858 force_sig(TARGET_SIGSEGV);
4861 #else
4863 static void setup_frame(int sig, struct target_sigaction *ka,
4864 target_sigset_t *set, CPUState *env)
4866 fprintf(stderr, "setup_frame: not implemented\n");
4869 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4870 target_siginfo_t *info,
4871 target_sigset_t *set, CPUState *env)
4873 fprintf(stderr, "setup_rt_frame: not implemented\n");
4876 long do_sigreturn(CPUState *env)
4878 fprintf(stderr, "do_sigreturn: not implemented\n");
4879 return -TARGET_ENOSYS;
4882 long do_rt_sigreturn(CPUState *env)
4884 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
4885 return -TARGET_ENOSYS;
4888 #endif
4890 void process_pending_signals(CPUState *cpu_env)
4892 int sig;
4893 abi_ulong handler;
4894 sigset_t set, old_set;
4895 target_sigset_t target_old_set;
4896 struct emulated_sigtable *k;
4897 struct target_sigaction *sa;
4898 struct sigqueue *q;
4899 TaskState *ts = cpu_env->opaque;
4901 if (!ts->signal_pending)
4902 return;
4904 /* FIXME: This is not threadsafe. */
4905 k = ts->sigtab;
4906 for(sig = 1; sig <= TARGET_NSIG; sig++) {
4907 if (k->pending)
4908 goto handle_signal;
4909 k++;
4911 /* if no signal is pending, just return */
4912 ts->signal_pending = 0;
4913 return;
4915 handle_signal:
4916 #ifdef DEBUG_SIGNAL
4917 fprintf(stderr, "qemu: process signal %d\n", sig);
4918 #endif
4919 /* dequeue signal */
4920 q = k->first;
4921 k->first = q->next;
4922 if (!k->first)
4923 k->pending = 0;
4925 sig = gdb_handlesig (cpu_env, sig);
4926 if (!sig) {
4927 sa = NULL;
4928 handler = TARGET_SIG_IGN;
4929 } else {
4930 sa = &sigact_table[sig - 1];
4931 handler = sa->_sa_handler;
4934 if (handler == TARGET_SIG_DFL) {
4935 /* default handler : ignore some signal. The other are job control or fatal */
4936 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
4937 kill(getpid(),SIGSTOP);
4938 } else if (sig != TARGET_SIGCHLD &&
4939 sig != TARGET_SIGURG &&
4940 sig != TARGET_SIGWINCH &&
4941 sig != TARGET_SIGCONT) {
4942 force_sig(sig);
4944 } else if (handler == TARGET_SIG_IGN) {
4945 /* ignore sig */
4946 } else if (handler == TARGET_SIG_ERR) {
4947 force_sig(sig);
4948 } else {
4949 /* compute the blocked signals during the handler execution */
4950 target_to_host_sigset(&set, &sa->sa_mask);
4951 /* SA_NODEFER indicates that the current signal should not be
4952 blocked during the handler */
4953 if (!(sa->sa_flags & TARGET_SA_NODEFER))
4954 sigaddset(&set, target_to_host_signal(sig));
4956 /* block signals in the handler using Linux */
4957 sigprocmask(SIG_BLOCK, &set, &old_set);
4958 /* save the previous blocked signal state to restore it at the
4959 end of the signal execution (see do_sigreturn) */
4960 host_to_target_sigset_internal(&target_old_set, &old_set);
4962 /* if the CPU is in VM86 mode, we restore the 32 bit values */
4963 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
4965 CPUX86State *env = cpu_env;
4966 if (env->eflags & VM_MASK)
4967 save_v86_state(env);
4969 #endif
4970 /* prepare the stack frame of the virtual CPU */
4971 if (sa->sa_flags & TARGET_SA_SIGINFO)
4972 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
4973 else
4974 setup_frame(sig, sa, &target_old_set, cpu_env);
4975 if (sa->sa_flags & TARGET_SA_RESETHAND)
4976 sa->_sa_handler = TARGET_SIG_DFL;
4978 if (q != &k->info)
4979 free_sigqueue(cpu_env, q);