irq: Slim conversion of qemu_irq to QOM
[qemu/cris-port.git] / linux-user / signal.c
blobf3b43787fd5e320b55c03d028c0a7201f6c4d518
1 /*
2 * Emulation of Linux signals
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include <sys/ucontext.h>
27 #include <sys/resource.h>
29 #include "qemu.h"
30 #include "qemu-common.h"
31 #include "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used = {
36 .ss_sp = 0,
37 .ss_size = 0,
38 .ss_flags = TARGET_SS_DISABLE,
41 static struct target_sigaction sigact_table[TARGET_NSIG];
43 static void host_signal_handler(int host_signum, siginfo_t *info,
44 void *puc);
46 static uint8_t host_to_target_signal_table[_NSIG] = {
47 [SIGHUP] = TARGET_SIGHUP,
48 [SIGINT] = TARGET_SIGINT,
49 [SIGQUIT] = TARGET_SIGQUIT,
50 [SIGILL] = TARGET_SIGILL,
51 [SIGTRAP] = TARGET_SIGTRAP,
52 [SIGABRT] = TARGET_SIGABRT,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS] = TARGET_SIGBUS,
55 [SIGFPE] = TARGET_SIGFPE,
56 [SIGKILL] = TARGET_SIGKILL,
57 [SIGUSR1] = TARGET_SIGUSR1,
58 [SIGSEGV] = TARGET_SIGSEGV,
59 [SIGUSR2] = TARGET_SIGUSR2,
60 [SIGPIPE] = TARGET_SIGPIPE,
61 [SIGALRM] = TARGET_SIGALRM,
62 [SIGTERM] = TARGET_SIGTERM,
63 #ifdef SIGSTKFLT
64 [SIGSTKFLT] = TARGET_SIGSTKFLT,
65 #endif
66 [SIGCHLD] = TARGET_SIGCHLD,
67 [SIGCONT] = TARGET_SIGCONT,
68 [SIGSTOP] = TARGET_SIGSTOP,
69 [SIGTSTP] = TARGET_SIGTSTP,
70 [SIGTTIN] = TARGET_SIGTTIN,
71 [SIGTTOU] = TARGET_SIGTTOU,
72 [SIGURG] = TARGET_SIGURG,
73 [SIGXCPU] = TARGET_SIGXCPU,
74 [SIGXFSZ] = TARGET_SIGXFSZ,
75 [SIGVTALRM] = TARGET_SIGVTALRM,
76 [SIGPROF] = TARGET_SIGPROF,
77 [SIGWINCH] = TARGET_SIGWINCH,
78 [SIGIO] = TARGET_SIGIO,
79 [SIGPWR] = TARGET_SIGPWR,
80 [SIGSYS] = TARGET_SIGSYS,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN] = __SIGRTMAX,
87 [__SIGRTMAX] = __SIGRTMIN,
89 static uint8_t target_to_host_signal_table[_NSIG];
91 static inline int on_sig_stack(unsigned long sp)
93 return (sp - target_sigaltstack_used.ss_sp
94 < target_sigaltstack_used.ss_size);
97 static inline int sas_ss_flags(unsigned long sp)
99 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
100 : on_sig_stack(sp) ? SS_ONSTACK : 0);
103 int host_to_target_signal(int sig)
105 if (sig < 0 || sig >= _NSIG)
106 return sig;
107 return host_to_target_signal_table[sig];
110 int target_to_host_signal(int sig)
112 if (sig < 0 || sig >= _NSIG)
113 return sig;
114 return target_to_host_signal_table[sig];
117 static inline void target_sigemptyset(target_sigset_t *set)
119 memset(set, 0, sizeof(*set));
122 static inline void target_sigaddset(target_sigset_t *set, int signum)
124 signum--;
125 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
126 set->sig[signum / TARGET_NSIG_BPW] |= mask;
129 static inline int target_sigismember(const target_sigset_t *set, int signum)
131 signum--;
132 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
133 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
136 static void host_to_target_sigset_internal(target_sigset_t *d,
137 const sigset_t *s)
139 int i;
140 target_sigemptyset(d);
141 for (i = 1; i <= TARGET_NSIG; i++) {
142 if (sigismember(s, i)) {
143 target_sigaddset(d, host_to_target_signal(i));
148 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
150 target_sigset_t d1;
151 int i;
153 host_to_target_sigset_internal(&d1, s);
154 for(i = 0;i < TARGET_NSIG_WORDS; i++)
155 d->sig[i] = tswapal(d1.sig[i]);
158 static void target_to_host_sigset_internal(sigset_t *d,
159 const target_sigset_t *s)
161 int i;
162 sigemptyset(d);
163 for (i = 1; i <= TARGET_NSIG; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
170 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
172 target_sigset_t s1;
173 int i;
175 for(i = 0;i < TARGET_NSIG_WORDS; i++)
176 s1.sig[i] = tswapal(s->sig[i]);
177 target_to_host_sigset_internal(d, &s1);
180 void host_to_target_old_sigset(abi_ulong *old_sigset,
181 const sigset_t *sigset)
183 target_sigset_t d;
184 host_to_target_sigset(&d, sigset);
185 *old_sigset = d.sig[0];
188 void target_to_host_old_sigset(sigset_t *sigset,
189 const abi_ulong *old_sigset)
191 target_sigset_t d;
192 int i;
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS; i++)
196 d.sig[i] = 0;
197 target_to_host_sigset(sigset, &d);
200 /* Wrapper for sigprocmask function
201 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
202 * are host signal set, not guest ones. This wraps the sigprocmask host calls
203 * that should be protected (calls originated from guest)
205 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
207 int ret;
208 sigset_t val;
209 sigset_t *temp = NULL;
210 CPUState *cpu = thread_cpu;
211 TaskState *ts = (TaskState *)cpu->opaque;
212 bool segv_was_blocked = ts->sigsegv_blocked;
214 if (set) {
215 bool has_sigsegv = sigismember(set, SIGSEGV);
216 val = *set;
217 temp = &val;
219 sigdelset(temp, SIGSEGV);
221 switch (how) {
222 case SIG_BLOCK:
223 if (has_sigsegv) {
224 ts->sigsegv_blocked = true;
226 break;
227 case SIG_UNBLOCK:
228 if (has_sigsegv) {
229 ts->sigsegv_blocked = false;
231 break;
232 case SIG_SETMASK:
233 ts->sigsegv_blocked = has_sigsegv;
234 break;
235 default:
236 g_assert_not_reached();
240 ret = sigprocmask(how, temp, oldset);
242 if (oldset && segv_was_blocked) {
243 sigaddset(oldset, SIGSEGV);
246 return ret;
249 /* siginfo conversion */
251 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
252 const siginfo_t *info)
254 int sig = host_to_target_signal(info->si_signo);
255 tinfo->si_signo = sig;
256 tinfo->si_errno = 0;
257 tinfo->si_code = info->si_code;
259 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
260 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
261 /* Should never come here, but who knows. The information for
262 the target is irrelevant. */
263 tinfo->_sifields._sigfault._addr = 0;
264 } else if (sig == TARGET_SIGIO) {
265 tinfo->_sifields._sigpoll._band = info->si_band;
266 tinfo->_sifields._sigpoll._fd = info->si_fd;
267 } else if (sig == TARGET_SIGCHLD) {
268 tinfo->_sifields._sigchld._pid = info->si_pid;
269 tinfo->_sifields._sigchld._uid = info->si_uid;
270 tinfo->_sifields._sigchld._status
271 = host_to_target_waitstatus(info->si_status);
272 tinfo->_sifields._sigchld._utime = info->si_utime;
273 tinfo->_sifields._sigchld._stime = info->si_stime;
274 } else if (sig >= TARGET_SIGRTMIN) {
275 tinfo->_sifields._rt._pid = info->si_pid;
276 tinfo->_sifields._rt._uid = info->si_uid;
277 /* XXX: potential problem if 64 bit */
278 tinfo->_sifields._rt._sigval.sival_ptr
279 = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
283 static void tswap_siginfo(target_siginfo_t *tinfo,
284 const target_siginfo_t *info)
286 int sig = info->si_signo;
287 tinfo->si_signo = tswap32(sig);
288 tinfo->si_errno = tswap32(info->si_errno);
289 tinfo->si_code = tswap32(info->si_code);
291 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
292 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
293 tinfo->_sifields._sigfault._addr
294 = tswapal(info->_sifields._sigfault._addr);
295 } else if (sig == TARGET_SIGIO) {
296 tinfo->_sifields._sigpoll._band
297 = tswap32(info->_sifields._sigpoll._band);
298 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
299 } else if (sig == TARGET_SIGCHLD) {
300 tinfo->_sifields._sigchld._pid
301 = tswap32(info->_sifields._sigchld._pid);
302 tinfo->_sifields._sigchld._uid
303 = tswap32(info->_sifields._sigchld._uid);
304 tinfo->_sifields._sigchld._status
305 = tswap32(info->_sifields._sigchld._status);
306 tinfo->_sifields._sigchld._utime
307 = tswapal(info->_sifields._sigchld._utime);
308 tinfo->_sifields._sigchld._stime
309 = tswapal(info->_sifields._sigchld._stime);
310 } else if (sig >= TARGET_SIGRTMIN) {
311 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
312 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
313 tinfo->_sifields._rt._sigval.sival_ptr
314 = tswapal(info->_sifields._rt._sigval.sival_ptr);
319 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
321 host_to_target_siginfo_noswap(tinfo, info);
322 tswap_siginfo(tinfo, tinfo);
325 /* XXX: we support only POSIX RT signals are used. */
326 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
327 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
329 info->si_signo = tswap32(tinfo->si_signo);
330 info->si_errno = tswap32(tinfo->si_errno);
331 info->si_code = tswap32(tinfo->si_code);
332 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
333 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
334 info->si_value.sival_ptr =
335 (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
338 static int fatal_signal (int sig)
340 switch (sig) {
341 case TARGET_SIGCHLD:
342 case TARGET_SIGURG:
343 case TARGET_SIGWINCH:
344 /* Ignored by default. */
345 return 0;
346 case TARGET_SIGCONT:
347 case TARGET_SIGSTOP:
348 case TARGET_SIGTSTP:
349 case TARGET_SIGTTIN:
350 case TARGET_SIGTTOU:
351 /* Job control signals. */
352 return 0;
353 default:
354 return 1;
358 /* returns 1 if given signal should dump core if not handled */
359 static int core_dump_signal(int sig)
361 switch (sig) {
362 case TARGET_SIGABRT:
363 case TARGET_SIGFPE:
364 case TARGET_SIGILL:
365 case TARGET_SIGQUIT:
366 case TARGET_SIGSEGV:
367 case TARGET_SIGTRAP:
368 case TARGET_SIGBUS:
369 return (1);
370 default:
371 return (0);
375 void signal_init(void)
377 struct sigaction act;
378 struct sigaction oact;
379 int i, j;
380 int host_sig;
382 /* generate signal conversion tables */
383 for(i = 1; i < _NSIG; i++) {
384 if (host_to_target_signal_table[i] == 0)
385 host_to_target_signal_table[i] = i;
387 for(i = 1; i < _NSIG; i++) {
388 j = host_to_target_signal_table[i];
389 target_to_host_signal_table[j] = i;
392 /* set all host signal handlers. ALL signals are blocked during
393 the handlers to serialize them. */
394 memset(sigact_table, 0, sizeof(sigact_table));
396 sigfillset(&act.sa_mask);
397 act.sa_flags = SA_SIGINFO;
398 act.sa_sigaction = host_signal_handler;
399 for(i = 1; i <= TARGET_NSIG; i++) {
400 host_sig = target_to_host_signal(i);
401 sigaction(host_sig, NULL, &oact);
402 if (oact.sa_sigaction == (void *)SIG_IGN) {
403 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
404 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
405 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
407 /* If there's already a handler installed then something has
408 gone horribly wrong, so don't even try to handle that case. */
409 /* Install some handlers for our own use. We need at least
410 SIGSEGV and SIGBUS, to detect exceptions. We can not just
411 trap all signals because it affects syscall interrupt
412 behavior. But do trap all default-fatal signals. */
413 if (fatal_signal (i))
414 sigaction(host_sig, &act, NULL);
418 /* signal queue handling */
420 static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
422 CPUState *cpu = ENV_GET_CPU(env);
423 TaskState *ts = cpu->opaque;
424 struct sigqueue *q = ts->first_free;
425 if (!q)
426 return NULL;
427 ts->first_free = q->next;
428 return q;
431 static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
433 CPUState *cpu = ENV_GET_CPU(env);
434 TaskState *ts = cpu->opaque;
436 q->next = ts->first_free;
437 ts->first_free = q;
440 /* abort execution with signal */
441 static void QEMU_NORETURN force_sig(int target_sig)
443 CPUState *cpu = thread_cpu;
444 CPUArchState *env = cpu->env_ptr;
445 TaskState *ts = (TaskState *)cpu->opaque;
446 int host_sig, core_dumped = 0;
447 struct sigaction act;
448 host_sig = target_to_host_signal(target_sig);
449 gdb_signalled(env, target_sig);
451 /* dump core if supported by target binary format */
452 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
453 stop_all_tasks();
454 core_dumped =
455 ((*ts->bprm->core_dump)(target_sig, env) == 0);
457 if (core_dumped) {
458 /* we already dumped the core of target process, we don't want
459 * a coredump of qemu itself */
460 struct rlimit nodump;
461 getrlimit(RLIMIT_CORE, &nodump);
462 nodump.rlim_cur=0;
463 setrlimit(RLIMIT_CORE, &nodump);
464 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
465 target_sig, strsignal(host_sig), "core dumped" );
468 /* The proper exit code for dying from an uncaught signal is
469 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
470 * a negative value. To get the proper exit code we need to
471 * actually die from an uncaught signal. Here the default signal
472 * handler is installed, we send ourself a signal and we wait for
473 * it to arrive. */
474 sigfillset(&act.sa_mask);
475 act.sa_handler = SIG_DFL;
476 act.sa_flags = 0;
477 sigaction(host_sig, &act, NULL);
479 /* For some reason raise(host_sig) doesn't send the signal when
480 * statically linked on x86-64. */
481 kill(getpid(), host_sig);
483 /* Make sure the signal isn't masked (just reuse the mask inside
484 of act) */
485 sigdelset(&act.sa_mask, host_sig);
486 sigsuspend(&act.sa_mask);
488 /* unreachable */
489 abort();
492 /* queue a signal so that it will be send to the virtual CPU as soon
493 as possible */
494 int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
496 CPUState *cpu = ENV_GET_CPU(env);
497 TaskState *ts = cpu->opaque;
498 struct emulated_sigtable *k;
499 struct sigqueue *q, **pq;
500 abi_ulong handler;
501 int queue;
503 #if defined(DEBUG_SIGNAL)
504 fprintf(stderr, "queue_signal: sig=%d\n",
505 sig);
506 #endif
507 k = &ts->sigtab[sig - 1];
508 queue = gdb_queuesig ();
509 handler = sigact_table[sig - 1]._sa_handler;
511 if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {
512 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
513 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
514 * because it got a real MMU fault). A blocked SIGSEGV in that
515 * situation is treated as if using the default handler. This is
516 * not correct if some other process has randomly sent us a SIGSEGV
517 * via kill(), but that is not easy to distinguish at this point,
518 * so we assume it doesn't happen.
520 handler = TARGET_SIG_DFL;
523 if (!queue && handler == TARGET_SIG_DFL) {
524 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
525 kill(getpid(),SIGSTOP);
526 return 0;
527 } else
528 /* default handler : ignore some signal. The other are fatal */
529 if (sig != TARGET_SIGCHLD &&
530 sig != TARGET_SIGURG &&
531 sig != TARGET_SIGWINCH &&
532 sig != TARGET_SIGCONT) {
533 force_sig(sig);
534 } else {
535 return 0; /* indicate ignored */
537 } else if (!queue && handler == TARGET_SIG_IGN) {
538 /* ignore signal */
539 return 0;
540 } else if (!queue && handler == TARGET_SIG_ERR) {
541 force_sig(sig);
542 } else {
543 pq = &k->first;
544 if (sig < TARGET_SIGRTMIN) {
545 /* if non real time signal, we queue exactly one signal */
546 if (!k->pending)
547 q = &k->info;
548 else
549 return 0;
550 } else {
551 if (!k->pending) {
552 /* first signal */
553 q = &k->info;
554 } else {
555 q = alloc_sigqueue(env);
556 if (!q)
557 return -EAGAIN;
558 while (*pq != NULL)
559 pq = &(*pq)->next;
562 *pq = q;
563 q->info = *info;
564 q->next = NULL;
565 k->pending = 1;
566 /* signal that a new signal is pending */
567 ts->signal_pending = 1;
568 return 1; /* indicates that the signal was queued */
572 static void host_signal_handler(int host_signum, siginfo_t *info,
573 void *puc)
575 CPUArchState *env = thread_cpu->env_ptr;
576 int sig;
577 target_siginfo_t tinfo;
579 /* the CPU emulator uses some host signals to detect exceptions,
580 we forward to it some signals */
581 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
582 && info->si_code > 0) {
583 if (cpu_signal_handler(host_signum, info, puc))
584 return;
587 /* get target signal number */
588 sig = host_to_target_signal(host_signum);
589 if (sig < 1 || sig > TARGET_NSIG)
590 return;
591 #if defined(DEBUG_SIGNAL)
592 fprintf(stderr, "qemu: got signal %d\n", sig);
593 #endif
594 host_to_target_siginfo_noswap(&tinfo, info);
595 if (queue_signal(env, sig, &tinfo) == 1) {
596 /* interrupt the virtual CPU as soon as possible */
597 cpu_exit(thread_cpu);
601 /* do_sigaltstack() returns target values and errnos. */
602 /* compare linux/kernel/signal.c:do_sigaltstack() */
603 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
605 int ret;
606 struct target_sigaltstack oss;
608 /* XXX: test errors */
609 if(uoss_addr)
611 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
612 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
613 __put_user(sas_ss_flags(sp), &oss.ss_flags);
616 if(uss_addr)
618 struct target_sigaltstack *uss;
619 struct target_sigaltstack ss;
621 ret = -TARGET_EFAULT;
622 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
623 goto out;
625 __get_user(ss.ss_sp, &uss->ss_sp);
626 __get_user(ss.ss_size, &uss->ss_size);
627 __get_user(ss.ss_flags, &uss->ss_flags);
628 unlock_user_struct(uss, uss_addr, 0);
630 ret = -TARGET_EPERM;
631 if (on_sig_stack(sp))
632 goto out;
634 ret = -TARGET_EINVAL;
635 if (ss.ss_flags != TARGET_SS_DISABLE
636 && ss.ss_flags != TARGET_SS_ONSTACK
637 && ss.ss_flags != 0)
638 goto out;
640 if (ss.ss_flags == TARGET_SS_DISABLE) {
641 ss.ss_size = 0;
642 ss.ss_sp = 0;
643 } else {
644 ret = -TARGET_ENOMEM;
645 if (ss.ss_size < MINSIGSTKSZ)
646 goto out;
649 target_sigaltstack_used.ss_sp = ss.ss_sp;
650 target_sigaltstack_used.ss_size = ss.ss_size;
653 if (uoss_addr) {
654 ret = -TARGET_EFAULT;
655 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
656 goto out;
659 ret = 0;
660 out:
661 return ret;
664 /* do_sigaction() return host values and errnos */
665 int do_sigaction(int sig, const struct target_sigaction *act,
666 struct target_sigaction *oact)
668 struct target_sigaction *k;
669 struct sigaction act1;
670 int host_sig;
671 int ret = 0;
673 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
674 return -EINVAL;
675 k = &sigact_table[sig - 1];
676 #if defined(DEBUG_SIGNAL)
677 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
678 sig, act, oact);
679 #endif
680 if (oact) {
681 __put_user(k->_sa_handler, &oact->_sa_handler);
682 __put_user(k->sa_flags, &oact->sa_flags);
683 #if !defined(TARGET_MIPS)
684 __put_user(k->sa_restorer, &oact->sa_restorer);
685 #endif
686 /* Not swapped. */
687 oact->sa_mask = k->sa_mask;
689 if (act) {
690 /* FIXME: This is not threadsafe. */
691 __get_user(k->_sa_handler, &act->_sa_handler);
692 __get_user(k->sa_flags, &act->sa_flags);
693 #if !defined(TARGET_MIPS)
694 __get_user(k->sa_restorer, &act->sa_restorer);
695 #endif
696 /* To be swapped in target_to_host_sigset. */
697 k->sa_mask = act->sa_mask;
699 /* we update the host linux signal state */
700 host_sig = target_to_host_signal(sig);
701 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
702 sigfillset(&act1.sa_mask);
703 act1.sa_flags = SA_SIGINFO;
704 if (k->sa_flags & TARGET_SA_RESTART)
705 act1.sa_flags |= SA_RESTART;
706 /* NOTE: it is important to update the host kernel signal
707 ignore state to avoid getting unexpected interrupted
708 syscalls */
709 if (k->_sa_handler == TARGET_SIG_IGN) {
710 act1.sa_sigaction = (void *)SIG_IGN;
711 } else if (k->_sa_handler == TARGET_SIG_DFL) {
712 if (fatal_signal (sig))
713 act1.sa_sigaction = host_signal_handler;
714 else
715 act1.sa_sigaction = (void *)SIG_DFL;
716 } else {
717 act1.sa_sigaction = host_signal_handler;
719 ret = sigaction(host_sig, &act1, NULL);
722 return ret;
725 static inline void copy_siginfo_to_user(target_siginfo_t *tinfo,
726 const target_siginfo_t *info)
728 tswap_siginfo(tinfo, info);
731 static inline int current_exec_domain_sig(int sig)
733 return /* current->exec_domain && current->exec_domain->signal_invmap
734 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
737 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
739 /* from the Linux kernel */
741 struct target_fpreg {
742 uint16_t significand[4];
743 uint16_t exponent;
746 struct target_fpxreg {
747 uint16_t significand[4];
748 uint16_t exponent;
749 uint16_t padding[3];
752 struct target_xmmreg {
753 abi_ulong element[4];
756 struct target_fpstate {
757 /* Regular FPU environment */
758 abi_ulong cw;
759 abi_ulong sw;
760 abi_ulong tag;
761 abi_ulong ipoff;
762 abi_ulong cssel;
763 abi_ulong dataoff;
764 abi_ulong datasel;
765 struct target_fpreg _st[8];
766 uint16_t status;
767 uint16_t magic; /* 0xffff = regular FPU data only */
769 /* FXSR FPU environment */
770 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
771 abi_ulong mxcsr;
772 abi_ulong reserved;
773 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
774 struct target_xmmreg _xmm[8];
775 abi_ulong padding[56];
778 #define X86_FXSR_MAGIC 0x0000
780 struct target_sigcontext {
781 uint16_t gs, __gsh;
782 uint16_t fs, __fsh;
783 uint16_t es, __esh;
784 uint16_t ds, __dsh;
785 abi_ulong edi;
786 abi_ulong esi;
787 abi_ulong ebp;
788 abi_ulong esp;
789 abi_ulong ebx;
790 abi_ulong edx;
791 abi_ulong ecx;
792 abi_ulong eax;
793 abi_ulong trapno;
794 abi_ulong err;
795 abi_ulong eip;
796 uint16_t cs, __csh;
797 abi_ulong eflags;
798 abi_ulong esp_at_signal;
799 uint16_t ss, __ssh;
800 abi_ulong fpstate; /* pointer */
801 abi_ulong oldmask;
802 abi_ulong cr2;
805 struct target_ucontext {
806 abi_ulong tuc_flags;
807 abi_ulong tuc_link;
808 target_stack_t tuc_stack;
809 struct target_sigcontext tuc_mcontext;
810 target_sigset_t tuc_sigmask; /* mask last for extensibility */
813 struct sigframe
815 abi_ulong pretcode;
816 int sig;
817 struct target_sigcontext sc;
818 struct target_fpstate fpstate;
819 abi_ulong extramask[TARGET_NSIG_WORDS-1];
820 char retcode[8];
823 struct rt_sigframe
825 abi_ulong pretcode;
826 int sig;
827 abi_ulong pinfo;
828 abi_ulong puc;
829 struct target_siginfo info;
830 struct target_ucontext uc;
831 struct target_fpstate fpstate;
832 char retcode[8];
836 * Set up a signal frame.
839 /* XXX: save x87 state */
840 static void setup_sigcontext(struct target_sigcontext *sc,
841 struct target_fpstate *fpstate, CPUX86State *env, abi_ulong mask,
842 abi_ulong fpstate_addr)
844 CPUState *cs = CPU(x86_env_get_cpu(env));
845 uint16_t magic;
847 /* already locked in setup_frame() */
848 __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
849 __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
850 __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
851 __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
852 __put_user(env->regs[R_EDI], &sc->edi);
853 __put_user(env->regs[R_ESI], &sc->esi);
854 __put_user(env->regs[R_EBP], &sc->ebp);
855 __put_user(env->regs[R_ESP], &sc->esp);
856 __put_user(env->regs[R_EBX], &sc->ebx);
857 __put_user(env->regs[R_EDX], &sc->edx);
858 __put_user(env->regs[R_ECX], &sc->ecx);
859 __put_user(env->regs[R_EAX], &sc->eax);
860 __put_user(cs->exception_index, &sc->trapno);
861 __put_user(env->error_code, &sc->err);
862 __put_user(env->eip, &sc->eip);
863 __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
864 __put_user(env->eflags, &sc->eflags);
865 __put_user(env->regs[R_ESP], &sc->esp_at_signal);
866 __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
868 cpu_x86_fsave(env, fpstate_addr, 1);
869 fpstate->status = fpstate->sw;
870 magic = 0xffff;
871 __put_user(magic, &fpstate->magic);
872 __put_user(fpstate_addr, &sc->fpstate);
874 /* non-iBCS2 extensions.. */
875 __put_user(mask, &sc->oldmask);
876 __put_user(env->cr[2], &sc->cr2);
880 * Determine which stack to use..
883 static inline abi_ulong
884 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
886 unsigned long esp;
888 /* Default to using normal stack */
889 esp = env->regs[R_ESP];
890 /* This is the X/Open sanctioned signal stack switching. */
891 if (ka->sa_flags & TARGET_SA_ONSTACK) {
892 if (sas_ss_flags(esp) == 0)
893 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
896 /* This is the legacy signal stack switching. */
897 else
898 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
899 !(ka->sa_flags & TARGET_SA_RESTORER) &&
900 ka->sa_restorer) {
901 esp = (unsigned long) ka->sa_restorer;
903 return (esp - frame_size) & -8ul;
906 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
907 static void setup_frame(int sig, struct target_sigaction *ka,
908 target_sigset_t *set, CPUX86State *env)
910 abi_ulong frame_addr;
911 struct sigframe *frame;
912 int i;
914 frame_addr = get_sigframe(ka, env, sizeof(*frame));
916 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
917 goto give_sigsegv;
919 __put_user(current_exec_domain_sig(sig),
920 &frame->sig);
922 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
923 frame_addr + offsetof(struct sigframe, fpstate));
925 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
926 __put_user(set->sig[i], &frame->extramask[i - 1]);
929 /* Set up to return from userspace. If provided, use a stub
930 already in userspace. */
931 if (ka->sa_flags & TARGET_SA_RESTORER) {
932 __put_user(ka->sa_restorer, &frame->pretcode);
933 } else {
934 uint16_t val16;
935 abi_ulong retcode_addr;
936 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
937 __put_user(retcode_addr, &frame->pretcode);
938 /* This is popl %eax ; movl $,%eax ; int $0x80 */
939 val16 = 0xb858;
940 __put_user(val16, (uint16_t *)(frame->retcode+0));
941 __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
942 val16 = 0x80cd;
943 __put_user(val16, (uint16_t *)(frame->retcode+6));
947 /* Set up registers for signal handler */
948 env->regs[R_ESP] = frame_addr;
949 env->eip = ka->_sa_handler;
951 cpu_x86_load_seg(env, R_DS, __USER_DS);
952 cpu_x86_load_seg(env, R_ES, __USER_DS);
953 cpu_x86_load_seg(env, R_SS, __USER_DS);
954 cpu_x86_load_seg(env, R_CS, __USER_CS);
955 env->eflags &= ~TF_MASK;
957 unlock_user_struct(frame, frame_addr, 1);
959 return;
961 give_sigsegv:
962 if (sig == TARGET_SIGSEGV)
963 ka->_sa_handler = TARGET_SIG_DFL;
964 force_sig(TARGET_SIGSEGV /* , current */);
967 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
968 static void setup_rt_frame(int sig, struct target_sigaction *ka,
969 target_siginfo_t *info,
970 target_sigset_t *set, CPUX86State *env)
972 abi_ulong frame_addr, addr;
973 struct rt_sigframe *frame;
974 int i;
976 frame_addr = get_sigframe(ka, env, sizeof(*frame));
978 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
979 goto give_sigsegv;
981 __put_user(current_exec_domain_sig(sig), &frame->sig);
982 addr = frame_addr + offsetof(struct rt_sigframe, info);
983 __put_user(addr, &frame->pinfo);
984 addr = frame_addr + offsetof(struct rt_sigframe, uc);
985 __put_user(addr, &frame->puc);
986 copy_siginfo_to_user(&frame->info, info);
988 /* Create the ucontext. */
989 __put_user(0, &frame->uc.tuc_flags);
990 __put_user(0, &frame->uc.tuc_link);
991 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
992 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
993 &frame->uc.tuc_stack.ss_flags);
994 __put_user(target_sigaltstack_used.ss_size,
995 &frame->uc.tuc_stack.ss_size);
996 setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, env,
997 set->sig[0], frame_addr + offsetof(struct rt_sigframe, fpstate));
999 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1000 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
1003 /* Set up to return from userspace. If provided, use a stub
1004 already in userspace. */
1005 if (ka->sa_flags & TARGET_SA_RESTORER) {
1006 __put_user(ka->sa_restorer, &frame->pretcode);
1007 } else {
1008 uint16_t val16;
1009 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
1010 __put_user(addr, &frame->pretcode);
1011 /* This is movl $,%eax ; int $0x80 */
1012 __put_user(0xb8, (char *)(frame->retcode+0));
1013 __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
1014 val16 = 0x80cd;
1015 __put_user(val16, (uint16_t *)(frame->retcode+5));
1018 /* Set up registers for signal handler */
1019 env->regs[R_ESP] = frame_addr;
1020 env->eip = ka->_sa_handler;
1022 cpu_x86_load_seg(env, R_DS, __USER_DS);
1023 cpu_x86_load_seg(env, R_ES, __USER_DS);
1024 cpu_x86_load_seg(env, R_SS, __USER_DS);
1025 cpu_x86_load_seg(env, R_CS, __USER_CS);
1026 env->eflags &= ~TF_MASK;
1028 unlock_user_struct(frame, frame_addr, 1);
1030 return;
1032 give_sigsegv:
1033 if (sig == TARGET_SIGSEGV)
1034 ka->_sa_handler = TARGET_SIG_DFL;
1035 force_sig(TARGET_SIGSEGV /* , current */);
1038 static int
1039 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
1041 unsigned int err = 0;
1042 abi_ulong fpstate_addr;
1043 unsigned int tmpflags;
1045 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
1046 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
1047 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
1048 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
1050 env->regs[R_EDI] = tswapl(sc->edi);
1051 env->regs[R_ESI] = tswapl(sc->esi);
1052 env->regs[R_EBP] = tswapl(sc->ebp);
1053 env->regs[R_ESP] = tswapl(sc->esp);
1054 env->regs[R_EBX] = tswapl(sc->ebx);
1055 env->regs[R_EDX] = tswapl(sc->edx);
1056 env->regs[R_ECX] = tswapl(sc->ecx);
1057 env->eip = tswapl(sc->eip);
1059 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
1060 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
1062 tmpflags = tswapl(sc->eflags);
1063 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1064 // regs->orig_eax = -1; /* disable syscall checks */
1066 fpstate_addr = tswapl(sc->fpstate);
1067 if (fpstate_addr != 0) {
1068 if (!access_ok(VERIFY_READ, fpstate_addr,
1069 sizeof(struct target_fpstate)))
1070 goto badframe;
1071 cpu_x86_frstor(env, fpstate_addr, 1);
1074 *peax = tswapl(sc->eax);
1075 return err;
1076 badframe:
1077 return 1;
1080 long do_sigreturn(CPUX86State *env)
1082 struct sigframe *frame;
1083 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1084 target_sigset_t target_set;
1085 sigset_t set;
1086 int eax, i;
1088 #if defined(DEBUG_SIGNAL)
1089 fprintf(stderr, "do_sigreturn\n");
1090 #endif
1091 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1092 goto badframe;
1093 /* set blocked signals */
1094 __get_user(target_set.sig[0], &frame->sc.oldmask);
1095 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1096 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
1099 target_to_host_sigset_internal(&set, &target_set);
1100 do_sigprocmask(SIG_SETMASK, &set, NULL);
1102 /* restore registers */
1103 if (restore_sigcontext(env, &frame->sc, &eax))
1104 goto badframe;
1105 unlock_user_struct(frame, frame_addr, 0);
1106 return eax;
1108 badframe:
1109 unlock_user_struct(frame, frame_addr, 0);
1110 force_sig(TARGET_SIGSEGV);
1111 return 0;
1114 long do_rt_sigreturn(CPUX86State *env)
1116 abi_ulong frame_addr;
1117 struct rt_sigframe *frame;
1118 sigset_t set;
1119 int eax;
1121 frame_addr = env->regs[R_ESP] - 4;
1122 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1123 goto badframe;
1124 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1125 do_sigprocmask(SIG_SETMASK, &set, NULL);
1127 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1128 goto badframe;
1130 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1131 get_sp_from_cpustate(env)) == -EFAULT)
1132 goto badframe;
1134 unlock_user_struct(frame, frame_addr, 0);
1135 return eax;
1137 badframe:
1138 unlock_user_struct(frame, frame_addr, 0);
1139 force_sig(TARGET_SIGSEGV);
1140 return 0;
1143 #elif defined(TARGET_AARCH64)
1145 struct target_sigcontext {
1146 uint64_t fault_address;
1147 /* AArch64 registers */
1148 uint64_t regs[31];
1149 uint64_t sp;
1150 uint64_t pc;
1151 uint64_t pstate;
1152 /* 4K reserved for FP/SIMD state and future expansion */
1153 char __reserved[4096] __attribute__((__aligned__(16)));
1156 struct target_ucontext {
1157 abi_ulong tuc_flags;
1158 abi_ulong tuc_link;
1159 target_stack_t tuc_stack;
1160 target_sigset_t tuc_sigmask;
1161 /* glibc uses a 1024-bit sigset_t */
1162 char __unused[1024 / 8 - sizeof(target_sigset_t)];
1163 /* last for future expansion */
1164 struct target_sigcontext tuc_mcontext;
1168 * Header to be used at the beginning of structures extending the user
1169 * context. Such structures must be placed after the rt_sigframe on the stack
1170 * and be 16-byte aligned. The last structure must be a dummy one with the
1171 * magic and size set to 0.
1173 struct target_aarch64_ctx {
1174 uint32_t magic;
1175 uint32_t size;
1178 #define TARGET_FPSIMD_MAGIC 0x46508001
1180 struct target_fpsimd_context {
1181 struct target_aarch64_ctx head;
1182 uint32_t fpsr;
1183 uint32_t fpcr;
1184 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
1188 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1189 * user space as it will change with the addition of new context. User space
1190 * should check the magic/size information.
1192 struct target_aux_context {
1193 struct target_fpsimd_context fpsimd;
1194 /* additional context to be added before "end" */
1195 struct target_aarch64_ctx end;
1198 struct target_rt_sigframe {
1199 struct target_siginfo info;
1200 struct target_ucontext uc;
1201 uint64_t fp;
1202 uint64_t lr;
1203 uint32_t tramp[2];
1206 static int target_setup_sigframe(struct target_rt_sigframe *sf,
1207 CPUARMState *env, target_sigset_t *set)
1209 int i;
1210 struct target_aux_context *aux =
1211 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1213 /* set up the stack frame for unwinding */
1214 __put_user(env->xregs[29], &sf->fp);
1215 __put_user(env->xregs[30], &sf->lr);
1217 for (i = 0; i < 31; i++) {
1218 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1220 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1221 __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
1222 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
1224 __put_user(env->exception.vaddress, &sf->uc.tuc_mcontext.fault_address);
1226 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
1227 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
1230 for (i = 0; i < 32; i++) {
1231 #ifdef TARGET_WORDS_BIGENDIAN
1232 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1233 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1234 #else
1235 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1236 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1237 #endif
1239 __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
1240 __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
1241 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
1242 __put_user(sizeof(struct target_fpsimd_context),
1243 &aux->fpsimd.head.size);
1245 /* set the "end" magic */
1246 __put_user(0, &aux->end.magic);
1247 __put_user(0, &aux->end.size);
1249 return 0;
1252 static int target_restore_sigframe(CPUARMState *env,
1253 struct target_rt_sigframe *sf)
1255 sigset_t set;
1256 int i;
1257 struct target_aux_context *aux =
1258 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1259 uint32_t magic, size, fpsr, fpcr;
1260 uint64_t pstate;
1262 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1263 do_sigprocmask(SIG_SETMASK, &set, NULL);
1265 for (i = 0; i < 31; i++) {
1266 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1269 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1270 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
1271 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
1272 pstate_write(env, pstate);
1274 __get_user(magic, &aux->fpsimd.head.magic);
1275 __get_user(size, &aux->fpsimd.head.size);
1277 if (magic != TARGET_FPSIMD_MAGIC
1278 || size != sizeof(struct target_fpsimd_context)) {
1279 return 1;
1282 for (i = 0; i < 32; i++) {
1283 #ifdef TARGET_WORDS_BIGENDIAN
1284 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1285 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1286 #else
1287 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1288 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1289 #endif
1291 __get_user(fpsr, &aux->fpsimd.fpsr);
1292 vfp_set_fpsr(env, fpsr);
1293 __get_user(fpcr, &aux->fpsimd.fpcr);
1294 vfp_set_fpcr(env, fpcr);
1296 return 0;
1299 static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1301 abi_ulong sp;
1303 sp = env->xregs[31];
1306 * This is the X/Open sanctioned signal stack switching.
1308 if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
1309 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1312 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1314 return sp;
1317 static void target_setup_frame(int usig, struct target_sigaction *ka,
1318 target_siginfo_t *info, target_sigset_t *set,
1319 CPUARMState *env)
1321 struct target_rt_sigframe *frame;
1322 abi_ulong frame_addr, return_addr;
1324 frame_addr = get_sigframe(ka, env);
1325 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1326 goto give_sigsegv;
1329 __put_user(0, &frame->uc.tuc_flags);
1330 __put_user(0, &frame->uc.tuc_link);
1332 __put_user(target_sigaltstack_used.ss_sp,
1333 &frame->uc.tuc_stack.ss_sp);
1334 __put_user(sas_ss_flags(env->xregs[31]),
1335 &frame->uc.tuc_stack.ss_flags);
1336 __put_user(target_sigaltstack_used.ss_size,
1337 &frame->uc.tuc_stack.ss_size);
1338 target_setup_sigframe(frame, env, set);
1339 if (ka->sa_flags & TARGET_SA_RESTORER) {
1340 return_addr = ka->sa_restorer;
1341 } else {
1342 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1343 __put_user(0xd2801168, &frame->tramp[0]);
1344 __put_user(0xd4000001, &frame->tramp[1]);
1345 return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
1347 env->xregs[0] = usig;
1348 env->xregs[31] = frame_addr;
1349 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
1350 env->pc = ka->_sa_handler;
1351 env->xregs[30] = return_addr;
1352 if (info) {
1353 copy_siginfo_to_user(&frame->info, info);
1354 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1355 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1358 unlock_user_struct(frame, frame_addr, 1);
1359 return;
1361 give_sigsegv:
1362 unlock_user_struct(frame, frame_addr, 1);
1363 force_sig(TARGET_SIGSEGV);
1366 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1367 target_siginfo_t *info, target_sigset_t *set,
1368 CPUARMState *env)
1370 target_setup_frame(sig, ka, info, set, env);
1373 static void setup_frame(int sig, struct target_sigaction *ka,
1374 target_sigset_t *set, CPUARMState *env)
1376 target_setup_frame(sig, ka, 0, set, env);
1379 long do_rt_sigreturn(CPUARMState *env)
1381 struct target_rt_sigframe *frame = NULL;
1382 abi_ulong frame_addr = env->xregs[31];
1384 if (frame_addr & 15) {
1385 goto badframe;
1388 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1389 goto badframe;
1392 if (target_restore_sigframe(env, frame)) {
1393 goto badframe;
1396 if (do_sigaltstack(frame_addr +
1397 offsetof(struct target_rt_sigframe, uc.tuc_stack),
1398 0, get_sp_from_cpustate(env)) == -EFAULT) {
1399 goto badframe;
1402 unlock_user_struct(frame, frame_addr, 0);
1403 return env->xregs[0];
1405 badframe:
1406 unlock_user_struct(frame, frame_addr, 0);
1407 force_sig(TARGET_SIGSEGV);
1408 return 0;
1411 long do_sigreturn(CPUARMState *env)
1413 return do_rt_sigreturn(env);
1416 #elif defined(TARGET_ARM)
1418 struct target_sigcontext {
1419 abi_ulong trap_no;
1420 abi_ulong error_code;
1421 abi_ulong oldmask;
1422 abi_ulong arm_r0;
1423 abi_ulong arm_r1;
1424 abi_ulong arm_r2;
1425 abi_ulong arm_r3;
1426 abi_ulong arm_r4;
1427 abi_ulong arm_r5;
1428 abi_ulong arm_r6;
1429 abi_ulong arm_r7;
1430 abi_ulong arm_r8;
1431 abi_ulong arm_r9;
1432 abi_ulong arm_r10;
1433 abi_ulong arm_fp;
1434 abi_ulong arm_ip;
1435 abi_ulong arm_sp;
1436 abi_ulong arm_lr;
1437 abi_ulong arm_pc;
1438 abi_ulong arm_cpsr;
1439 abi_ulong fault_address;
1442 struct target_ucontext_v1 {
1443 abi_ulong tuc_flags;
1444 abi_ulong tuc_link;
1445 target_stack_t tuc_stack;
1446 struct target_sigcontext tuc_mcontext;
1447 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1450 struct target_ucontext_v2 {
1451 abi_ulong tuc_flags;
1452 abi_ulong tuc_link;
1453 target_stack_t tuc_stack;
1454 struct target_sigcontext tuc_mcontext;
1455 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1456 char __unused[128 - sizeof(target_sigset_t)];
1457 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1460 struct target_user_vfp {
1461 uint64_t fpregs[32];
1462 abi_ulong fpscr;
1465 struct target_user_vfp_exc {
1466 abi_ulong fpexc;
1467 abi_ulong fpinst;
1468 abi_ulong fpinst2;
1471 struct target_vfp_sigframe {
1472 abi_ulong magic;
1473 abi_ulong size;
1474 struct target_user_vfp ufp;
1475 struct target_user_vfp_exc ufp_exc;
1476 } __attribute__((__aligned__(8)));
1478 struct target_iwmmxt_sigframe {
1479 abi_ulong magic;
1480 abi_ulong size;
1481 uint64_t regs[16];
1482 /* Note that not all the coprocessor control registers are stored here */
1483 uint32_t wcssf;
1484 uint32_t wcasf;
1485 uint32_t wcgr0;
1486 uint32_t wcgr1;
1487 uint32_t wcgr2;
1488 uint32_t wcgr3;
1489 } __attribute__((__aligned__(8)));
1491 #define TARGET_VFP_MAGIC 0x56465001
1492 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1494 struct sigframe_v1
1496 struct target_sigcontext sc;
1497 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1498 abi_ulong retcode;
1501 struct sigframe_v2
1503 struct target_ucontext_v2 uc;
1504 abi_ulong retcode;
1507 struct rt_sigframe_v1
1509 abi_ulong pinfo;
1510 abi_ulong puc;
1511 struct target_siginfo info;
1512 struct target_ucontext_v1 uc;
1513 abi_ulong retcode;
1516 struct rt_sigframe_v2
1518 struct target_siginfo info;
1519 struct target_ucontext_v2 uc;
1520 abi_ulong retcode;
1523 #define TARGET_CONFIG_CPU_32 1
1526 * For ARM syscalls, we encode the syscall number into the instruction.
1528 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1529 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1532 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1533 * need two 16-bit instructions.
1535 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1536 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1538 static const abi_ulong retcodes[4] = {
1539 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1540 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1544 static inline int valid_user_regs(CPUARMState *regs)
1546 return 1;
1549 static void
1550 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1551 CPUARMState *env, abi_ulong mask)
1553 __put_user(env->regs[0], &sc->arm_r0);
1554 __put_user(env->regs[1], &sc->arm_r1);
1555 __put_user(env->regs[2], &sc->arm_r2);
1556 __put_user(env->regs[3], &sc->arm_r3);
1557 __put_user(env->regs[4], &sc->arm_r4);
1558 __put_user(env->regs[5], &sc->arm_r5);
1559 __put_user(env->regs[6], &sc->arm_r6);
1560 __put_user(env->regs[7], &sc->arm_r7);
1561 __put_user(env->regs[8], &sc->arm_r8);
1562 __put_user(env->regs[9], &sc->arm_r9);
1563 __put_user(env->regs[10], &sc->arm_r10);
1564 __put_user(env->regs[11], &sc->arm_fp);
1565 __put_user(env->regs[12], &sc->arm_ip);
1566 __put_user(env->regs[13], &sc->arm_sp);
1567 __put_user(env->regs[14], &sc->arm_lr);
1568 __put_user(env->regs[15], &sc->arm_pc);
1569 #ifdef TARGET_CONFIG_CPU_32
1570 __put_user(cpsr_read(env), &sc->arm_cpsr);
1571 #endif
1573 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1574 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1575 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1576 __put_user(mask, &sc->oldmask);
1579 static inline abi_ulong
1580 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1582 unsigned long sp = regs->regs[13];
1585 * This is the X/Open sanctioned signal stack switching.
1587 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1588 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1590 * ATPCS B01 mandates 8-byte alignment
1592 return (sp - framesize) & ~7;
1595 static void
1596 setup_return(CPUARMState *env, struct target_sigaction *ka,
1597 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1599 abi_ulong handler = ka->_sa_handler;
1600 abi_ulong retcode;
1601 int thumb = handler & 1;
1602 uint32_t cpsr = cpsr_read(env);
1604 cpsr &= ~CPSR_IT;
1605 if (thumb) {
1606 cpsr |= CPSR_T;
1607 } else {
1608 cpsr &= ~CPSR_T;
1611 if (ka->sa_flags & TARGET_SA_RESTORER) {
1612 retcode = ka->sa_restorer;
1613 } else {
1614 unsigned int idx = thumb;
1616 if (ka->sa_flags & TARGET_SA_SIGINFO)
1617 idx += 2;
1619 __put_user(retcodes[idx], rc);
1621 retcode = rc_addr + thumb;
1624 env->regs[0] = usig;
1625 env->regs[13] = frame_addr;
1626 env->regs[14] = retcode;
1627 env->regs[15] = handler & (thumb ? ~1 : ~3);
1628 cpsr_write(env, cpsr, 0xffffffff);
1631 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1633 int i;
1634 struct target_vfp_sigframe *vfpframe;
1635 vfpframe = (struct target_vfp_sigframe *)regspace;
1636 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1637 __put_user(sizeof(*vfpframe), &vfpframe->size);
1638 for (i = 0; i < 32; i++) {
1639 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1641 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1642 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1643 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1644 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1645 return (abi_ulong*)(vfpframe+1);
1648 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1649 CPUARMState *env)
1651 int i;
1652 struct target_iwmmxt_sigframe *iwmmxtframe;
1653 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1654 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1655 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1656 for (i = 0; i < 16; i++) {
1657 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1659 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1660 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1661 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1662 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1663 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1664 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1665 return (abi_ulong*)(iwmmxtframe+1);
1668 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1669 target_sigset_t *set, CPUARMState *env)
1671 struct target_sigaltstack stack;
1672 int i;
1673 abi_ulong *regspace;
1675 /* Clear all the bits of the ucontext we don't use. */
1676 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1678 memset(&stack, 0, sizeof(stack));
1679 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1680 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1681 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1682 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1684 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1685 /* Save coprocessor signal frame. */
1686 regspace = uc->tuc_regspace;
1687 if (arm_feature(env, ARM_FEATURE_VFP)) {
1688 regspace = setup_sigframe_v2_vfp(regspace, env);
1690 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1691 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1694 /* Write terminating magic word */
1695 __put_user(0, regspace);
1697 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1698 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1702 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1703 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1704 target_sigset_t *set, CPUARMState *regs)
1706 struct sigframe_v1 *frame;
1707 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1708 int i;
1710 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1711 return;
1713 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1715 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1716 __put_user(set->sig[i], &frame->extramask[i - 1]);
1719 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1720 frame_addr + offsetof(struct sigframe_v1, retcode));
1722 unlock_user_struct(frame, frame_addr, 1);
1725 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1726 target_sigset_t *set, CPUARMState *regs)
1728 struct sigframe_v2 *frame;
1729 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1731 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1732 return;
1734 setup_sigframe_v2(&frame->uc, set, regs);
1736 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1737 frame_addr + offsetof(struct sigframe_v2, retcode));
1739 unlock_user_struct(frame, frame_addr, 1);
1742 static void setup_frame(int usig, struct target_sigaction *ka,
1743 target_sigset_t *set, CPUARMState *regs)
1745 if (get_osversion() >= 0x020612) {
1746 setup_frame_v2(usig, ka, set, regs);
1747 } else {
1748 setup_frame_v1(usig, ka, set, regs);
1752 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1753 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1754 target_siginfo_t *info,
1755 target_sigset_t *set, CPUARMState *env)
1757 struct rt_sigframe_v1 *frame;
1758 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1759 struct target_sigaltstack stack;
1760 int i;
1761 abi_ulong info_addr, uc_addr;
1763 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1764 return /* 1 */;
1766 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1767 __put_user(info_addr, &frame->pinfo);
1768 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1769 __put_user(uc_addr, &frame->puc);
1770 copy_siginfo_to_user(&frame->info, info);
1772 /* Clear all the bits of the ucontext we don't use. */
1773 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1775 memset(&stack, 0, sizeof(stack));
1776 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1777 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1778 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1779 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1781 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1782 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1783 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
1786 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1787 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1789 env->regs[1] = info_addr;
1790 env->regs[2] = uc_addr;
1792 unlock_user_struct(frame, frame_addr, 1);
1795 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1796 target_siginfo_t *info,
1797 target_sigset_t *set, CPUARMState *env)
1799 struct rt_sigframe_v2 *frame;
1800 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1801 abi_ulong info_addr, uc_addr;
1803 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1804 return /* 1 */;
1806 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1807 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1808 copy_siginfo_to_user(&frame->info, info);
1810 setup_sigframe_v2(&frame->uc, set, env);
1812 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1813 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1815 env->regs[1] = info_addr;
1816 env->regs[2] = uc_addr;
1818 unlock_user_struct(frame, frame_addr, 1);
1821 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1822 target_siginfo_t *info,
1823 target_sigset_t *set, CPUARMState *env)
1825 if (get_osversion() >= 0x020612) {
1826 setup_rt_frame_v2(usig, ka, info, set, env);
1827 } else {
1828 setup_rt_frame_v1(usig, ka, info, set, env);
1832 static int
1833 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1835 int err = 0;
1836 uint32_t cpsr;
1838 __get_user(env->regs[0], &sc->arm_r0);
1839 __get_user(env->regs[1], &sc->arm_r1);
1840 __get_user(env->regs[2], &sc->arm_r2);
1841 __get_user(env->regs[3], &sc->arm_r3);
1842 __get_user(env->regs[4], &sc->arm_r4);
1843 __get_user(env->regs[5], &sc->arm_r5);
1844 __get_user(env->regs[6], &sc->arm_r6);
1845 __get_user(env->regs[7], &sc->arm_r7);
1846 __get_user(env->regs[8], &sc->arm_r8);
1847 __get_user(env->regs[9], &sc->arm_r9);
1848 __get_user(env->regs[10], &sc->arm_r10);
1849 __get_user(env->regs[11], &sc->arm_fp);
1850 __get_user(env->regs[12], &sc->arm_ip);
1851 __get_user(env->regs[13], &sc->arm_sp);
1852 __get_user(env->regs[14], &sc->arm_lr);
1853 __get_user(env->regs[15], &sc->arm_pc);
1854 #ifdef TARGET_CONFIG_CPU_32
1855 __get_user(cpsr, &sc->arm_cpsr);
1856 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1857 #endif
1859 err |= !valid_user_regs(env);
1861 return err;
1864 static long do_sigreturn_v1(CPUARMState *env)
1866 abi_ulong frame_addr;
1867 struct sigframe_v1 *frame = NULL;
1868 target_sigset_t set;
1869 sigset_t host_set;
1870 int i;
1873 * Since we stacked the signal on a 64-bit boundary,
1874 * then 'sp' should be word aligned here. If it's
1875 * not, then the user is trying to mess with us.
1877 frame_addr = env->regs[13];
1878 if (frame_addr & 7) {
1879 goto badframe;
1882 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1883 goto badframe;
1885 __get_user(set.sig[0], &frame->sc.oldmask);
1886 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1887 __get_user(set.sig[i], &frame->extramask[i - 1]);
1890 target_to_host_sigset_internal(&host_set, &set);
1891 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
1893 if (restore_sigcontext(env, &frame->sc))
1894 goto badframe;
1896 #if 0
1897 /* Send SIGTRAP if we're single-stepping */
1898 if (ptrace_cancel_bpt(current))
1899 send_sig(SIGTRAP, current, 1);
1900 #endif
1901 unlock_user_struct(frame, frame_addr, 0);
1902 return env->regs[0];
1904 badframe:
1905 force_sig(TARGET_SIGSEGV /* , current */);
1906 return 0;
1909 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1911 int i;
1912 abi_ulong magic, sz;
1913 uint32_t fpscr, fpexc;
1914 struct target_vfp_sigframe *vfpframe;
1915 vfpframe = (struct target_vfp_sigframe *)regspace;
1917 __get_user(magic, &vfpframe->magic);
1918 __get_user(sz, &vfpframe->size);
1919 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1920 return 0;
1922 for (i = 0; i < 32; i++) {
1923 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1925 __get_user(fpscr, &vfpframe->ufp.fpscr);
1926 vfp_set_fpscr(env, fpscr);
1927 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1928 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1929 * and the exception flag is cleared
1931 fpexc |= (1 << 30);
1932 fpexc &= ~((1 << 31) | (1 << 28));
1933 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1934 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1935 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1936 return (abi_ulong*)(vfpframe + 1);
1939 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1940 abi_ulong *regspace)
1942 int i;
1943 abi_ulong magic, sz;
1944 struct target_iwmmxt_sigframe *iwmmxtframe;
1945 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1947 __get_user(magic, &iwmmxtframe->magic);
1948 __get_user(sz, &iwmmxtframe->size);
1949 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1950 return 0;
1952 for (i = 0; i < 16; i++) {
1953 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1955 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1956 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1957 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1958 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1959 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1960 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1961 return (abi_ulong*)(iwmmxtframe + 1);
1964 static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1965 struct target_ucontext_v2 *uc)
1967 sigset_t host_set;
1968 abi_ulong *regspace;
1970 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1971 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
1973 if (restore_sigcontext(env, &uc->tuc_mcontext))
1974 return 1;
1976 /* Restore coprocessor signal frame */
1977 regspace = uc->tuc_regspace;
1978 if (arm_feature(env, ARM_FEATURE_VFP)) {
1979 regspace = restore_sigframe_v2_vfp(env, regspace);
1980 if (!regspace) {
1981 return 1;
1984 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1985 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1986 if (!regspace) {
1987 return 1;
1991 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1992 return 1;
1994 #if 0
1995 /* Send SIGTRAP if we're single-stepping */
1996 if (ptrace_cancel_bpt(current))
1997 send_sig(SIGTRAP, current, 1);
1998 #endif
2000 return 0;
2003 static long do_sigreturn_v2(CPUARMState *env)
2005 abi_ulong frame_addr;
2006 struct sigframe_v2 *frame = NULL;
2009 * Since we stacked the signal on a 64-bit boundary,
2010 * then 'sp' should be word aligned here. If it's
2011 * not, then the user is trying to mess with us.
2013 frame_addr = env->regs[13];
2014 if (frame_addr & 7) {
2015 goto badframe;
2018 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2019 goto badframe;
2021 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2022 goto badframe;
2024 unlock_user_struct(frame, frame_addr, 0);
2025 return env->regs[0];
2027 badframe:
2028 unlock_user_struct(frame, frame_addr, 0);
2029 force_sig(TARGET_SIGSEGV /* , current */);
2030 return 0;
2033 long do_sigreturn(CPUARMState *env)
2035 if (get_osversion() >= 0x020612) {
2036 return do_sigreturn_v2(env);
2037 } else {
2038 return do_sigreturn_v1(env);
2042 static long do_rt_sigreturn_v1(CPUARMState *env)
2044 abi_ulong frame_addr;
2045 struct rt_sigframe_v1 *frame = NULL;
2046 sigset_t host_set;
2049 * Since we stacked the signal on a 64-bit boundary,
2050 * then 'sp' should be word aligned here. If it's
2051 * not, then the user is trying to mess with us.
2053 frame_addr = env->regs[13];
2054 if (frame_addr & 7) {
2055 goto badframe;
2058 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2059 goto badframe;
2061 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2062 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
2064 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2065 goto badframe;
2067 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2068 goto badframe;
2070 #if 0
2071 /* Send SIGTRAP if we're single-stepping */
2072 if (ptrace_cancel_bpt(current))
2073 send_sig(SIGTRAP, current, 1);
2074 #endif
2075 unlock_user_struct(frame, frame_addr, 0);
2076 return env->regs[0];
2078 badframe:
2079 unlock_user_struct(frame, frame_addr, 0);
2080 force_sig(TARGET_SIGSEGV /* , current */);
2081 return 0;
2084 static long do_rt_sigreturn_v2(CPUARMState *env)
2086 abi_ulong frame_addr;
2087 struct rt_sigframe_v2 *frame = NULL;
2090 * Since we stacked the signal on a 64-bit boundary,
2091 * then 'sp' should be word aligned here. If it's
2092 * not, then the user is trying to mess with us.
2094 frame_addr = env->regs[13];
2095 if (frame_addr & 7) {
2096 goto badframe;
2099 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2100 goto badframe;
2102 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2103 goto badframe;
2105 unlock_user_struct(frame, frame_addr, 0);
2106 return env->regs[0];
2108 badframe:
2109 unlock_user_struct(frame, frame_addr, 0);
2110 force_sig(TARGET_SIGSEGV /* , current */);
2111 return 0;
2114 long do_rt_sigreturn(CPUARMState *env)
2116 if (get_osversion() >= 0x020612) {
2117 return do_rt_sigreturn_v2(env);
2118 } else {
2119 return do_rt_sigreturn_v1(env);
2123 #elif defined(TARGET_SPARC)
2125 #define __SUNOS_MAXWIN 31
2127 /* This is what SunOS does, so shall I. */
2128 struct target_sigcontext {
2129 abi_ulong sigc_onstack; /* state to restore */
2131 abi_ulong sigc_mask; /* sigmask to restore */
2132 abi_ulong sigc_sp; /* stack pointer */
2133 abi_ulong sigc_pc; /* program counter */
2134 abi_ulong sigc_npc; /* next program counter */
2135 abi_ulong sigc_psr; /* for condition codes etc */
2136 abi_ulong sigc_g1; /* User uses these two registers */
2137 abi_ulong sigc_o0; /* within the trampoline code. */
2139 /* Now comes information regarding the users window set
2140 * at the time of the signal.
2142 abi_ulong sigc_oswins; /* outstanding windows */
2144 /* stack ptrs for each regwin buf */
2145 char *sigc_spbuf[__SUNOS_MAXWIN];
2147 /* Windows to restore after signal */
2148 struct {
2149 abi_ulong locals[8];
2150 abi_ulong ins[8];
2151 } sigc_wbuf[__SUNOS_MAXWIN];
2153 /* A Sparc stack frame */
2154 struct sparc_stackf {
2155 abi_ulong locals[8];
2156 abi_ulong ins[8];
2157 /* It's simpler to treat fp and callers_pc as elements of ins[]
2158 * since we never need to access them ourselves.
2160 char *structptr;
2161 abi_ulong xargs[6];
2162 abi_ulong xxargs[1];
2165 typedef struct {
2166 struct {
2167 abi_ulong psr;
2168 abi_ulong pc;
2169 abi_ulong npc;
2170 abi_ulong y;
2171 abi_ulong u_regs[16]; /* globals and ins */
2172 } si_regs;
2173 int si_mask;
2174 } __siginfo_t;
2176 typedef struct {
2177 abi_ulong si_float_regs[32];
2178 unsigned long si_fsr;
2179 unsigned long si_fpqdepth;
2180 struct {
2181 unsigned long *insn_addr;
2182 unsigned long insn;
2183 } si_fpqueue [16];
2184 } qemu_siginfo_fpu_t;
2187 struct target_signal_frame {
2188 struct sparc_stackf ss;
2189 __siginfo_t info;
2190 abi_ulong fpu_save;
2191 abi_ulong insns[2] __attribute__ ((aligned (8)));
2192 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
2193 abi_ulong extra_size; /* Should be 0 */
2194 qemu_siginfo_fpu_t fpu_state;
2196 struct target_rt_signal_frame {
2197 struct sparc_stackf ss;
2198 siginfo_t info;
2199 abi_ulong regs[20];
2200 sigset_t mask;
2201 abi_ulong fpu_save;
2202 unsigned int insns[2];
2203 stack_t stack;
2204 unsigned int extra_size; /* Should be 0 */
2205 qemu_siginfo_fpu_t fpu_state;
2208 #define UREG_O0 16
2209 #define UREG_O6 22
2210 #define UREG_I0 0
2211 #define UREG_I1 1
2212 #define UREG_I2 2
2213 #define UREG_I3 3
2214 #define UREG_I4 4
2215 #define UREG_I5 5
2216 #define UREG_I6 6
2217 #define UREG_I7 7
2218 #define UREG_L0 8
2219 #define UREG_FP UREG_I6
2220 #define UREG_SP UREG_O6
2222 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2223 CPUSPARCState *env,
2224 unsigned long framesize)
2226 abi_ulong sp;
2228 sp = env->regwptr[UREG_FP];
2230 /* This is the X/Open sanctioned signal stack switching. */
2231 if (sa->sa_flags & TARGET_SA_ONSTACK) {
2232 if (!on_sig_stack(sp)
2233 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2234 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2236 return sp - framesize;
2239 static int
2240 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2242 int err = 0, i;
2244 __put_user(env->psr, &si->si_regs.psr);
2245 __put_user(env->pc, &si->si_regs.pc);
2246 __put_user(env->npc, &si->si_regs.npc);
2247 __put_user(env->y, &si->si_regs.y);
2248 for (i=0; i < 8; i++) {
2249 __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
2251 for (i=0; i < 8; i++) {
2252 __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2254 __put_user(mask, &si->si_mask);
2255 return err;
2258 #if 0
2259 static int
2260 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2261 CPUSPARCState *env, unsigned long mask)
2263 int err = 0;
2265 __put_user(mask, &sc->sigc_mask);
2266 __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
2267 __put_user(env->pc, &sc->sigc_pc);
2268 __put_user(env->npc, &sc->sigc_npc);
2269 __put_user(env->psr, &sc->sigc_psr);
2270 __put_user(env->gregs[1], &sc->sigc_g1);
2271 __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
2273 return err;
2275 #endif
2276 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2278 static void setup_frame(int sig, struct target_sigaction *ka,
2279 target_sigset_t *set, CPUSPARCState *env)
2281 abi_ulong sf_addr;
2282 struct target_signal_frame *sf;
2283 int sigframe_size, err, i;
2285 /* 1. Make sure everything is clean */
2286 //synchronize_user_stack();
2288 sigframe_size = NF_ALIGNEDSZ;
2289 sf_addr = get_sigframe(ka, env, sigframe_size);
2291 sf = lock_user(VERIFY_WRITE, sf_addr,
2292 sizeof(struct target_signal_frame), 0);
2293 if (!sf)
2294 goto sigsegv;
2296 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2297 #if 0
2298 if (invalid_frame_pointer(sf, sigframe_size))
2299 goto sigill_and_return;
2300 #endif
2301 /* 2. Save the current process state */
2302 err = setup___siginfo(&sf->info, env, set->sig[0]);
2303 __put_user(0, &sf->extra_size);
2305 //save_fpu_state(regs, &sf->fpu_state);
2306 //__put_user(&sf->fpu_state, &sf->fpu_save);
2308 __put_user(set->sig[0], &sf->info.si_mask);
2309 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2310 __put_user(set->sig[i + 1], &sf->extramask[i]);
2313 for (i = 0; i < 8; i++) {
2314 __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2316 for (i = 0; i < 8; i++) {
2317 __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
2319 if (err)
2320 goto sigsegv;
2322 /* 3. signal handler back-trampoline and parameters */
2323 env->regwptr[UREG_FP] = sf_addr;
2324 env->regwptr[UREG_I0] = sig;
2325 env->regwptr[UREG_I1] = sf_addr +
2326 offsetof(struct target_signal_frame, info);
2327 env->regwptr[UREG_I2] = sf_addr +
2328 offsetof(struct target_signal_frame, info);
2330 /* 4. signal handler */
2331 env->pc = ka->_sa_handler;
2332 env->npc = (env->pc + 4);
2333 /* 5. return to kernel instructions */
2334 if (ka->sa_restorer)
2335 env->regwptr[UREG_I7] = ka->sa_restorer;
2336 else {
2337 uint32_t val32;
2339 env->regwptr[UREG_I7] = sf_addr +
2340 offsetof(struct target_signal_frame, insns) - 2 * 4;
2342 /* mov __NR_sigreturn, %g1 */
2343 val32 = 0x821020d8;
2344 __put_user(val32, &sf->insns[0]);
2346 /* t 0x10 */
2347 val32 = 0x91d02010;
2348 __put_user(val32, &sf->insns[1]);
2349 if (err)
2350 goto sigsegv;
2352 /* Flush instruction space. */
2353 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2354 // tb_flush(env);
2356 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2357 return;
2358 #if 0
2359 sigill_and_return:
2360 force_sig(TARGET_SIGILL);
2361 #endif
2362 sigsegv:
2363 //fprintf(stderr, "force_sig\n");
2364 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2365 force_sig(TARGET_SIGSEGV);
2368 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2369 target_siginfo_t *info,
2370 target_sigset_t *set, CPUSPARCState *env)
2372 fprintf(stderr, "setup_rt_frame: not implemented\n");
2375 long do_sigreturn(CPUSPARCState *env)
2377 abi_ulong sf_addr;
2378 struct target_signal_frame *sf;
2379 uint32_t up_psr, pc, npc;
2380 target_sigset_t set;
2381 sigset_t host_set;
2382 int err=0, i;
2384 sf_addr = env->regwptr[UREG_FP];
2385 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2386 goto segv_and_exit;
2387 #if 0
2388 fprintf(stderr, "sigreturn\n");
2389 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2390 #endif
2391 //cpu_dump_state(env, stderr, fprintf, 0);
2393 /* 1. Make sure we are not getting garbage from the user */
2395 if (sf_addr & 3)
2396 goto segv_and_exit;
2398 __get_user(pc, &sf->info.si_regs.pc);
2399 __get_user(npc, &sf->info.si_regs.npc);
2401 if ((pc | npc) & 3)
2402 goto segv_and_exit;
2404 /* 2. Restore the state */
2405 __get_user(up_psr, &sf->info.si_regs.psr);
2407 /* User can only change condition codes and FPU enabling in %psr. */
2408 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2409 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2411 env->pc = pc;
2412 env->npc = npc;
2413 __get_user(env->y, &sf->info.si_regs.y);
2414 for (i=0; i < 8; i++) {
2415 __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2417 for (i=0; i < 8; i++) {
2418 __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2421 /* FIXME: implement FPU save/restore:
2422 * __get_user(fpu_save, &sf->fpu_save);
2423 * if (fpu_save)
2424 * err |= restore_fpu_state(env, fpu_save);
2427 /* This is pretty much atomic, no amount locking would prevent
2428 * the races which exist anyways.
2430 __get_user(set.sig[0], &sf->info.si_mask);
2431 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2432 __get_user(set.sig[i], &sf->extramask[i - 1]);
2435 target_to_host_sigset_internal(&host_set, &set);
2436 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
2438 if (err)
2439 goto segv_and_exit;
2440 unlock_user_struct(sf, sf_addr, 0);
2441 return env->regwptr[0];
2443 segv_and_exit:
2444 unlock_user_struct(sf, sf_addr, 0);
2445 force_sig(TARGET_SIGSEGV);
2448 long do_rt_sigreturn(CPUSPARCState *env)
2450 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2451 return -TARGET_ENOSYS;
2454 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2455 #define MC_TSTATE 0
2456 #define MC_PC 1
2457 #define MC_NPC 2
2458 #define MC_Y 3
2459 #define MC_G1 4
2460 #define MC_G2 5
2461 #define MC_G3 6
2462 #define MC_G4 7
2463 #define MC_G5 8
2464 #define MC_G6 9
2465 #define MC_G7 10
2466 #define MC_O0 11
2467 #define MC_O1 12
2468 #define MC_O2 13
2469 #define MC_O3 14
2470 #define MC_O4 15
2471 #define MC_O5 16
2472 #define MC_O6 17
2473 #define MC_O7 18
2474 #define MC_NGREG 19
2476 typedef abi_ulong target_mc_greg_t;
2477 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2479 struct target_mc_fq {
2480 abi_ulong *mcfq_addr;
2481 uint32_t mcfq_insn;
2484 struct target_mc_fpu {
2485 union {
2486 uint32_t sregs[32];
2487 uint64_t dregs[32];
2488 //uint128_t qregs[16];
2489 } mcfpu_fregs;
2490 abi_ulong mcfpu_fsr;
2491 abi_ulong mcfpu_fprs;
2492 abi_ulong mcfpu_gsr;
2493 struct target_mc_fq *mcfpu_fq;
2494 unsigned char mcfpu_qcnt;
2495 unsigned char mcfpu_qentsz;
2496 unsigned char mcfpu_enab;
2498 typedef struct target_mc_fpu target_mc_fpu_t;
2500 typedef struct {
2501 target_mc_gregset_t mc_gregs;
2502 target_mc_greg_t mc_fp;
2503 target_mc_greg_t mc_i7;
2504 target_mc_fpu_t mc_fpregs;
2505 } target_mcontext_t;
2507 struct target_ucontext {
2508 struct target_ucontext *tuc_link;
2509 abi_ulong tuc_flags;
2510 target_sigset_t tuc_sigmask;
2511 target_mcontext_t tuc_mcontext;
2514 /* A V9 register window */
2515 struct target_reg_window {
2516 abi_ulong locals[8];
2517 abi_ulong ins[8];
2520 #define TARGET_STACK_BIAS 2047
2522 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2523 void sparc64_set_context(CPUSPARCState *env)
2525 abi_ulong ucp_addr;
2526 struct target_ucontext *ucp;
2527 target_mc_gregset_t *grp;
2528 abi_ulong pc, npc, tstate;
2529 abi_ulong fp, i7, w_addr;
2530 unsigned int i;
2532 ucp_addr = env->regwptr[UREG_I0];
2533 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2534 goto do_sigsegv;
2535 grp = &ucp->tuc_mcontext.mc_gregs;
2536 __get_user(pc, &((*grp)[MC_PC]));
2537 __get_user(npc, &((*grp)[MC_NPC]));
2538 if ((pc | npc) & 3)
2539 goto do_sigsegv;
2540 if (env->regwptr[UREG_I1]) {
2541 target_sigset_t target_set;
2542 sigset_t set;
2544 if (TARGET_NSIG_WORDS == 1) {
2545 __get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]);
2546 } else {
2547 abi_ulong *src, *dst;
2548 src = ucp->tuc_sigmask.sig;
2549 dst = target_set.sig;
2550 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2551 __get_user(*dst, src);
2554 target_to_host_sigset_internal(&set, &target_set);
2555 do_sigprocmask(SIG_SETMASK, &set, NULL);
2557 env->pc = pc;
2558 env->npc = npc;
2559 __get_user(env->y, &((*grp)[MC_Y]));
2560 __get_user(tstate, &((*grp)[MC_TSTATE]));
2561 env->asi = (tstate >> 24) & 0xff;
2562 cpu_put_ccr(env, tstate >> 32);
2563 cpu_put_cwp64(env, tstate & 0x1f);
2564 __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2565 __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2566 __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2567 __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2568 __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2569 __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2570 __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2571 __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2572 __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2573 __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2574 __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2575 __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2576 __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2577 __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2578 __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2580 __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2581 __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2583 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2584 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2585 abi_ulong) != 0)
2586 goto do_sigsegv;
2587 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2588 abi_ulong) != 0)
2589 goto do_sigsegv;
2590 /* FIXME this does not match how the kernel handles the FPU in
2591 * its sparc64_set_context implementation. In particular the FPU
2592 * is only restored if fenab is non-zero in:
2593 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2595 __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2597 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2598 for (i = 0; i < 64; i++, src++) {
2599 if (i & 1) {
2600 __get_user(env->fpr[i/2].l.lower, src);
2601 } else {
2602 __get_user(env->fpr[i/2].l.upper, src);
2606 __get_user(env->fsr,
2607 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2608 __get_user(env->gsr,
2609 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2610 unlock_user_struct(ucp, ucp_addr, 0);
2611 return;
2612 do_sigsegv:
2613 unlock_user_struct(ucp, ucp_addr, 0);
2614 force_sig(TARGET_SIGSEGV);
2617 void sparc64_get_context(CPUSPARCState *env)
2619 abi_ulong ucp_addr;
2620 struct target_ucontext *ucp;
2621 target_mc_gregset_t *grp;
2622 target_mcontext_t *mcp;
2623 abi_ulong fp, i7, w_addr;
2624 int err;
2625 unsigned int i;
2626 target_sigset_t target_set;
2627 sigset_t set;
2629 ucp_addr = env->regwptr[UREG_I0];
2630 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2631 goto do_sigsegv;
2633 mcp = &ucp->tuc_mcontext;
2634 grp = &mcp->mc_gregs;
2636 /* Skip over the trap instruction, first. */
2637 env->pc = env->npc;
2638 env->npc += 4;
2640 err = 0;
2642 do_sigprocmask(0, NULL, &set);
2643 host_to_target_sigset_internal(&target_set, &set);
2644 if (TARGET_NSIG_WORDS == 1) {
2645 __put_user(target_set.sig[0],
2646 (abi_ulong *)&ucp->tuc_sigmask);
2647 } else {
2648 abi_ulong *src, *dst;
2649 src = target_set.sig;
2650 dst = ucp->tuc_sigmask.sig;
2651 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2652 __put_user(*src, dst);
2654 if (err)
2655 goto do_sigsegv;
2658 /* XXX: tstate must be saved properly */
2659 // __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2660 __put_user(env->pc, &((*grp)[MC_PC]));
2661 __put_user(env->npc, &((*grp)[MC_NPC]));
2662 __put_user(env->y, &((*grp)[MC_Y]));
2663 __put_user(env->gregs[1], &((*grp)[MC_G1]));
2664 __put_user(env->gregs[2], &((*grp)[MC_G2]));
2665 __put_user(env->gregs[3], &((*grp)[MC_G3]));
2666 __put_user(env->gregs[4], &((*grp)[MC_G4]));
2667 __put_user(env->gregs[5], &((*grp)[MC_G5]));
2668 __put_user(env->gregs[6], &((*grp)[MC_G6]));
2669 __put_user(env->gregs[7], &((*grp)[MC_G7]));
2670 __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2671 __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2672 __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2673 __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2674 __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2675 __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2676 __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2677 __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2679 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2680 fp = i7 = 0;
2681 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2682 abi_ulong) != 0)
2683 goto do_sigsegv;
2684 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2685 abi_ulong) != 0)
2686 goto do_sigsegv;
2687 __put_user(fp, &(mcp->mc_fp));
2688 __put_user(i7, &(mcp->mc_i7));
2691 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2692 for (i = 0; i < 64; i++, dst++) {
2693 if (i & 1) {
2694 __put_user(env->fpr[i/2].l.lower, dst);
2695 } else {
2696 __put_user(env->fpr[i/2].l.upper, dst);
2700 __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2701 __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2702 __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2704 if (err)
2705 goto do_sigsegv;
2706 unlock_user_struct(ucp, ucp_addr, 1);
2707 return;
2708 do_sigsegv:
2709 unlock_user_struct(ucp, ucp_addr, 1);
2710 force_sig(TARGET_SIGSEGV);
2712 #endif
2713 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2715 # if defined(TARGET_ABI_MIPSO32)
2716 struct target_sigcontext {
2717 uint32_t sc_regmask; /* Unused */
2718 uint32_t sc_status;
2719 uint64_t sc_pc;
2720 uint64_t sc_regs[32];
2721 uint64_t sc_fpregs[32];
2722 uint32_t sc_ownedfp; /* Unused */
2723 uint32_t sc_fpc_csr;
2724 uint32_t sc_fpc_eir; /* Unused */
2725 uint32_t sc_used_math;
2726 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2727 uint32_t pad0;
2728 uint64_t sc_mdhi;
2729 uint64_t sc_mdlo;
2730 target_ulong sc_hi1; /* Was sc_cause */
2731 target_ulong sc_lo1; /* Was sc_badvaddr */
2732 target_ulong sc_hi2; /* Was sc_sigset[4] */
2733 target_ulong sc_lo2;
2734 target_ulong sc_hi3;
2735 target_ulong sc_lo3;
2737 # else /* N32 || N64 */
2738 struct target_sigcontext {
2739 uint64_t sc_regs[32];
2740 uint64_t sc_fpregs[32];
2741 uint64_t sc_mdhi;
2742 uint64_t sc_hi1;
2743 uint64_t sc_hi2;
2744 uint64_t sc_hi3;
2745 uint64_t sc_mdlo;
2746 uint64_t sc_lo1;
2747 uint64_t sc_lo2;
2748 uint64_t sc_lo3;
2749 uint64_t sc_pc;
2750 uint32_t sc_fpc_csr;
2751 uint32_t sc_used_math;
2752 uint32_t sc_dsp;
2753 uint32_t sc_reserved;
2755 # endif /* O32 */
2757 struct sigframe {
2758 uint32_t sf_ass[4]; /* argument save space for o32 */
2759 uint32_t sf_code[2]; /* signal trampoline */
2760 struct target_sigcontext sf_sc;
2761 target_sigset_t sf_mask;
2764 struct target_ucontext {
2765 target_ulong tuc_flags;
2766 target_ulong tuc_link;
2767 target_stack_t tuc_stack;
2768 target_ulong pad0;
2769 struct target_sigcontext tuc_mcontext;
2770 target_sigset_t tuc_sigmask;
2773 struct target_rt_sigframe {
2774 uint32_t rs_ass[4]; /* argument save space for o32 */
2775 uint32_t rs_code[2]; /* signal trampoline */
2776 struct target_siginfo rs_info;
2777 struct target_ucontext rs_uc;
2780 /* Install trampoline to jump back from signal handler */
2781 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2783 int err = 0;
2786 * Set up the return code ...
2788 * li v0, __NR__foo_sigreturn
2789 * syscall
2792 __put_user(0x24020000 + syscall, tramp + 0);
2793 __put_user(0x0000000c , tramp + 1);
2794 return err;
2797 static inline void setup_sigcontext(CPUMIPSState *regs,
2798 struct target_sigcontext *sc)
2800 int i;
2802 __put_user(exception_resume_pc(regs), &sc->sc_pc);
2803 regs->hflags &= ~MIPS_HFLAG_BMASK;
2805 __put_user(0, &sc->sc_regs[0]);
2806 for (i = 1; i < 32; ++i) {
2807 __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2810 __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2811 __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2813 /* Rather than checking for dsp existence, always copy. The storage
2814 would just be garbage otherwise. */
2815 __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
2816 __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
2817 __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
2818 __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
2819 __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
2820 __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
2822 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2823 __put_user(dsp, &sc->sc_dsp);
2826 __put_user(1, &sc->sc_used_math);
2828 for (i = 0; i < 32; ++i) {
2829 __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2833 static inline void
2834 restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2836 int i;
2838 __get_user(regs->CP0_EPC, &sc->sc_pc);
2840 __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2841 __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2843 for (i = 1; i < 32; ++i) {
2844 __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2847 __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
2848 __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
2849 __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
2850 __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
2851 __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
2852 __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
2854 uint32_t dsp;
2855 __get_user(dsp, &sc->sc_dsp);
2856 cpu_wrdsp(dsp, 0x3ff, regs);
2859 for (i = 0; i < 32; ++i) {
2860 __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2865 * Determine which stack to use..
2867 static inline abi_ulong
2868 get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2870 unsigned long sp;
2872 /* Default to using normal stack */
2873 sp = regs->active_tc.gpr[29];
2876 * FPU emulator may have its own trampoline active just
2877 * above the user stack, 16-bytes before the next lowest
2878 * 16 byte boundary. Try to avoid trashing it.
2880 sp -= 32;
2882 /* This is the X/Open sanctioned signal stack switching. */
2883 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2884 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2887 return (sp - frame_size) & ~7;
2890 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2892 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2893 env->hflags &= ~MIPS_HFLAG_M16;
2894 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2895 env->active_tc.PC &= ~(target_ulong) 1;
2899 # if defined(TARGET_ABI_MIPSO32)
2900 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2901 static void setup_frame(int sig, struct target_sigaction * ka,
2902 target_sigset_t *set, CPUMIPSState *regs)
2904 struct sigframe *frame;
2905 abi_ulong frame_addr;
2906 int i;
2908 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2909 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2910 goto give_sigsegv;
2912 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2914 setup_sigcontext(regs, &frame->sf_sc);
2916 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2917 __put_user(set->sig[i], &frame->sf_mask.sig[i]);
2921 * Arguments to signal handler:
2923 * a0 = signal number
2924 * a1 = 0 (should be cause)
2925 * a2 = pointer to struct sigcontext
2927 * $25 and PC point to the signal handler, $29 points to the
2928 * struct sigframe.
2930 regs->active_tc.gpr[ 4] = sig;
2931 regs->active_tc.gpr[ 5] = 0;
2932 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2933 regs->active_tc.gpr[29] = frame_addr;
2934 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2935 /* The original kernel code sets CP0_EPC to the handler
2936 * since it returns to userland using eret
2937 * we cannot do this here, and we must set PC directly */
2938 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2939 mips_set_hflags_isa_mode_from_pc(regs);
2940 unlock_user_struct(frame, frame_addr, 1);
2941 return;
2943 give_sigsegv:
2944 force_sig(TARGET_SIGSEGV/*, current*/);
2947 long do_sigreturn(CPUMIPSState *regs)
2949 struct sigframe *frame;
2950 abi_ulong frame_addr;
2951 sigset_t blocked;
2952 target_sigset_t target_set;
2953 int i;
2955 #if defined(DEBUG_SIGNAL)
2956 fprintf(stderr, "do_sigreturn\n");
2957 #endif
2958 frame_addr = regs->active_tc.gpr[29];
2959 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2960 goto badframe;
2962 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2963 __get_user(target_set.sig[i], &frame->sf_mask.sig[i]);
2966 target_to_host_sigset_internal(&blocked, &target_set);
2967 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
2969 restore_sigcontext(regs, &frame->sf_sc);
2971 #if 0
2973 * Don't let your children do this ...
2975 __asm__ __volatile__(
2976 "move\t$29, %0\n\t"
2977 "j\tsyscall_exit"
2978 :/* no outputs */
2979 :"r" (&regs));
2980 /* Unreached */
2981 #endif
2983 regs->active_tc.PC = regs->CP0_EPC;
2984 mips_set_hflags_isa_mode_from_pc(regs);
2985 /* I am not sure this is right, but it seems to work
2986 * maybe a problem with nested signals ? */
2987 regs->CP0_EPC = 0;
2988 return -TARGET_QEMU_ESIGRETURN;
2990 badframe:
2991 force_sig(TARGET_SIGSEGV/*, current*/);
2992 return 0;
2994 # endif /* O32 */
2996 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2997 target_siginfo_t *info,
2998 target_sigset_t *set, CPUMIPSState *env)
3000 struct target_rt_sigframe *frame;
3001 abi_ulong frame_addr;
3002 int i;
3004 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3005 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3006 goto give_sigsegv;
3008 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3010 copy_siginfo_to_user(&frame->rs_info, info);
3012 __put_user(0, &frame->rs_uc.tuc_flags);
3013 __put_user(0, &frame->rs_uc.tuc_link);
3014 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
3015 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
3016 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3017 &frame->rs_uc.tuc_stack.ss_flags);
3019 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3021 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3022 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3026 * Arguments to signal handler:
3028 * a0 = signal number
3029 * a1 = pointer to siginfo_t
3030 * a2 = pointer to struct ucontext
3032 * $25 and PC point to the signal handler, $29 points to the
3033 * struct sigframe.
3035 env->active_tc.gpr[ 4] = sig;
3036 env->active_tc.gpr[ 5] = frame_addr
3037 + offsetof(struct target_rt_sigframe, rs_info);
3038 env->active_tc.gpr[ 6] = frame_addr
3039 + offsetof(struct target_rt_sigframe, rs_uc);
3040 env->active_tc.gpr[29] = frame_addr;
3041 env->active_tc.gpr[31] = frame_addr
3042 + offsetof(struct target_rt_sigframe, rs_code);
3043 /* The original kernel code sets CP0_EPC to the handler
3044 * since it returns to userland using eret
3045 * we cannot do this here, and we must set PC directly */
3046 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3047 mips_set_hflags_isa_mode_from_pc(env);
3048 unlock_user_struct(frame, frame_addr, 1);
3049 return;
3051 give_sigsegv:
3052 unlock_user_struct(frame, frame_addr, 1);
3053 force_sig(TARGET_SIGSEGV/*, current*/);
3056 long do_rt_sigreturn(CPUMIPSState *env)
3058 struct target_rt_sigframe *frame;
3059 abi_ulong frame_addr;
3060 sigset_t blocked;
3062 #if defined(DEBUG_SIGNAL)
3063 fprintf(stderr, "do_rt_sigreturn\n");
3064 #endif
3065 frame_addr = env->active_tc.gpr[29];
3066 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3067 goto badframe;
3069 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3070 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3072 restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3074 if (do_sigaltstack(frame_addr +
3075 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3076 0, get_sp_from_cpustate(env)) == -EFAULT)
3077 goto badframe;
3079 env->active_tc.PC = env->CP0_EPC;
3080 mips_set_hflags_isa_mode_from_pc(env);
3081 /* I am not sure this is right, but it seems to work
3082 * maybe a problem with nested signals ? */
3083 env->CP0_EPC = 0;
3084 return -TARGET_QEMU_ESIGRETURN;
3086 badframe:
3087 force_sig(TARGET_SIGSEGV/*, current*/);
3088 return 0;
3091 #elif defined(TARGET_SH4)
3094 * code and data structures from linux kernel:
3095 * include/asm-sh/sigcontext.h
3096 * arch/sh/kernel/signal.c
3099 struct target_sigcontext {
3100 target_ulong oldmask;
3102 /* CPU registers */
3103 target_ulong sc_gregs[16];
3104 target_ulong sc_pc;
3105 target_ulong sc_pr;
3106 target_ulong sc_sr;
3107 target_ulong sc_gbr;
3108 target_ulong sc_mach;
3109 target_ulong sc_macl;
3111 /* FPU registers */
3112 target_ulong sc_fpregs[16];
3113 target_ulong sc_xfpregs[16];
3114 unsigned int sc_fpscr;
3115 unsigned int sc_fpul;
3116 unsigned int sc_ownedfp;
3119 struct target_sigframe
3121 struct target_sigcontext sc;
3122 target_ulong extramask[TARGET_NSIG_WORDS-1];
3123 uint16_t retcode[3];
3127 struct target_ucontext {
3128 target_ulong tuc_flags;
3129 struct target_ucontext *tuc_link;
3130 target_stack_t tuc_stack;
3131 struct target_sigcontext tuc_mcontext;
3132 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3135 struct target_rt_sigframe
3137 struct target_siginfo info;
3138 struct target_ucontext uc;
3139 uint16_t retcode[3];
3143 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3144 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3146 static abi_ulong get_sigframe(struct target_sigaction *ka,
3147 unsigned long sp, size_t frame_size)
3149 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
3150 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3153 return (sp - frame_size) & -8ul;
3156 static void setup_sigcontext(struct target_sigcontext *sc,
3157 CPUSH4State *regs, unsigned long mask)
3159 int i;
3161 #define COPY(x) __put_user(regs->x, &sc->sc_##x)
3162 COPY(gregs[0]); COPY(gregs[1]);
3163 COPY(gregs[2]); COPY(gregs[3]);
3164 COPY(gregs[4]); COPY(gregs[5]);
3165 COPY(gregs[6]); COPY(gregs[7]);
3166 COPY(gregs[8]); COPY(gregs[9]);
3167 COPY(gregs[10]); COPY(gregs[11]);
3168 COPY(gregs[12]); COPY(gregs[13]);
3169 COPY(gregs[14]); COPY(gregs[15]);
3170 COPY(gbr); COPY(mach);
3171 COPY(macl); COPY(pr);
3172 COPY(sr); COPY(pc);
3173 #undef COPY
3175 for (i=0; i<16; i++) {
3176 __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3178 __put_user(regs->fpscr, &sc->sc_fpscr);
3179 __put_user(regs->fpul, &sc->sc_fpul);
3181 /* non-iBCS2 extensions.. */
3182 __put_user(mask, &sc->oldmask);
3185 static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3186 target_ulong *r0_p)
3188 int i;
3190 #define COPY(x) __get_user(regs->x, &sc->sc_##x)
3191 COPY(gregs[1]);
3192 COPY(gregs[2]); COPY(gregs[3]);
3193 COPY(gregs[4]); COPY(gregs[5]);
3194 COPY(gregs[6]); COPY(gregs[7]);
3195 COPY(gregs[8]); COPY(gregs[9]);
3196 COPY(gregs[10]); COPY(gregs[11]);
3197 COPY(gregs[12]); COPY(gregs[13]);
3198 COPY(gregs[14]); COPY(gregs[15]);
3199 COPY(gbr); COPY(mach);
3200 COPY(macl); COPY(pr);
3201 COPY(sr); COPY(pc);
3202 #undef COPY
3204 for (i=0; i<16; i++) {
3205 __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3207 __get_user(regs->fpscr, &sc->sc_fpscr);
3208 __get_user(regs->fpul, &sc->sc_fpul);
3210 regs->tra = -1; /* disable syscall checks */
3211 __get_user(*r0_p, &sc->sc_gregs[0]);
3214 static void setup_frame(int sig, struct target_sigaction *ka,
3215 target_sigset_t *set, CPUSH4State *regs)
3217 struct target_sigframe *frame;
3218 abi_ulong frame_addr;
3219 int i;
3220 int err = 0;
3221 int signal;
3223 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3224 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3225 goto give_sigsegv;
3227 signal = current_exec_domain_sig(sig);
3229 setup_sigcontext(&frame->sc, regs, set->sig[0]);
3231 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3232 __put_user(set->sig[i + 1], &frame->extramask[i]);
3235 /* Set up to return from userspace. If provided, use a stub
3236 already in userspace. */
3237 if (ka->sa_flags & TARGET_SA_RESTORER) {
3238 regs->pr = (unsigned long) ka->sa_restorer;
3239 } else {
3240 /* Generate return code (system call to sigreturn) */
3241 __put_user(MOVW(2), &frame->retcode[0]);
3242 __put_user(TRAP_NOARG, &frame->retcode[1]);
3243 __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3244 regs->pr = (unsigned long) frame->retcode;
3247 if (err)
3248 goto give_sigsegv;
3250 /* Set up registers for signal handler */
3251 regs->gregs[15] = frame_addr;
3252 regs->gregs[4] = signal; /* Arg for signal handler */
3253 regs->gregs[5] = 0;
3254 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3255 regs->pc = (unsigned long) ka->_sa_handler;
3257 unlock_user_struct(frame, frame_addr, 1);
3258 return;
3260 give_sigsegv:
3261 unlock_user_struct(frame, frame_addr, 1);
3262 force_sig(TARGET_SIGSEGV);
3265 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3266 target_siginfo_t *info,
3267 target_sigset_t *set, CPUSH4State *regs)
3269 struct target_rt_sigframe *frame;
3270 abi_ulong frame_addr;
3271 int i;
3272 int err = 0;
3273 int signal;
3275 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3276 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3277 goto give_sigsegv;
3279 signal = current_exec_domain_sig(sig);
3281 copy_siginfo_to_user(&frame->info, info);
3283 /* Create the ucontext. */
3284 __put_user(0, &frame->uc.tuc_flags);
3285 __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3286 __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3287 &frame->uc.tuc_stack.ss_sp);
3288 __put_user(sas_ss_flags(regs->gregs[15]),
3289 &frame->uc.tuc_stack.ss_flags);
3290 __put_user(target_sigaltstack_used.ss_size,
3291 &frame->uc.tuc_stack.ss_size);
3292 setup_sigcontext(&frame->uc.tuc_mcontext,
3293 regs, set->sig[0]);
3294 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3295 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3298 /* Set up to return from userspace. If provided, use a stub
3299 already in userspace. */
3300 if (ka->sa_flags & TARGET_SA_RESTORER) {
3301 regs->pr = (unsigned long) ka->sa_restorer;
3302 } else {
3303 /* Generate return code (system call to sigreturn) */
3304 __put_user(MOVW(2), &frame->retcode[0]);
3305 __put_user(TRAP_NOARG, &frame->retcode[1]);
3306 __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3307 regs->pr = (unsigned long) frame->retcode;
3310 if (err)
3311 goto give_sigsegv;
3313 /* Set up registers for signal handler */
3314 regs->gregs[15] = frame_addr;
3315 regs->gregs[4] = signal; /* Arg for signal handler */
3316 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3317 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3318 regs->pc = (unsigned long) ka->_sa_handler;
3320 unlock_user_struct(frame, frame_addr, 1);
3321 return;
3323 give_sigsegv:
3324 unlock_user_struct(frame, frame_addr, 1);
3325 force_sig(TARGET_SIGSEGV);
3328 long do_sigreturn(CPUSH4State *regs)
3330 struct target_sigframe *frame;
3331 abi_ulong frame_addr;
3332 sigset_t blocked;
3333 target_sigset_t target_set;
3334 target_ulong r0;
3335 int i;
3336 int err = 0;
3338 #if defined(DEBUG_SIGNAL)
3339 fprintf(stderr, "do_sigreturn\n");
3340 #endif
3341 frame_addr = regs->gregs[15];
3342 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3343 goto badframe;
3345 __get_user(target_set.sig[0], &frame->sc.oldmask);
3346 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3347 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
3350 if (err)
3351 goto badframe;
3353 target_to_host_sigset_internal(&blocked, &target_set);
3354 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3356 restore_sigcontext(regs, &frame->sc, &r0);
3358 unlock_user_struct(frame, frame_addr, 0);
3359 return r0;
3361 badframe:
3362 unlock_user_struct(frame, frame_addr, 0);
3363 force_sig(TARGET_SIGSEGV);
3364 return 0;
3367 long do_rt_sigreturn(CPUSH4State *regs)
3369 struct target_rt_sigframe *frame;
3370 abi_ulong frame_addr;
3371 sigset_t blocked;
3372 target_ulong r0;
3374 #if defined(DEBUG_SIGNAL)
3375 fprintf(stderr, "do_rt_sigreturn\n");
3376 #endif
3377 frame_addr = regs->gregs[15];
3378 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3379 goto badframe;
3381 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3382 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3384 restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0);
3386 if (do_sigaltstack(frame_addr +
3387 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3388 0, get_sp_from_cpustate(regs)) == -EFAULT)
3389 goto badframe;
3391 unlock_user_struct(frame, frame_addr, 0);
3392 return r0;
3394 badframe:
3395 unlock_user_struct(frame, frame_addr, 0);
3396 force_sig(TARGET_SIGSEGV);
3397 return 0;
3399 #elif defined(TARGET_MICROBLAZE)
3401 struct target_sigcontext {
3402 struct target_pt_regs regs; /* needs to be first */
3403 uint32_t oldmask;
3406 struct target_stack_t {
3407 abi_ulong ss_sp;
3408 int ss_flags;
3409 unsigned int ss_size;
3412 struct target_ucontext {
3413 abi_ulong tuc_flags;
3414 abi_ulong tuc_link;
3415 struct target_stack_t tuc_stack;
3416 struct target_sigcontext tuc_mcontext;
3417 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3420 /* Signal frames. */
3421 struct target_signal_frame {
3422 struct target_ucontext uc;
3423 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3424 uint32_t tramp[2];
3427 struct rt_signal_frame {
3428 siginfo_t info;
3429 struct ucontext uc;
3430 uint32_t tramp[2];
3433 static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3435 __put_user(env->regs[0], &sc->regs.r0);
3436 __put_user(env->regs[1], &sc->regs.r1);
3437 __put_user(env->regs[2], &sc->regs.r2);
3438 __put_user(env->regs[3], &sc->regs.r3);
3439 __put_user(env->regs[4], &sc->regs.r4);
3440 __put_user(env->regs[5], &sc->regs.r5);
3441 __put_user(env->regs[6], &sc->regs.r6);
3442 __put_user(env->regs[7], &sc->regs.r7);
3443 __put_user(env->regs[8], &sc->regs.r8);
3444 __put_user(env->regs[9], &sc->regs.r9);
3445 __put_user(env->regs[10], &sc->regs.r10);
3446 __put_user(env->regs[11], &sc->regs.r11);
3447 __put_user(env->regs[12], &sc->regs.r12);
3448 __put_user(env->regs[13], &sc->regs.r13);
3449 __put_user(env->regs[14], &sc->regs.r14);
3450 __put_user(env->regs[15], &sc->regs.r15);
3451 __put_user(env->regs[16], &sc->regs.r16);
3452 __put_user(env->regs[17], &sc->regs.r17);
3453 __put_user(env->regs[18], &sc->regs.r18);
3454 __put_user(env->regs[19], &sc->regs.r19);
3455 __put_user(env->regs[20], &sc->regs.r20);
3456 __put_user(env->regs[21], &sc->regs.r21);
3457 __put_user(env->regs[22], &sc->regs.r22);
3458 __put_user(env->regs[23], &sc->regs.r23);
3459 __put_user(env->regs[24], &sc->regs.r24);
3460 __put_user(env->regs[25], &sc->regs.r25);
3461 __put_user(env->regs[26], &sc->regs.r26);
3462 __put_user(env->regs[27], &sc->regs.r27);
3463 __put_user(env->regs[28], &sc->regs.r28);
3464 __put_user(env->regs[29], &sc->regs.r29);
3465 __put_user(env->regs[30], &sc->regs.r30);
3466 __put_user(env->regs[31], &sc->regs.r31);
3467 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3470 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3472 __get_user(env->regs[0], &sc->regs.r0);
3473 __get_user(env->regs[1], &sc->regs.r1);
3474 __get_user(env->regs[2], &sc->regs.r2);
3475 __get_user(env->regs[3], &sc->regs.r3);
3476 __get_user(env->regs[4], &sc->regs.r4);
3477 __get_user(env->regs[5], &sc->regs.r5);
3478 __get_user(env->regs[6], &sc->regs.r6);
3479 __get_user(env->regs[7], &sc->regs.r7);
3480 __get_user(env->regs[8], &sc->regs.r8);
3481 __get_user(env->regs[9], &sc->regs.r9);
3482 __get_user(env->regs[10], &sc->regs.r10);
3483 __get_user(env->regs[11], &sc->regs.r11);
3484 __get_user(env->regs[12], &sc->regs.r12);
3485 __get_user(env->regs[13], &sc->regs.r13);
3486 __get_user(env->regs[14], &sc->regs.r14);
3487 __get_user(env->regs[15], &sc->regs.r15);
3488 __get_user(env->regs[16], &sc->regs.r16);
3489 __get_user(env->regs[17], &sc->regs.r17);
3490 __get_user(env->regs[18], &sc->regs.r18);
3491 __get_user(env->regs[19], &sc->regs.r19);
3492 __get_user(env->regs[20], &sc->regs.r20);
3493 __get_user(env->regs[21], &sc->regs.r21);
3494 __get_user(env->regs[22], &sc->regs.r22);
3495 __get_user(env->regs[23], &sc->regs.r23);
3496 __get_user(env->regs[24], &sc->regs.r24);
3497 __get_user(env->regs[25], &sc->regs.r25);
3498 __get_user(env->regs[26], &sc->regs.r26);
3499 __get_user(env->regs[27], &sc->regs.r27);
3500 __get_user(env->regs[28], &sc->regs.r28);
3501 __get_user(env->regs[29], &sc->regs.r29);
3502 __get_user(env->regs[30], &sc->regs.r30);
3503 __get_user(env->regs[31], &sc->regs.r31);
3504 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3507 static abi_ulong get_sigframe(struct target_sigaction *ka,
3508 CPUMBState *env, int frame_size)
3510 abi_ulong sp = env->regs[1];
3512 if ((ka->sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
3513 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3515 return ((sp - frame_size) & -8UL);
3518 static void setup_frame(int sig, struct target_sigaction *ka,
3519 target_sigset_t *set, CPUMBState *env)
3521 struct target_signal_frame *frame;
3522 abi_ulong frame_addr;
3523 int i;
3525 frame_addr = get_sigframe(ka, env, sizeof *frame);
3526 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3527 goto badframe;
3529 /* Save the mask. */
3530 __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3532 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3533 __put_user(set->sig[i], &frame->extramask[i - 1]);
3536 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3538 /* Set up to return from userspace. If provided, use a stub
3539 already in userspace. */
3540 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3541 if (ka->sa_flags & TARGET_SA_RESTORER) {
3542 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3543 } else {
3544 uint32_t t;
3545 /* Note, these encodings are _big endian_! */
3546 /* addi r12, r0, __NR_sigreturn */
3547 t = 0x31800000UL | TARGET_NR_sigreturn;
3548 __put_user(t, frame->tramp + 0);
3549 /* brki r14, 0x8 */
3550 t = 0xb9cc0008UL;
3551 __put_user(t, frame->tramp + 1);
3553 /* Return from sighandler will jump to the tramp.
3554 Negative 8 offset because return is rtsd r15, 8 */
3555 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3558 /* Set up registers for signal handler */
3559 env->regs[1] = frame_addr;
3560 /* Signal handler args: */
3561 env->regs[5] = sig; /* Arg 0: signum */
3562 env->regs[6] = 0;
3563 /* arg 1: sigcontext */
3564 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3566 /* Offset of 4 to handle microblaze rtid r14, 0 */
3567 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3569 unlock_user_struct(frame, frame_addr, 1);
3570 return;
3571 badframe:
3572 force_sig(TARGET_SIGSEGV);
3575 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3576 target_siginfo_t *info,
3577 target_sigset_t *set, CPUMBState *env)
3579 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3582 long do_sigreturn(CPUMBState *env)
3584 struct target_signal_frame *frame;
3585 abi_ulong frame_addr;
3586 target_sigset_t target_set;
3587 sigset_t set;
3588 int i;
3590 frame_addr = env->regs[R_SP];
3591 /* Make sure the guest isn't playing games. */
3592 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3593 goto badframe;
3595 /* Restore blocked signals */
3596 __get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask);
3597 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3598 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
3600 target_to_host_sigset_internal(&set, &target_set);
3601 do_sigprocmask(SIG_SETMASK, &set, NULL);
3603 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3604 /* We got here through a sigreturn syscall, our path back is via an
3605 rtb insn so setup r14 for that. */
3606 env->regs[14] = env->sregs[SR_PC];
3608 unlock_user_struct(frame, frame_addr, 0);
3609 return env->regs[10];
3610 badframe:
3611 force_sig(TARGET_SIGSEGV);
3614 long do_rt_sigreturn(CPUMBState *env)
3616 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3617 return -TARGET_ENOSYS;
3620 #elif defined(TARGET_CRIS)
3622 struct target_sigcontext {
3623 struct target_pt_regs regs; /* needs to be first */
3624 uint32_t oldmask;
3625 uint32_t usp; /* usp before stacking this gunk on it */
3628 /* Signal frames. */
3629 struct target_signal_frame {
3630 struct target_sigcontext sc;
3631 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3632 uint16_t retcode[4]; /* Trampoline code. */
3635 struct rt_signal_frame {
3636 siginfo_t *pinfo;
3637 void *puc;
3638 siginfo_t info;
3639 struct ucontext uc;
3640 uint16_t retcode[4]; /* Trampoline code. */
3643 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3645 __put_user(env->regs[0], &sc->regs.r0);
3646 __put_user(env->regs[1], &sc->regs.r1);
3647 __put_user(env->regs[2], &sc->regs.r2);
3648 __put_user(env->regs[3], &sc->regs.r3);
3649 __put_user(env->regs[4], &sc->regs.r4);
3650 __put_user(env->regs[5], &sc->regs.r5);
3651 __put_user(env->regs[6], &sc->regs.r6);
3652 __put_user(env->regs[7], &sc->regs.r7);
3653 __put_user(env->regs[8], &sc->regs.r8);
3654 __put_user(env->regs[9], &sc->regs.r9);
3655 __put_user(env->regs[10], &sc->regs.r10);
3656 __put_user(env->regs[11], &sc->regs.r11);
3657 __put_user(env->regs[12], &sc->regs.r12);
3658 __put_user(env->regs[13], &sc->regs.r13);
3659 __put_user(env->regs[14], &sc->usp);
3660 __put_user(env->regs[15], &sc->regs.acr);
3661 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3662 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3663 __put_user(env->pc, &sc->regs.erp);
3666 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3668 __get_user(env->regs[0], &sc->regs.r0);
3669 __get_user(env->regs[1], &sc->regs.r1);
3670 __get_user(env->regs[2], &sc->regs.r2);
3671 __get_user(env->regs[3], &sc->regs.r3);
3672 __get_user(env->regs[4], &sc->regs.r4);
3673 __get_user(env->regs[5], &sc->regs.r5);
3674 __get_user(env->regs[6], &sc->regs.r6);
3675 __get_user(env->regs[7], &sc->regs.r7);
3676 __get_user(env->regs[8], &sc->regs.r8);
3677 __get_user(env->regs[9], &sc->regs.r9);
3678 __get_user(env->regs[10], &sc->regs.r10);
3679 __get_user(env->regs[11], &sc->regs.r11);
3680 __get_user(env->regs[12], &sc->regs.r12);
3681 __get_user(env->regs[13], &sc->regs.r13);
3682 __get_user(env->regs[14], &sc->usp);
3683 __get_user(env->regs[15], &sc->regs.acr);
3684 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3685 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3686 __get_user(env->pc, &sc->regs.erp);
3689 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3691 abi_ulong sp;
3692 /* Align the stack downwards to 4. */
3693 sp = (env->regs[R_SP] & ~3);
3694 return sp - framesize;
3697 static void setup_frame(int sig, struct target_sigaction *ka,
3698 target_sigset_t *set, CPUCRISState *env)
3700 struct target_signal_frame *frame;
3701 abi_ulong frame_addr;
3702 int i;
3704 frame_addr = get_sigframe(env, sizeof *frame);
3705 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3706 goto badframe;
3709 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3710 * use this trampoline anymore but it sets it up for GDB.
3711 * In QEMU, using the trampoline simplifies things a bit so we use it.
3713 * This is movu.w __NR_sigreturn, r9; break 13;
3715 __put_user(0x9c5f, frame->retcode+0);
3716 __put_user(TARGET_NR_sigreturn,
3717 frame->retcode + 1);
3718 __put_user(0xe93d, frame->retcode + 2);
3720 /* Save the mask. */
3721 __put_user(set->sig[0], &frame->sc.oldmask);
3723 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3724 __put_user(set->sig[i], &frame->extramask[i - 1]);
3727 setup_sigcontext(&frame->sc, env);
3729 /* Move the stack and setup the arguments for the handler. */
3730 env->regs[R_SP] = frame_addr;
3731 env->regs[10] = sig;
3732 env->pc = (unsigned long) ka->_sa_handler;
3733 /* Link SRP so the guest returns through the trampoline. */
3734 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3736 unlock_user_struct(frame, frame_addr, 1);
3737 return;
3738 badframe:
3739 force_sig(TARGET_SIGSEGV);
3742 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3743 target_siginfo_t *info,
3744 target_sigset_t *set, CPUCRISState *env)
3746 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3749 long do_sigreturn(CPUCRISState *env)
3751 struct target_signal_frame *frame;
3752 abi_ulong frame_addr;
3753 target_sigset_t target_set;
3754 sigset_t set;
3755 int i;
3757 frame_addr = env->regs[R_SP];
3758 /* Make sure the guest isn't playing games. */
3759 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3760 goto badframe;
3762 /* Restore blocked signals */
3763 __get_user(target_set.sig[0], &frame->sc.oldmask);
3764 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3765 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
3767 target_to_host_sigset_internal(&set, &target_set);
3768 do_sigprocmask(SIG_SETMASK, &set, NULL);
3770 restore_sigcontext(&frame->sc, env);
3771 unlock_user_struct(frame, frame_addr, 0);
3772 return env->regs[10];
3773 badframe:
3774 force_sig(TARGET_SIGSEGV);
3777 long do_rt_sigreturn(CPUCRISState *env)
3779 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3780 return -TARGET_ENOSYS;
3783 #elif defined(TARGET_OPENRISC)
3785 struct target_sigcontext {
3786 struct target_pt_regs regs;
3787 abi_ulong oldmask;
3788 abi_ulong usp;
3791 struct target_ucontext {
3792 abi_ulong tuc_flags;
3793 abi_ulong tuc_link;
3794 target_stack_t tuc_stack;
3795 struct target_sigcontext tuc_mcontext;
3796 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3799 struct target_rt_sigframe {
3800 abi_ulong pinfo;
3801 uint64_t puc;
3802 struct target_siginfo info;
3803 struct target_sigcontext sc;
3804 struct target_ucontext uc;
3805 unsigned char retcode[16]; /* trampoline code */
3808 /* This is the asm-generic/ucontext.h version */
3809 #if 0
3810 static int restore_sigcontext(CPUOpenRISCState *regs,
3811 struct target_sigcontext *sc)
3813 unsigned int err = 0;
3814 unsigned long old_usp;
3816 /* Alwys make any pending restarted system call return -EINTR */
3817 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3819 /* restore the regs from &sc->regs (same as sc, since regs is first)
3820 * (sc is already checked for VERIFY_READ since the sigframe was
3821 * checked in sys_sigreturn previously)
3824 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3825 goto badframe;
3828 /* make sure the U-flag is set so user-mode cannot fool us */
3830 regs->sr &= ~SR_SM;
3832 /* restore the old USP as it was before we stacked the sc etc.
3833 * (we cannot just pop the sigcontext since we aligned the sp and
3834 * stuff after pushing it)
3837 __get_user(old_usp, &sc->usp);
3838 phx_signal("old_usp 0x%lx", old_usp);
3840 __PHX__ REALLY /* ??? */
3841 wrusp(old_usp);
3842 regs->gpr[1] = old_usp;
3844 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3845 * after this completes, but we don't use that mechanism. maybe we can
3846 * use it now ?
3849 return err;
3851 badframe:
3852 return 1;
3854 #endif
3856 /* Set up a signal frame. */
3858 static void setup_sigcontext(struct target_sigcontext *sc,
3859 CPUOpenRISCState *regs,
3860 unsigned long mask)
3862 unsigned long usp = regs->gpr[1];
3864 /* copy the regs. they are first in sc so we can use sc directly */
3866 /*copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3868 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3869 the signal handler. The frametype will be restored to its previous
3870 value in restore_sigcontext. */
3871 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3873 /* then some other stuff */
3874 __put_user(mask, &sc->oldmask);
3875 __put_user(usp, &sc->usp);
3878 static inline unsigned long align_sigframe(unsigned long sp)
3880 unsigned long i;
3881 i = sp & ~3UL;
3882 return i;
3885 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3886 CPUOpenRISCState *regs,
3887 size_t frame_size)
3889 unsigned long sp = regs->gpr[1];
3890 int onsigstack = on_sig_stack(sp);
3892 /* redzone */
3893 /* This is the X/Open sanctioned signal stack switching. */
3894 if ((ka->sa_flags & SA_ONSTACK) != 0 && !onsigstack) {
3895 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3898 sp = align_sigframe(sp - frame_size);
3901 * If we are on the alternate signal stack and would overflow it, don't.
3902 * Return an always-bogus address instead so we will die with SIGSEGV.
3905 if (onsigstack && !likely(on_sig_stack(sp))) {
3906 return -1L;
3909 return sp;
3912 static void setup_frame(int sig, struct target_sigaction *ka,
3913 target_sigset_t *set, CPUOpenRISCState *env)
3915 qemu_log("Not implement.\n");
3918 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3919 target_siginfo_t *info,
3920 target_sigset_t *set, CPUOpenRISCState *env)
3922 int err = 0;
3923 abi_ulong frame_addr;
3924 unsigned long return_ip;
3925 struct target_rt_sigframe *frame;
3926 abi_ulong info_addr, uc_addr;
3928 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3929 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3930 goto give_sigsegv;
3933 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
3934 __put_user(info_addr, &frame->pinfo);
3935 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
3936 __put_user(uc_addr, &frame->puc);
3938 if (ka->sa_flags & SA_SIGINFO) {
3939 copy_siginfo_to_user(&frame->info, info);
3942 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3943 __put_user(0, &frame->uc.tuc_flags);
3944 __put_user(0, &frame->uc.tuc_link);
3945 __put_user(target_sigaltstack_used.ss_sp,
3946 &frame->uc.tuc_stack.ss_sp);
3947 __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
3948 __put_user(target_sigaltstack_used.ss_size,
3949 &frame->uc.tuc_stack.ss_size);
3950 setup_sigcontext(&frame->sc, env, set->sig[0]);
3952 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3954 /* trampoline - the desired return ip is the retcode itself */
3955 return_ip = (unsigned long)&frame->retcode;
3956 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
3957 __put_user(0xa960, (short *)(frame->retcode + 0));
3958 __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
3959 __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
3960 __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
3962 if (err) {
3963 goto give_sigsegv;
3966 /* TODO what is the current->exec_domain stuff and invmap ? */
3968 /* Set up registers for signal handler */
3969 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
3970 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
3971 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
3972 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
3973 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
3975 /* actually move the usp to reflect the stacked frame */
3976 env->gpr[1] = (unsigned long)frame;
3978 return;
3980 give_sigsegv:
3981 unlock_user_struct(frame, frame_addr, 1);
3982 if (sig == TARGET_SIGSEGV) {
3983 ka->_sa_handler = TARGET_SIG_DFL;
3985 force_sig(TARGET_SIGSEGV);
3988 long do_sigreturn(CPUOpenRISCState *env)
3991 qemu_log("do_sigreturn: not implemented\n");
3992 return -TARGET_ENOSYS;
3995 long do_rt_sigreturn(CPUOpenRISCState *env)
3997 qemu_log("do_rt_sigreturn: not implemented\n");
3998 return -TARGET_ENOSYS;
4000 /* TARGET_OPENRISC */
4002 #elif defined(TARGET_S390X)
4004 #define __NUM_GPRS 16
4005 #define __NUM_FPRS 16
4006 #define __NUM_ACRS 16
4008 #define S390_SYSCALL_SIZE 2
4009 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
4011 #define _SIGCONTEXT_NSIG 64
4012 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4013 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4014 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4015 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4016 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4018 typedef struct {
4019 target_psw_t psw;
4020 target_ulong gprs[__NUM_GPRS];
4021 unsigned int acrs[__NUM_ACRS];
4022 } target_s390_regs_common;
4024 typedef struct {
4025 unsigned int fpc;
4026 double fprs[__NUM_FPRS];
4027 } target_s390_fp_regs;
4029 typedef struct {
4030 target_s390_regs_common regs;
4031 target_s390_fp_regs fpregs;
4032 } target_sigregs;
4034 struct target_sigcontext {
4035 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4036 target_sigregs *sregs;
4039 typedef struct {
4040 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4041 struct target_sigcontext sc;
4042 target_sigregs sregs;
4043 int signo;
4044 uint8_t retcode[S390_SYSCALL_SIZE];
4045 } sigframe;
4047 struct target_ucontext {
4048 target_ulong tuc_flags;
4049 struct target_ucontext *tuc_link;
4050 target_stack_t tuc_stack;
4051 target_sigregs tuc_mcontext;
4052 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4055 typedef struct {
4056 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4057 uint8_t retcode[S390_SYSCALL_SIZE];
4058 struct target_siginfo info;
4059 struct target_ucontext uc;
4060 } rt_sigframe;
4062 static inline abi_ulong
4063 get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4065 abi_ulong sp;
4067 /* Default to using normal stack */
4068 sp = env->regs[15];
4070 /* This is the X/Open sanctioned signal stack switching. */
4071 if (ka->sa_flags & TARGET_SA_ONSTACK) {
4072 if (!sas_ss_flags(sp)) {
4073 sp = target_sigaltstack_used.ss_sp +
4074 target_sigaltstack_used.ss_size;
4078 /* This is the legacy signal stack switching. */
4079 else if (/* FIXME !user_mode(regs) */ 0 &&
4080 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4081 ka->sa_restorer) {
4082 sp = (abi_ulong) ka->sa_restorer;
4085 return (sp - frame_size) & -8ul;
4088 static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4090 int i;
4091 //save_access_regs(current->thread.acrs); FIXME
4093 /* Copy a 'clean' PSW mask to the user to avoid leaking
4094 information about whether PER is currently on. */
4095 __put_user(env->psw.mask, &sregs->regs.psw.mask);
4096 __put_user(env->psw.addr, &sregs->regs.psw.addr);
4097 for (i = 0; i < 16; i++) {
4098 __put_user(env->regs[i], &sregs->regs.gprs[i]);
4100 for (i = 0; i < 16; i++) {
4101 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
4104 * We have to store the fp registers to current->thread.fp_regs
4105 * to merge them with the emulated registers.
4107 //save_fp_regs(&current->thread.fp_regs); FIXME
4108 for (i = 0; i < 16; i++) {
4109 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4113 static void setup_frame(int sig, struct target_sigaction *ka,
4114 target_sigset_t *set, CPUS390XState *env)
4116 sigframe *frame;
4117 abi_ulong frame_addr;
4119 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4120 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4121 (unsigned long long)frame_addr);
4122 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4123 goto give_sigsegv;
4126 qemu_log("%s: 1\n", __FUNCTION__);
4127 __put_user(set->sig[0], &frame->sc.oldmask[0]);
4129 save_sigregs(env, &frame->sregs);
4131 __put_user((abi_ulong)(unsigned long)&frame->sregs,
4132 (abi_ulong *)&frame->sc.sregs);
4134 /* Set up to return from userspace. If provided, use a stub
4135 already in userspace. */
4136 if (ka->sa_flags & TARGET_SA_RESTORER) {
4137 env->regs[14] = (unsigned long)
4138 ka->sa_restorer | PSW_ADDR_AMODE;
4139 } else {
4140 env->regs[14] = (unsigned long)
4141 frame->retcode | PSW_ADDR_AMODE;
4142 __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
4143 (uint16_t *)(frame->retcode));
4146 /* Set up backchain. */
4147 __put_user(env->regs[15], (abi_ulong *) frame);
4149 /* Set up registers for signal handler */
4150 env->regs[15] = frame_addr;
4151 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4153 env->regs[2] = sig; //map_signal(sig);
4154 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
4156 /* We forgot to include these in the sigcontext.
4157 To avoid breaking binary compatibility, they are passed as args. */
4158 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4159 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4161 /* Place signal number on stack to allow backtrace from handler. */
4162 __put_user(env->regs[2], (int *) &frame->signo);
4163 unlock_user_struct(frame, frame_addr, 1);
4164 return;
4166 give_sigsegv:
4167 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4168 force_sig(TARGET_SIGSEGV);
4171 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4172 target_siginfo_t *info,
4173 target_sigset_t *set, CPUS390XState *env)
4175 int i;
4176 rt_sigframe *frame;
4177 abi_ulong frame_addr;
4179 frame_addr = get_sigframe(ka, env, sizeof *frame);
4180 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4181 (unsigned long long)frame_addr);
4182 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4183 goto give_sigsegv;
4186 qemu_log("%s: 1\n", __FUNCTION__);
4187 copy_siginfo_to_user(&frame->info, info);
4189 /* Create the ucontext. */
4190 __put_user(0, &frame->uc.tuc_flags);
4191 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
4192 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
4193 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
4194 &frame->uc.tuc_stack.ss_flags);
4195 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
4196 save_sigregs(env, &frame->uc.tuc_mcontext);
4197 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
4198 __put_user((abi_ulong)set->sig[i],
4199 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
4202 /* Set up to return from userspace. If provided, use a stub
4203 already in userspace. */
4204 if (ka->sa_flags & TARGET_SA_RESTORER) {
4205 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4206 } else {
4207 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4208 __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
4209 (uint16_t *)(frame->retcode));
4212 /* Set up backchain. */
4213 __put_user(env->regs[15], (abi_ulong *) frame);
4215 /* Set up registers for signal handler */
4216 env->regs[15] = frame_addr;
4217 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4219 env->regs[2] = sig; //map_signal(sig);
4220 env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
4221 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
4222 return;
4224 give_sigsegv:
4225 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4226 force_sig(TARGET_SIGSEGV);
4229 static int
4230 restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4232 int err = 0;
4233 int i;
4235 for (i = 0; i < 16; i++) {
4236 __get_user(env->regs[i], &sc->regs.gprs[i]);
4239 __get_user(env->psw.mask, &sc->regs.psw.mask);
4240 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4241 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4242 (unsigned long long)env->psw.addr);
4243 __get_user(env->psw.addr, &sc->regs.psw.addr);
4244 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4246 for (i = 0; i < 16; i++) {
4247 __get_user(env->aregs[i], &sc->regs.acrs[i]);
4249 for (i = 0; i < 16; i++) {
4250 __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4253 return err;
4256 long do_sigreturn(CPUS390XState *env)
4258 sigframe *frame;
4259 abi_ulong frame_addr = env->regs[15];
4260 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4261 (unsigned long long)frame_addr);
4262 target_sigset_t target_set;
4263 sigset_t set;
4265 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4266 goto badframe;
4268 __get_user(target_set.sig[0], &frame->sc.oldmask[0]);
4270 target_to_host_sigset_internal(&set, &target_set);
4271 do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4273 if (restore_sigregs(env, &frame->sregs)) {
4274 goto badframe;
4277 unlock_user_struct(frame, frame_addr, 0);
4278 return env->regs[2];
4280 badframe:
4281 force_sig(TARGET_SIGSEGV);
4282 return 0;
4285 long do_rt_sigreturn(CPUS390XState *env)
4287 rt_sigframe *frame;
4288 abi_ulong frame_addr = env->regs[15];
4289 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4290 (unsigned long long)frame_addr);
4291 sigset_t set;
4293 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4294 goto badframe;
4296 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4298 do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4300 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4301 goto badframe;
4304 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4305 get_sp_from_cpustate(env)) == -EFAULT) {
4306 goto badframe;
4308 unlock_user_struct(frame, frame_addr, 0);
4309 return env->regs[2];
4311 badframe:
4312 unlock_user_struct(frame, frame_addr, 0);
4313 force_sig(TARGET_SIGSEGV);
4314 return 0;
4317 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
4319 /* FIXME: Many of the structures are defined for both PPC and PPC64, but
4320 the signal handling is different enough that we haven't implemented
4321 support for PPC64 yet. Hence the restriction above.
4323 There are various #if'd blocks for code for TARGET_PPC64. These
4324 blocks should go away so that we can successfully run 32-bit and
4325 64-bit binaries on a QEMU configured for PPC64. */
4327 /* Size of dummy stack frame allocated when calling signal handler.
4328 See arch/powerpc/include/asm/ptrace.h. */
4329 #if defined(TARGET_PPC64)
4330 #define SIGNAL_FRAMESIZE 128
4331 #else
4332 #define SIGNAL_FRAMESIZE 64
4333 #endif
4335 /* See arch/powerpc/include/asm/sigcontext.h. */
4336 struct target_sigcontext {
4337 target_ulong _unused[4];
4338 int32_t signal;
4339 #if defined(TARGET_PPC64)
4340 int32_t pad0;
4341 #endif
4342 target_ulong handler;
4343 target_ulong oldmask;
4344 target_ulong regs; /* struct pt_regs __user * */
4345 /* TODO: PPC64 includes extra bits here. */
4348 /* Indices for target_mcontext.mc_gregs, below.
4349 See arch/powerpc/include/asm/ptrace.h for details. */
4350 enum {
4351 TARGET_PT_R0 = 0,
4352 TARGET_PT_R1 = 1,
4353 TARGET_PT_R2 = 2,
4354 TARGET_PT_R3 = 3,
4355 TARGET_PT_R4 = 4,
4356 TARGET_PT_R5 = 5,
4357 TARGET_PT_R6 = 6,
4358 TARGET_PT_R7 = 7,
4359 TARGET_PT_R8 = 8,
4360 TARGET_PT_R9 = 9,
4361 TARGET_PT_R10 = 10,
4362 TARGET_PT_R11 = 11,
4363 TARGET_PT_R12 = 12,
4364 TARGET_PT_R13 = 13,
4365 TARGET_PT_R14 = 14,
4366 TARGET_PT_R15 = 15,
4367 TARGET_PT_R16 = 16,
4368 TARGET_PT_R17 = 17,
4369 TARGET_PT_R18 = 18,
4370 TARGET_PT_R19 = 19,
4371 TARGET_PT_R20 = 20,
4372 TARGET_PT_R21 = 21,
4373 TARGET_PT_R22 = 22,
4374 TARGET_PT_R23 = 23,
4375 TARGET_PT_R24 = 24,
4376 TARGET_PT_R25 = 25,
4377 TARGET_PT_R26 = 26,
4378 TARGET_PT_R27 = 27,
4379 TARGET_PT_R28 = 28,
4380 TARGET_PT_R29 = 29,
4381 TARGET_PT_R30 = 30,
4382 TARGET_PT_R31 = 31,
4383 TARGET_PT_NIP = 32,
4384 TARGET_PT_MSR = 33,
4385 TARGET_PT_ORIG_R3 = 34,
4386 TARGET_PT_CTR = 35,
4387 TARGET_PT_LNK = 36,
4388 TARGET_PT_XER = 37,
4389 TARGET_PT_CCR = 38,
4390 /* Yes, there are two registers with #39. One is 64-bit only. */
4391 TARGET_PT_MQ = 39,
4392 TARGET_PT_SOFTE = 39,
4393 TARGET_PT_TRAP = 40,
4394 TARGET_PT_DAR = 41,
4395 TARGET_PT_DSISR = 42,
4396 TARGET_PT_RESULT = 43,
4397 TARGET_PT_REGS_COUNT = 44
4400 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4401 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4402 struct target_mcontext {
4403 target_ulong mc_gregs[48];
4404 /* Includes fpscr. */
4405 uint64_t mc_fregs[33];
4406 target_ulong mc_pad[2];
4407 /* We need to handle Altivec and SPE at the same time, which no
4408 kernel needs to do. Fortunately, the kernel defines this bit to
4409 be Altivec-register-large all the time, rather than trying to
4410 twiddle it based on the specific platform. */
4411 union {
4412 /* SPE vector registers. One extra for SPEFSCR. */
4413 uint32_t spe[33];
4414 /* Altivec vector registers. The packing of VSCR and VRSAVE
4415 varies depending on whether we're PPC64 or not: PPC64 splits
4416 them apart; PPC32 stuffs them together. */
4417 #if defined(TARGET_PPC64)
4418 #define QEMU_NVRREG 34
4419 #else
4420 #define QEMU_NVRREG 33
4421 #endif
4422 ppc_avr_t altivec[QEMU_NVRREG];
4423 #undef QEMU_NVRREG
4424 } mc_vregs __attribute__((__aligned__(16)));
4427 struct target_ucontext {
4428 target_ulong tuc_flags;
4429 target_ulong tuc_link; /* struct ucontext __user * */
4430 struct target_sigaltstack tuc_stack;
4431 #if !defined(TARGET_PPC64)
4432 int32_t tuc_pad[7];
4433 target_ulong tuc_regs; /* struct mcontext __user *
4434 points to uc_mcontext field */
4435 #endif
4436 target_sigset_t tuc_sigmask;
4437 #if defined(TARGET_PPC64)
4438 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4439 struct target_sigcontext tuc_mcontext;
4440 #else
4441 int32_t tuc_maskext[30];
4442 int32_t tuc_pad2[3];
4443 struct target_mcontext tuc_mcontext;
4444 #endif
4447 /* See arch/powerpc/kernel/signal_32.c. */
4448 struct target_sigframe {
4449 struct target_sigcontext sctx;
4450 struct target_mcontext mctx;
4451 int32_t abigap[56];
4454 struct target_rt_sigframe {
4455 struct target_siginfo info;
4456 struct target_ucontext uc;
4457 int32_t abigap[56];
4460 /* We use the mc_pad field for the signal return trampoline. */
4461 #define tramp mc_pad
4463 /* See arch/powerpc/kernel/signal.c. */
4464 static target_ulong get_sigframe(struct target_sigaction *ka,
4465 CPUPPCState *env,
4466 int frame_size)
4468 target_ulong oldsp, newsp;
4470 oldsp = env->gpr[1];
4472 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4473 (sas_ss_flags(oldsp) == 0)) {
4474 oldsp = (target_sigaltstack_used.ss_sp
4475 + target_sigaltstack_used.ss_size);
4478 newsp = (oldsp - frame_size) & ~0xFUL;
4480 return newsp;
4483 static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
4484 int sigret)
4486 target_ulong msr = env->msr;
4487 int i;
4488 target_ulong ccr = 0;
4490 /* In general, the kernel attempts to be intelligent about what it
4491 needs to save for Altivec/FP/SPE registers. We don't care that
4492 much, so we just go ahead and save everything. */
4494 /* Save general registers. */
4495 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4496 __put_user(env->gpr[i], &frame->mc_gregs[i]);
4498 __put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP]);
4499 __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR]);
4500 __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK]);
4501 __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]);
4503 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4504 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4506 __put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]);
4508 /* Save Altivec registers if necessary. */
4509 if (env->insns_flags & PPC_ALTIVEC) {
4510 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4511 ppc_avr_t *avr = &env->avr[i];
4512 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4514 __put_user(avr->u64[0], &vreg->u64[0]);
4515 __put_user(avr->u64[1], &vreg->u64[1]);
4517 /* Set MSR_VR in the saved MSR value to indicate that
4518 frame->mc_vregs contains valid data. */
4519 msr |= MSR_VR;
4520 __put_user((uint32_t)env->spr[SPR_VRSAVE],
4521 &frame->mc_vregs.altivec[32].u32[3]);
4524 /* Save floating point registers. */
4525 if (env->insns_flags & PPC_FLOAT) {
4526 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4527 __put_user(env->fpr[i], &frame->mc_fregs[i]);
4529 __put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]);
4532 /* Save SPE registers. The kernel only saves the high half. */
4533 if (env->insns_flags & PPC_SPE) {
4534 #if defined(TARGET_PPC64)
4535 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4536 __put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i]);
4538 #else
4539 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4540 __put_user(env->gprh[i], &frame->mc_vregs.spe[i]);
4542 #endif
4543 /* Set MSR_SPE in the saved MSR value to indicate that
4544 frame->mc_vregs contains valid data. */
4545 msr |= MSR_SPE;
4546 __put_user(env->spe_fscr, &frame->mc_vregs.spe[32]);
4549 /* Store MSR. */
4550 __put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]);
4552 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4553 if (sigret) {
4554 __put_user(0x38000000UL | sigret, &frame->tramp[0]);
4555 __put_user(0x44000002UL, &frame->tramp[1]);
4559 static void restore_user_regs(CPUPPCState *env,
4560 struct target_mcontext *frame, int sig)
4562 target_ulong save_r2 = 0;
4563 target_ulong msr;
4564 target_ulong ccr;
4566 int i;
4568 if (!sig) {
4569 save_r2 = env->gpr[2];
4572 /* Restore general registers. */
4573 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4574 __get_user(env->gpr[i], &frame->mc_gregs[i]);
4576 __get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP]);
4577 __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR]);
4578 __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK]);
4579 __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]);
4580 __get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]);
4582 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4583 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4586 if (!sig) {
4587 env->gpr[2] = save_r2;
4589 /* Restore MSR. */
4590 __get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]);
4592 /* If doing signal return, restore the previous little-endian mode. */
4593 if (sig)
4594 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4596 /* Restore Altivec registers if necessary. */
4597 if (env->insns_flags & PPC_ALTIVEC) {
4598 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4599 ppc_avr_t *avr = &env->avr[i];
4600 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4602 __get_user(avr->u64[0], &vreg->u64[0]);
4603 __get_user(avr->u64[1], &vreg->u64[1]);
4605 /* Set MSR_VEC in the saved MSR value to indicate that
4606 frame->mc_vregs contains valid data. */
4607 __get_user(env->spr[SPR_VRSAVE],
4608 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3]));
4611 /* Restore floating point registers. */
4612 if (env->insns_flags & PPC_FLOAT) {
4613 uint64_t fpscr;
4614 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4615 __get_user(env->fpr[i], &frame->mc_fregs[i]);
4617 __get_user(fpscr, &frame->mc_fregs[32]);
4618 env->fpscr = (uint32_t) fpscr;
4621 /* Save SPE registers. The kernel only saves the high half. */
4622 if (env->insns_flags & PPC_SPE) {
4623 #if defined(TARGET_PPC64)
4624 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4625 uint32_t hi;
4627 __get_user(hi, &frame->mc_vregs.spe[i]);
4628 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4630 #else
4631 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4632 __get_user(env->gprh[i], &frame->mc_vregs.spe[i]);
4634 #endif
4635 __get_user(env->spe_fscr, &frame->mc_vregs.spe[32]);
4639 static void setup_frame(int sig, struct target_sigaction *ka,
4640 target_sigset_t *set, CPUPPCState *env)
4642 struct target_sigframe *frame;
4643 struct target_sigcontext *sc;
4644 target_ulong frame_addr, newsp;
4645 int err = 0;
4646 int signal;
4648 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4649 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4650 goto sigsegv;
4651 sc = &frame->sctx;
4653 signal = current_exec_domain_sig(sig);
4655 __put_user(ka->_sa_handler, &sc->handler);
4656 __put_user(set->sig[0], &sc->oldmask);
4657 #if defined(TARGET_PPC64)
4658 __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4659 #else
4660 __put_user(set->sig[1], &sc->_unused[3]);
4661 #endif
4662 __put_user(h2g(&frame->mctx), &sc->regs);
4663 __put_user(sig, &sc->signal);
4665 /* Save user regs. */
4666 save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
4668 /* The kernel checks for the presence of a VDSO here. We don't
4669 emulate a vdso, so use a sigreturn system call. */
4670 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4672 /* Turn off all fp exceptions. */
4673 env->fpscr = 0;
4675 /* Create a stack frame for the caller of the handler. */
4676 newsp = frame_addr - SIGNAL_FRAMESIZE;
4677 err |= put_user(env->gpr[1], newsp, target_ulong);
4679 if (err)
4680 goto sigsegv;
4682 /* Set up registers for signal handler. */
4683 env->gpr[1] = newsp;
4684 env->gpr[3] = signal;
4685 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
4686 env->nip = (target_ulong) ka->_sa_handler;
4687 /* Signal handlers are entered in big-endian mode. */
4688 env->msr &= ~MSR_LE;
4690 unlock_user_struct(frame, frame_addr, 1);
4691 return;
4693 sigsegv:
4694 unlock_user_struct(frame, frame_addr, 1);
4695 qemu_log("segfaulting from setup_frame\n");
4696 force_sig(TARGET_SIGSEGV);
4699 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4700 target_siginfo_t *info,
4701 target_sigset_t *set, CPUPPCState *env)
4703 struct target_rt_sigframe *rt_sf;
4704 struct target_mcontext *frame;
4705 target_ulong rt_sf_addr, newsp = 0;
4706 int i, err = 0;
4707 int signal;
4709 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4710 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4711 goto sigsegv;
4713 signal = current_exec_domain_sig(sig);
4715 copy_siginfo_to_user(&rt_sf->info, info);
4717 __put_user(0, &rt_sf->uc.tuc_flags);
4718 __put_user(0, &rt_sf->uc.tuc_link);
4719 __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4720 &rt_sf->uc.tuc_stack.ss_sp);
4721 __put_user(sas_ss_flags(env->gpr[1]),
4722 &rt_sf->uc.tuc_stack.ss_flags);
4723 __put_user(target_sigaltstack_used.ss_size,
4724 &rt_sf->uc.tuc_stack.ss_size);
4725 __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4726 &rt_sf->uc.tuc_regs);
4727 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4728 __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4731 frame = &rt_sf->uc.tuc_mcontext;
4732 save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
4734 /* The kernel checks for the presence of a VDSO here. We don't
4735 emulate a vdso, so use a sigreturn system call. */
4736 env->lr = (target_ulong) h2g(frame->tramp);
4738 /* Turn off all fp exceptions. */
4739 env->fpscr = 0;
4741 /* Create a stack frame for the caller of the handler. */
4742 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4743 __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
4745 if (err)
4746 goto sigsegv;
4748 /* Set up registers for signal handler. */
4749 env->gpr[1] = newsp;
4750 env->gpr[3] = (target_ulong) signal;
4751 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4752 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4753 env->gpr[6] = (target_ulong) h2g(rt_sf);
4754 env->nip = (target_ulong) ka->_sa_handler;
4755 /* Signal handlers are entered in big-endian mode. */
4756 env->msr &= ~MSR_LE;
4758 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4759 return;
4761 sigsegv:
4762 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4763 qemu_log("segfaulting from setup_rt_frame\n");
4764 force_sig(TARGET_SIGSEGV);
4768 long do_sigreturn(CPUPPCState *env)
4770 struct target_sigcontext *sc = NULL;
4771 struct target_mcontext *sr = NULL;
4772 target_ulong sr_addr = 0, sc_addr;
4773 sigset_t blocked;
4774 target_sigset_t set;
4776 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4777 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4778 goto sigsegv;
4780 #if defined(TARGET_PPC64)
4781 set.sig[0] = sc->oldmask + ((long)(sc->_unused[3]) << 32);
4782 #else
4783 __get_user(set.sig[0], &sc->oldmask);
4784 __get_user(set.sig[1], &sc->_unused[3]);
4785 #endif
4786 target_to_host_sigset_internal(&blocked, &set);
4787 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
4789 __get_user(sr_addr, &sc->regs);
4790 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4791 goto sigsegv;
4792 restore_user_regs(env, sr, 1);
4794 unlock_user_struct(sr, sr_addr, 1);
4795 unlock_user_struct(sc, sc_addr, 1);
4796 return -TARGET_QEMU_ESIGRETURN;
4798 sigsegv:
4799 unlock_user_struct(sr, sr_addr, 1);
4800 unlock_user_struct(sc, sc_addr, 1);
4801 qemu_log("segfaulting from do_sigreturn\n");
4802 force_sig(TARGET_SIGSEGV);
4803 return 0;
4806 /* See arch/powerpc/kernel/signal_32.c. */
4807 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4809 struct target_mcontext *mcp;
4810 target_ulong mcp_addr;
4811 sigset_t blocked;
4812 target_sigset_t set;
4814 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4815 sizeof (set)))
4816 return 1;
4818 #if defined(TARGET_PPC64)
4819 fprintf (stderr, "do_setcontext: not implemented\n");
4820 return 0;
4821 #else
4822 __get_user(mcp_addr, &ucp->tuc_regs);
4824 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4825 return 1;
4827 target_to_host_sigset_internal(&blocked, &set);
4828 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
4829 restore_user_regs(env, mcp, sig);
4831 unlock_user_struct(mcp, mcp_addr, 1);
4832 return 0;
4833 #endif
4836 long do_rt_sigreturn(CPUPPCState *env)
4838 struct target_rt_sigframe *rt_sf = NULL;
4839 target_ulong rt_sf_addr;
4841 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4842 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4843 goto sigsegv;
4845 if (do_setcontext(&rt_sf->uc, env, 1))
4846 goto sigsegv;
4848 do_sigaltstack(rt_sf_addr
4849 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4850 0, env->gpr[1]);
4852 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4853 return -TARGET_QEMU_ESIGRETURN;
4855 sigsegv:
4856 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4857 qemu_log("segfaulting from do_rt_sigreturn\n");
4858 force_sig(TARGET_SIGSEGV);
4859 return 0;
4862 #elif defined(TARGET_M68K)
4864 struct target_sigcontext {
4865 abi_ulong sc_mask;
4866 abi_ulong sc_usp;
4867 abi_ulong sc_d0;
4868 abi_ulong sc_d1;
4869 abi_ulong sc_a0;
4870 abi_ulong sc_a1;
4871 unsigned short sc_sr;
4872 abi_ulong sc_pc;
4875 struct target_sigframe
4877 abi_ulong pretcode;
4878 int sig;
4879 int code;
4880 abi_ulong psc;
4881 char retcode[8];
4882 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4883 struct target_sigcontext sc;
4886 typedef int target_greg_t;
4887 #define TARGET_NGREG 18
4888 typedef target_greg_t target_gregset_t[TARGET_NGREG];
4890 typedef struct target_fpregset {
4891 int f_fpcntl[3];
4892 int f_fpregs[8*3];
4893 } target_fpregset_t;
4895 struct target_mcontext {
4896 int version;
4897 target_gregset_t gregs;
4898 target_fpregset_t fpregs;
4901 #define TARGET_MCONTEXT_VERSION 2
4903 struct target_ucontext {
4904 abi_ulong tuc_flags;
4905 abi_ulong tuc_link;
4906 target_stack_t tuc_stack;
4907 struct target_mcontext tuc_mcontext;
4908 abi_long tuc_filler[80];
4909 target_sigset_t tuc_sigmask;
4912 struct target_rt_sigframe
4914 abi_ulong pretcode;
4915 int sig;
4916 abi_ulong pinfo;
4917 abi_ulong puc;
4918 char retcode[8];
4919 struct target_siginfo info;
4920 struct target_ucontext uc;
4923 static void setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
4924 abi_ulong mask)
4926 __put_user(mask, &sc->sc_mask);
4927 __put_user(env->aregs[7], &sc->sc_usp);
4928 __put_user(env->dregs[0], &sc->sc_d0);
4929 __put_user(env->dregs[1], &sc->sc_d1);
4930 __put_user(env->aregs[0], &sc->sc_a0);
4931 __put_user(env->aregs[1], &sc->sc_a1);
4932 __put_user(env->sr, &sc->sc_sr);
4933 __put_user(env->pc, &sc->sc_pc);
4936 static void
4937 restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
4939 int temp;
4941 __get_user(env->aregs[7], &sc->sc_usp);
4942 __get_user(env->dregs[1], &sc->sc_d1);
4943 __get_user(env->aregs[0], &sc->sc_a0);
4944 __get_user(env->aregs[1], &sc->sc_a1);
4945 __get_user(env->pc, &sc->sc_pc);
4946 __get_user(temp, &sc->sc_sr);
4947 env->sr = (env->sr & 0xff00) | (temp & 0xff);
4949 *pd0 = tswapl(sc->sc_d0);
4953 * Determine which stack to use..
4955 static inline abi_ulong
4956 get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
4957 size_t frame_size)
4959 unsigned long sp;
4961 sp = regs->aregs[7];
4963 /* This is the X/Open sanctioned signal stack switching. */
4964 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
4965 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4968 return ((sp - frame_size) & -8UL);
4971 static void setup_frame(int sig, struct target_sigaction *ka,
4972 target_sigset_t *set, CPUM68KState *env)
4974 struct target_sigframe *frame;
4975 abi_ulong frame_addr;
4976 abi_ulong retcode_addr;
4977 abi_ulong sc_addr;
4978 int i;
4980 frame_addr = get_sigframe(ka, env, sizeof *frame);
4981 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
4982 goto give_sigsegv;
4984 __put_user(sig, &frame->sig);
4986 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
4987 __put_user(sc_addr, &frame->psc);
4989 setup_sigcontext(&frame->sc, env, set->sig[0]);
4991 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
4992 __put_user(set->sig[i], &frame->extramask[i - 1]);
4995 /* Set up to return from userspace. */
4997 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
4998 __put_user(retcode_addr, &frame->pretcode);
5000 /* moveq #,d0; trap #0 */
5002 __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5003 (long *)(frame->retcode));
5005 /* Set up to return from userspace */
5007 env->aregs[7] = frame_addr;
5008 env->pc = ka->_sa_handler;
5010 unlock_user_struct(frame, frame_addr, 1);
5011 return;
5013 give_sigsegv:
5014 force_sig(TARGET_SIGSEGV);
5017 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5018 CPUM68KState *env)
5020 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5022 __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
5023 __put_user(env->dregs[0], &gregs[0]);
5024 __put_user(env->dregs[1], &gregs[1]);
5025 __put_user(env->dregs[2], &gregs[2]);
5026 __put_user(env->dregs[3], &gregs[3]);
5027 __put_user(env->dregs[4], &gregs[4]);
5028 __put_user(env->dregs[5], &gregs[5]);
5029 __put_user(env->dregs[6], &gregs[6]);
5030 __put_user(env->dregs[7], &gregs[7]);
5031 __put_user(env->aregs[0], &gregs[8]);
5032 __put_user(env->aregs[1], &gregs[9]);
5033 __put_user(env->aregs[2], &gregs[10]);
5034 __put_user(env->aregs[3], &gregs[11]);
5035 __put_user(env->aregs[4], &gregs[12]);
5036 __put_user(env->aregs[5], &gregs[13]);
5037 __put_user(env->aregs[6], &gregs[14]);
5038 __put_user(env->aregs[7], &gregs[15]);
5039 __put_user(env->pc, &gregs[16]);
5040 __put_user(env->sr, &gregs[17]);
5042 return 0;
5045 static inline int target_rt_restore_ucontext(CPUM68KState *env,
5046 struct target_ucontext *uc,
5047 int *pd0)
5049 int temp;
5050 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5052 __get_user(temp, &uc->tuc_mcontext.version);
5053 if (temp != TARGET_MCONTEXT_VERSION)
5054 goto badframe;
5056 /* restore passed registers */
5057 __get_user(env->dregs[0], &gregs[0]);
5058 __get_user(env->dregs[1], &gregs[1]);
5059 __get_user(env->dregs[2], &gregs[2]);
5060 __get_user(env->dregs[3], &gregs[3]);
5061 __get_user(env->dregs[4], &gregs[4]);
5062 __get_user(env->dregs[5], &gregs[5]);
5063 __get_user(env->dregs[6], &gregs[6]);
5064 __get_user(env->dregs[7], &gregs[7]);
5065 __get_user(env->aregs[0], &gregs[8]);
5066 __get_user(env->aregs[1], &gregs[9]);
5067 __get_user(env->aregs[2], &gregs[10]);
5068 __get_user(env->aregs[3], &gregs[11]);
5069 __get_user(env->aregs[4], &gregs[12]);
5070 __get_user(env->aregs[5], &gregs[13]);
5071 __get_user(env->aregs[6], &gregs[14]);
5072 __get_user(env->aregs[7], &gregs[15]);
5073 __get_user(env->pc, &gregs[16]);
5074 __get_user(temp, &gregs[17]);
5075 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5077 *pd0 = env->dregs[0];
5078 return 0;
5080 badframe:
5081 return 1;
5084 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5085 target_siginfo_t *info,
5086 target_sigset_t *set, CPUM68KState *env)
5088 struct target_rt_sigframe *frame;
5089 abi_ulong frame_addr;
5090 abi_ulong retcode_addr;
5091 abi_ulong info_addr;
5092 abi_ulong uc_addr;
5093 int err = 0;
5094 int i;
5096 frame_addr = get_sigframe(ka, env, sizeof *frame);
5097 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5098 goto give_sigsegv;
5100 __put_user(sig, &frame->sig);
5102 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5103 __put_user(info_addr, &frame->pinfo);
5105 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5106 __put_user(uc_addr, &frame->puc);
5108 copy_siginfo_to_user(&frame->info, info);
5110 /* Create the ucontext */
5112 __put_user(0, &frame->uc.tuc_flags);
5113 __put_user(0, &frame->uc.tuc_link);
5114 __put_user(target_sigaltstack_used.ss_sp,
5115 &frame->uc.tuc_stack.ss_sp);
5116 __put_user(sas_ss_flags(env->aregs[7]),
5117 &frame->uc.tuc_stack.ss_flags);
5118 __put_user(target_sigaltstack_used.ss_size,
5119 &frame->uc.tuc_stack.ss_size);
5120 err |= target_rt_setup_ucontext(&frame->uc, env);
5122 if (err)
5123 goto give_sigsegv;
5125 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5126 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5129 /* Set up to return from userspace. */
5131 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5132 __put_user(retcode_addr, &frame->pretcode);
5134 /* moveq #,d0; notb d0; trap #0 */
5136 __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
5137 (long *)(frame->retcode + 0));
5138 __put_user(0x4e40, (short *)(frame->retcode + 4));
5140 if (err)
5141 goto give_sigsegv;
5143 /* Set up to return from userspace */
5145 env->aregs[7] = frame_addr;
5146 env->pc = ka->_sa_handler;
5148 unlock_user_struct(frame, frame_addr, 1);
5149 return;
5151 give_sigsegv:
5152 unlock_user_struct(frame, frame_addr, 1);
5153 force_sig(TARGET_SIGSEGV);
5156 long do_sigreturn(CPUM68KState *env)
5158 struct target_sigframe *frame;
5159 abi_ulong frame_addr = env->aregs[7] - 4;
5160 target_sigset_t target_set;
5161 sigset_t set;
5162 int d0, i;
5164 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5165 goto badframe;
5167 /* set blocked signals */
5169 __get_user(target_set.sig[0], &frame->sc.sc_mask);
5171 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5172 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
5175 target_to_host_sigset_internal(&set, &target_set);
5176 do_sigprocmask(SIG_SETMASK, &set, NULL);
5178 /* restore registers */
5180 restore_sigcontext(env, &frame->sc, &d0);
5182 unlock_user_struct(frame, frame_addr, 0);
5183 return d0;
5185 badframe:
5186 force_sig(TARGET_SIGSEGV);
5187 return 0;
5190 long do_rt_sigreturn(CPUM68KState *env)
5192 struct target_rt_sigframe *frame;
5193 abi_ulong frame_addr = env->aregs[7] - 4;
5194 target_sigset_t target_set;
5195 sigset_t set;
5196 int d0;
5198 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5199 goto badframe;
5201 target_to_host_sigset_internal(&set, &target_set);
5202 do_sigprocmask(SIG_SETMASK, &set, NULL);
5204 /* restore registers */
5206 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5207 goto badframe;
5209 if (do_sigaltstack(frame_addr +
5210 offsetof(struct target_rt_sigframe, uc.tuc_stack),
5211 0, get_sp_from_cpustate(env)) == -EFAULT)
5212 goto badframe;
5214 unlock_user_struct(frame, frame_addr, 0);
5215 return d0;
5217 badframe:
5218 unlock_user_struct(frame, frame_addr, 0);
5219 force_sig(TARGET_SIGSEGV);
5220 return 0;
5223 #elif defined(TARGET_ALPHA)
5225 struct target_sigcontext {
5226 abi_long sc_onstack;
5227 abi_long sc_mask;
5228 abi_long sc_pc;
5229 abi_long sc_ps;
5230 abi_long sc_regs[32];
5231 abi_long sc_ownedfp;
5232 abi_long sc_fpregs[32];
5233 abi_ulong sc_fpcr;
5234 abi_ulong sc_fp_control;
5235 abi_ulong sc_reserved1;
5236 abi_ulong sc_reserved2;
5237 abi_ulong sc_ssize;
5238 abi_ulong sc_sbase;
5239 abi_ulong sc_traparg_a0;
5240 abi_ulong sc_traparg_a1;
5241 abi_ulong sc_traparg_a2;
5242 abi_ulong sc_fp_trap_pc;
5243 abi_ulong sc_fp_trigger_sum;
5244 abi_ulong sc_fp_trigger_inst;
5247 struct target_ucontext {
5248 abi_ulong tuc_flags;
5249 abi_ulong tuc_link;
5250 abi_ulong tuc_osf_sigmask;
5251 target_stack_t tuc_stack;
5252 struct target_sigcontext tuc_mcontext;
5253 target_sigset_t tuc_sigmask;
5256 struct target_sigframe {
5257 struct target_sigcontext sc;
5258 unsigned int retcode[3];
5261 struct target_rt_sigframe {
5262 target_siginfo_t info;
5263 struct target_ucontext uc;
5264 unsigned int retcode[3];
5267 #define INSN_MOV_R30_R16 0x47fe0410
5268 #define INSN_LDI_R0 0x201f0000
5269 #define INSN_CALLSYS 0x00000083
5271 static void setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5272 abi_ulong frame_addr, target_sigset_t *set)
5274 int i;
5276 __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
5277 __put_user(set->sig[0], &sc->sc_mask);
5278 __put_user(env->pc, &sc->sc_pc);
5279 __put_user(8, &sc->sc_ps);
5281 for (i = 0; i < 31; ++i) {
5282 __put_user(env->ir[i], &sc->sc_regs[i]);
5284 __put_user(0, &sc->sc_regs[31]);
5286 for (i = 0; i < 31; ++i) {
5287 __put_user(env->fir[i], &sc->sc_fpregs[i]);
5289 __put_user(0, &sc->sc_fpregs[31]);
5290 __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5292 __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5293 __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5294 __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5297 static void restore_sigcontext(CPUAlphaState *env,
5298 struct target_sigcontext *sc)
5300 uint64_t fpcr;
5301 int i;
5303 __get_user(env->pc, &sc->sc_pc);
5305 for (i = 0; i < 31; ++i) {
5306 __get_user(env->ir[i], &sc->sc_regs[i]);
5308 for (i = 0; i < 31; ++i) {
5309 __get_user(env->fir[i], &sc->sc_fpregs[i]);
5312 __get_user(fpcr, &sc->sc_fpcr);
5313 cpu_alpha_store_fpcr(env, fpcr);
5316 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5317 CPUAlphaState *env,
5318 unsigned long framesize)
5320 abi_ulong sp = env->ir[IR_SP];
5322 /* This is the X/Open sanctioned signal stack switching. */
5323 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5324 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5326 return (sp - framesize) & -32;
5329 static void setup_frame(int sig, struct target_sigaction *ka,
5330 target_sigset_t *set, CPUAlphaState *env)
5332 abi_ulong frame_addr, r26;
5333 struct target_sigframe *frame;
5334 int err = 0;
5336 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5337 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5338 goto give_sigsegv;
5341 setup_sigcontext(&frame->sc, env, frame_addr, set);
5343 if (ka->sa_restorer) {
5344 r26 = ka->sa_restorer;
5345 } else {
5346 __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5347 __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5348 &frame->retcode[1]);
5349 __put_user(INSN_CALLSYS, &frame->retcode[2]);
5350 /* imb() */
5351 r26 = frame_addr;
5354 unlock_user_struct(frame, frame_addr, 1);
5356 if (err) {
5357 give_sigsegv:
5358 if (sig == TARGET_SIGSEGV) {
5359 ka->_sa_handler = TARGET_SIG_DFL;
5361 force_sig(TARGET_SIGSEGV);
5364 env->ir[IR_RA] = r26;
5365 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5366 env->ir[IR_A0] = sig;
5367 env->ir[IR_A1] = 0;
5368 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5369 env->ir[IR_SP] = frame_addr;
5372 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5373 target_siginfo_t *info,
5374 target_sigset_t *set, CPUAlphaState *env)
5376 abi_ulong frame_addr, r26;
5377 struct target_rt_sigframe *frame;
5378 int i, err = 0;
5380 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5381 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5382 goto give_sigsegv;
5385 copy_siginfo_to_user(&frame->info, info);
5387 __put_user(0, &frame->uc.tuc_flags);
5388 __put_user(0, &frame->uc.tuc_link);
5389 __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5390 __put_user(target_sigaltstack_used.ss_sp,
5391 &frame->uc.tuc_stack.ss_sp);
5392 __put_user(sas_ss_flags(env->ir[IR_SP]),
5393 &frame->uc.tuc_stack.ss_flags);
5394 __put_user(target_sigaltstack_used.ss_size,
5395 &frame->uc.tuc_stack.ss_size);
5396 setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5397 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5398 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5401 if (ka->sa_restorer) {
5402 r26 = ka->sa_restorer;
5403 } else {
5404 __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5405 __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5406 &frame->retcode[1]);
5407 __put_user(INSN_CALLSYS, &frame->retcode[2]);
5408 /* imb(); */
5409 r26 = frame_addr;
5412 if (err) {
5413 give_sigsegv:
5414 if (sig == TARGET_SIGSEGV) {
5415 ka->_sa_handler = TARGET_SIG_DFL;
5417 force_sig(TARGET_SIGSEGV);
5420 env->ir[IR_RA] = r26;
5421 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5422 env->ir[IR_A0] = sig;
5423 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5424 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5425 env->ir[IR_SP] = frame_addr;
5428 long do_sigreturn(CPUAlphaState *env)
5430 struct target_sigcontext *sc;
5431 abi_ulong sc_addr = env->ir[IR_A0];
5432 target_sigset_t target_set;
5433 sigset_t set;
5435 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5436 goto badframe;
5439 target_sigemptyset(&target_set);
5440 __get_user(target_set.sig[0], &sc->sc_mask);
5442 target_to_host_sigset_internal(&set, &target_set);
5443 do_sigprocmask(SIG_SETMASK, &set, NULL);
5445 restore_sigcontext(env, sc);
5446 unlock_user_struct(sc, sc_addr, 0);
5447 return env->ir[IR_V0];
5449 badframe:
5450 force_sig(TARGET_SIGSEGV);
5453 long do_rt_sigreturn(CPUAlphaState *env)
5455 abi_ulong frame_addr = env->ir[IR_A0];
5456 struct target_rt_sigframe *frame;
5457 sigset_t set;
5459 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5460 goto badframe;
5462 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5463 do_sigprocmask(SIG_SETMASK, &set, NULL);
5465 restore_sigcontext(env, &frame->uc.tuc_mcontext);
5466 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5467 uc.tuc_stack),
5468 0, env->ir[IR_SP]) == -EFAULT) {
5469 goto badframe;
5472 unlock_user_struct(frame, frame_addr, 0);
5473 return env->ir[IR_V0];
5476 badframe:
5477 unlock_user_struct(frame, frame_addr, 0);
5478 force_sig(TARGET_SIGSEGV);
5481 #else
5483 static void setup_frame(int sig, struct target_sigaction *ka,
5484 target_sigset_t *set, CPUArchState *env)
5486 fprintf(stderr, "setup_frame: not implemented\n");
5489 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5490 target_siginfo_t *info,
5491 target_sigset_t *set, CPUArchState *env)
5493 fprintf(stderr, "setup_rt_frame: not implemented\n");
5496 long do_sigreturn(CPUArchState *env)
5498 fprintf(stderr, "do_sigreturn: not implemented\n");
5499 return -TARGET_ENOSYS;
5502 long do_rt_sigreturn(CPUArchState *env)
5504 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5505 return -TARGET_ENOSYS;
5508 #endif
5510 void process_pending_signals(CPUArchState *cpu_env)
5512 CPUState *cpu = ENV_GET_CPU(cpu_env);
5513 int sig;
5514 abi_ulong handler;
5515 sigset_t set, old_set;
5516 target_sigset_t target_old_set;
5517 struct emulated_sigtable *k;
5518 struct target_sigaction *sa;
5519 struct sigqueue *q;
5520 TaskState *ts = cpu->opaque;
5522 if (!ts->signal_pending)
5523 return;
5525 /* FIXME: This is not threadsafe. */
5526 k = ts->sigtab;
5527 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5528 if (k->pending)
5529 goto handle_signal;
5530 k++;
5532 /* if no signal is pending, just return */
5533 ts->signal_pending = 0;
5534 return;
5536 handle_signal:
5537 #ifdef DEBUG_SIGNAL
5538 fprintf(stderr, "qemu: process signal %d\n", sig);
5539 #endif
5540 /* dequeue signal */
5541 q = k->first;
5542 k->first = q->next;
5543 if (!k->first)
5544 k->pending = 0;
5546 sig = gdb_handlesig(cpu, sig);
5547 if (!sig) {
5548 sa = NULL;
5549 handler = TARGET_SIG_IGN;
5550 } else {
5551 sa = &sigact_table[sig - 1];
5552 handler = sa->_sa_handler;
5555 if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {
5556 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
5557 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
5558 * because it got a real MMU fault), and treat as if default handler.
5560 handler = TARGET_SIG_DFL;
5563 if (handler == TARGET_SIG_DFL) {
5564 /* default handler : ignore some signal. The other are job control or fatal */
5565 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5566 kill(getpid(),SIGSTOP);
5567 } else if (sig != TARGET_SIGCHLD &&
5568 sig != TARGET_SIGURG &&
5569 sig != TARGET_SIGWINCH &&
5570 sig != TARGET_SIGCONT) {
5571 force_sig(sig);
5573 } else if (handler == TARGET_SIG_IGN) {
5574 /* ignore sig */
5575 } else if (handler == TARGET_SIG_ERR) {
5576 force_sig(sig);
5577 } else {
5578 /* compute the blocked signals during the handler execution */
5579 target_to_host_sigset(&set, &sa->sa_mask);
5580 /* SA_NODEFER indicates that the current signal should not be
5581 blocked during the handler */
5582 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5583 sigaddset(&set, target_to_host_signal(sig));
5585 /* block signals in the handler using Linux */
5586 do_sigprocmask(SIG_BLOCK, &set, &old_set);
5587 /* save the previous blocked signal state to restore it at the
5588 end of the signal execution (see do_sigreturn) */
5589 host_to_target_sigset_internal(&target_old_set, &old_set);
5591 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5592 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5594 CPUX86State *env = cpu_env;
5595 if (env->eflags & VM_MASK)
5596 save_v86_state(env);
5598 #endif
5599 /* prepare the stack frame of the virtual CPU */
5600 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5601 /* These targets do not have traditional signals. */
5602 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5603 #else
5604 if (sa->sa_flags & TARGET_SA_SIGINFO)
5605 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5606 else
5607 setup_frame(sig, sa, &target_old_set, cpu_env);
5608 #endif
5609 if (sa->sa_flags & TARGET_SA_RESETHAND)
5610 sa->_sa_handler = TARGET_SIG_DFL;
5612 if (q != &k->info)
5613 free_sigqueue(cpu_env, q);