Merge remote-tracking branch 'qemu/master'
[qemu/ar7.git] / linux-user / signal.c
blob60be90a6198aadaea302e96bcf2c78bd577fb0c5
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/>.
20 #include <sys/ucontext.h>
21 #include <sys/resource.h>
23 #include "qemu-common.h"
24 #include "qemu.h"
25 #include "target_signal.h"
27 //#define DEBUG_SIGNAL
29 static struct target_sigaltstack target_sigaltstack_used = {
30 .ss_sp = 0,
31 .ss_size = 0,
32 .ss_flags = TARGET_SS_DISABLE,
35 static struct target_sigaction sigact_table[TARGET_NSIG];
37 static void host_signal_handler(int host_signum, siginfo_t *info,
38 void *puc);
40 static uint8_t host_to_target_signal_table[_NSIG] = {
41 [SIGHUP] = TARGET_SIGHUP,
42 [SIGINT] = TARGET_SIGINT,
43 [SIGQUIT] = TARGET_SIGQUIT,
44 [SIGILL] = TARGET_SIGILL,
45 [SIGTRAP] = TARGET_SIGTRAP,
46 [SIGABRT] = TARGET_SIGABRT,
47 /* [SIGIOT] = TARGET_SIGIOT,*/
48 [SIGBUS] = TARGET_SIGBUS,
49 [SIGFPE] = TARGET_SIGFPE,
50 [SIGKILL] = TARGET_SIGKILL,
51 [SIGUSR1] = TARGET_SIGUSR1,
52 [SIGSEGV] = TARGET_SIGSEGV,
53 [SIGUSR2] = TARGET_SIGUSR2,
54 [SIGPIPE] = TARGET_SIGPIPE,
55 [SIGALRM] = TARGET_SIGALRM,
56 [SIGTERM] = TARGET_SIGTERM,
57 #ifdef SIGSTKFLT
58 [SIGSTKFLT] = TARGET_SIGSTKFLT,
59 #endif
60 [SIGCHLD] = TARGET_SIGCHLD,
61 [SIGCONT] = TARGET_SIGCONT,
62 [SIGSTOP] = TARGET_SIGSTOP,
63 [SIGTSTP] = TARGET_SIGTSTP,
64 [SIGTTIN] = TARGET_SIGTTIN,
65 [SIGTTOU] = TARGET_SIGTTOU,
66 [SIGURG] = TARGET_SIGURG,
67 [SIGXCPU] = TARGET_SIGXCPU,
68 [SIGXFSZ] = TARGET_SIGXFSZ,
69 [SIGVTALRM] = TARGET_SIGVTALRM,
70 [SIGPROF] = TARGET_SIGPROF,
71 [SIGWINCH] = TARGET_SIGWINCH,
72 [SIGIO] = TARGET_SIGIO,
73 [SIGPWR] = TARGET_SIGPWR,
74 [SIGSYS] = TARGET_SIGSYS,
75 /* next signals stay the same */
76 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
77 host libpthread signals. This assumes no one actually uses SIGRTMAX :-/
78 To fix this properly we need to do manual signal delivery multiplexed
79 over a single host signal. */
80 [__SIGRTMIN] = __SIGRTMAX,
81 [__SIGRTMAX] = __SIGRTMIN,
83 static uint8_t target_to_host_signal_table[_NSIG];
85 static inline int on_sig_stack(unsigned long sp)
87 return (sp - target_sigaltstack_used.ss_sp
88 < target_sigaltstack_used.ss_size);
91 static inline int sas_ss_flags(unsigned long sp)
93 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
94 : on_sig_stack(sp) ? SS_ONSTACK : 0);
97 int host_to_target_signal(int sig)
99 if (sig < 0 || sig >= _NSIG)
100 return sig;
101 return host_to_target_signal_table[sig];
104 int target_to_host_signal(int sig)
106 if (sig < 0 || sig >= _NSIG)
107 return sig;
108 return target_to_host_signal_table[sig];
111 static inline void target_sigemptyset(target_sigset_t *set)
113 memset(set, 0, sizeof(*set));
116 static inline void target_sigaddset(target_sigset_t *set, int signum)
118 signum--;
119 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
120 set->sig[signum / TARGET_NSIG_BPW] |= mask;
123 static inline int target_sigismember(const target_sigset_t *set, int signum)
125 signum--;
126 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
127 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
130 static void host_to_target_sigset_internal(target_sigset_t *d,
131 const sigset_t *s)
133 int i;
134 target_sigemptyset(d);
135 for (i = 1; i <= TARGET_NSIG; i++) {
136 if (sigismember(s, i)) {
137 target_sigaddset(d, host_to_target_signal(i));
142 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
144 target_sigset_t d1;
145 int i;
147 host_to_target_sigset_internal(&d1, s);
148 for(i = 0;i < TARGET_NSIG_WORDS; i++)
149 d->sig[i] = tswapal(d1.sig[i]);
152 static void target_to_host_sigset_internal(sigset_t *d,
153 const target_sigset_t *s)
155 int i;
156 sigemptyset(d);
157 for (i = 1; i <= TARGET_NSIG; i++) {
158 if (target_sigismember(s, i)) {
159 sigaddset(d, target_to_host_signal(i));
164 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
166 target_sigset_t s1;
167 int i;
169 for(i = 0;i < TARGET_NSIG_WORDS; i++)
170 s1.sig[i] = tswapal(s->sig[i]);
171 target_to_host_sigset_internal(d, &s1);
174 void host_to_target_old_sigset(abi_ulong *old_sigset,
175 const sigset_t *sigset)
177 target_sigset_t d;
178 host_to_target_sigset(&d, sigset);
179 *old_sigset = d.sig[0];
182 void target_to_host_old_sigset(sigset_t *sigset,
183 const abi_ulong *old_sigset)
185 target_sigset_t d;
186 int i;
188 d.sig[0] = *old_sigset;
189 for(i = 1;i < TARGET_NSIG_WORDS; i++)
190 d.sig[i] = 0;
191 target_to_host_sigset(sigset, &d);
194 /* Wrapper for sigprocmask function
195 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
196 * are host signal set, not guest ones. This wraps the sigprocmask host calls
197 * that should be protected (calls originated from guest)
199 int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
201 int ret;
202 sigset_t val;
203 sigset_t *temp = NULL;
204 CPUState *cpu = thread_cpu;
205 TaskState *ts = (TaskState *)cpu->opaque;
206 bool segv_was_blocked = ts->sigsegv_blocked;
208 if (set) {
209 bool has_sigsegv = sigismember(set, SIGSEGV);
210 val = *set;
211 temp = &val;
213 sigdelset(temp, SIGSEGV);
215 switch (how) {
216 case SIG_BLOCK:
217 if (has_sigsegv) {
218 ts->sigsegv_blocked = true;
220 break;
221 case SIG_UNBLOCK:
222 if (has_sigsegv) {
223 ts->sigsegv_blocked = false;
225 break;
226 case SIG_SETMASK:
227 ts->sigsegv_blocked = has_sigsegv;
228 break;
229 default:
230 g_assert_not_reached();
234 ret = sigprocmask(how, temp, oldset);
236 if (oldset && segv_was_blocked) {
237 sigaddset(oldset, SIGSEGV);
240 return ret;
243 /* siginfo conversion */
245 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
246 const siginfo_t *info)
248 int sig = host_to_target_signal(info->si_signo);
249 tinfo->si_signo = sig;
250 tinfo->si_errno = 0;
251 tinfo->si_code = info->si_code;
253 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
254 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
255 /* Should never come here, but who knows. The information for
256 the target is irrelevant. */
257 tinfo->_sifields._sigfault._addr = 0;
258 } else if (sig == TARGET_SIGIO) {
259 tinfo->_sifields._sigpoll._band = info->si_band;
260 tinfo->_sifields._sigpoll._fd = info->si_fd;
261 } else if (sig == TARGET_SIGCHLD) {
262 tinfo->_sifields._sigchld._pid = info->si_pid;
263 tinfo->_sifields._sigchld._uid = info->si_uid;
264 tinfo->_sifields._sigchld._status
265 = host_to_target_waitstatus(info->si_status);
266 tinfo->_sifields._sigchld._utime = info->si_utime;
267 tinfo->_sifields._sigchld._stime = info->si_stime;
268 } else if (sig >= TARGET_SIGRTMIN) {
269 tinfo->_sifields._rt._pid = info->si_pid;
270 tinfo->_sifields._rt._uid = info->si_uid;
271 /* XXX: potential problem if 64 bit */
272 tinfo->_sifields._rt._sigval.sival_ptr
273 = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
277 static void tswap_siginfo(target_siginfo_t *tinfo,
278 const target_siginfo_t *info)
280 int sig = info->si_signo;
281 tinfo->si_signo = tswap32(sig);
282 tinfo->si_errno = tswap32(info->si_errno);
283 tinfo->si_code = tswap32(info->si_code);
285 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
286 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
287 tinfo->_sifields._sigfault._addr
288 = tswapal(info->_sifields._sigfault._addr);
289 } else if (sig == TARGET_SIGIO) {
290 tinfo->_sifields._sigpoll._band
291 = tswap32(info->_sifields._sigpoll._band);
292 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
293 } else if (sig == TARGET_SIGCHLD) {
294 tinfo->_sifields._sigchld._pid
295 = tswap32(info->_sifields._sigchld._pid);
296 tinfo->_sifields._sigchld._uid
297 = tswap32(info->_sifields._sigchld._uid);
298 tinfo->_sifields._sigchld._status
299 = tswap32(info->_sifields._sigchld._status);
300 tinfo->_sifields._sigchld._utime
301 = tswapal(info->_sifields._sigchld._utime);
302 tinfo->_sifields._sigchld._stime
303 = tswapal(info->_sifields._sigchld._stime);
304 } else if (sig >= TARGET_SIGRTMIN) {
305 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
306 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
307 tinfo->_sifields._rt._sigval.sival_ptr
308 = tswapal(info->_sifields._rt._sigval.sival_ptr);
313 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
315 host_to_target_siginfo_noswap(tinfo, info);
316 tswap_siginfo(tinfo, tinfo);
319 /* XXX: we support only POSIX RT signals are used. */
320 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
321 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
323 info->si_signo = tswap32(tinfo->si_signo);
324 info->si_errno = tswap32(tinfo->si_errno);
325 info->si_code = tswap32(tinfo->si_code);
326 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
327 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
328 info->si_value.sival_ptr =
329 (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr);
332 static int fatal_signal (int sig)
334 switch (sig) {
335 case TARGET_SIGCHLD:
336 case TARGET_SIGURG:
337 case TARGET_SIGWINCH:
338 /* Ignored by default. */
339 return 0;
340 case TARGET_SIGCONT:
341 case TARGET_SIGSTOP:
342 case TARGET_SIGTSTP:
343 case TARGET_SIGTTIN:
344 case TARGET_SIGTTOU:
345 /* Job control signals. */
346 return 0;
347 default:
348 return 1;
352 /* returns 1 if given signal should dump core if not handled */
353 static int core_dump_signal(int sig)
355 switch (sig) {
356 case TARGET_SIGABRT:
357 case TARGET_SIGFPE:
358 case TARGET_SIGILL:
359 case TARGET_SIGQUIT:
360 case TARGET_SIGSEGV:
361 case TARGET_SIGTRAP:
362 case TARGET_SIGBUS:
363 return (1);
364 default:
365 return (0);
369 void signal_init(void)
371 struct sigaction act;
372 struct sigaction oact;
373 int i, j;
374 int host_sig;
376 /* generate signal conversion tables */
377 for(i = 1; i < _NSIG; i++) {
378 if (host_to_target_signal_table[i] == 0)
379 host_to_target_signal_table[i] = i;
381 for(i = 1; i < _NSIG; i++) {
382 j = host_to_target_signal_table[i];
383 target_to_host_signal_table[j] = i;
386 /* set all host signal handlers. ALL signals are blocked during
387 the handlers to serialize them. */
388 memset(sigact_table, 0, sizeof(sigact_table));
390 sigfillset(&act.sa_mask);
391 act.sa_flags = SA_SIGINFO;
392 act.sa_sigaction = host_signal_handler;
393 for(i = 1; i <= TARGET_NSIG; i++) {
394 host_sig = target_to_host_signal(i);
395 sigaction(host_sig, NULL, &oact);
396 if (oact.sa_sigaction == (void *)SIG_IGN) {
397 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
398 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
399 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
401 /* If there's already a handler installed then something has
402 gone horribly wrong, so don't even try to handle that case. */
403 /* Install some handlers for our own use. We need at least
404 SIGSEGV and SIGBUS, to detect exceptions. We can not just
405 trap all signals because it affects syscall interrupt
406 behavior. But do trap all default-fatal signals. */
407 if (fatal_signal (i))
408 sigaction(host_sig, &act, NULL);
412 /* signal queue handling */
414 static inline struct sigqueue *alloc_sigqueue(CPUArchState *env)
416 CPUState *cpu = ENV_GET_CPU(env);
417 TaskState *ts = cpu->opaque;
418 struct sigqueue *q = ts->first_free;
419 if (!q)
420 return NULL;
421 ts->first_free = q->next;
422 return q;
425 static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
427 CPUState *cpu = ENV_GET_CPU(env);
428 TaskState *ts = cpu->opaque;
430 q->next = ts->first_free;
431 ts->first_free = q;
434 /* abort execution with signal */
435 static void QEMU_NORETURN force_sig(int target_sig)
437 CPUState *cpu = thread_cpu;
438 CPUArchState *env = cpu->env_ptr;
439 TaskState *ts = (TaskState *)cpu->opaque;
440 int host_sig, core_dumped = 0;
441 struct sigaction act;
442 host_sig = target_to_host_signal(target_sig);
443 gdb_signalled(env, target_sig);
445 /* dump core if supported by target binary format */
446 if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
447 stop_all_tasks();
448 core_dumped =
449 ((*ts->bprm->core_dump)(target_sig, env) == 0);
451 if (core_dumped) {
452 /* we already dumped the core of target process, we don't want
453 * a coredump of qemu itself */
454 struct rlimit nodump;
455 getrlimit(RLIMIT_CORE, &nodump);
456 nodump.rlim_cur=0;
457 setrlimit(RLIMIT_CORE, &nodump);
458 (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
459 target_sig, strsignal(host_sig), "core dumped" );
462 /* The proper exit code for dying from an uncaught signal is
463 * -<signal>. The kernel doesn't allow exit() or _exit() to pass
464 * a negative value. To get the proper exit code we need to
465 * actually die from an uncaught signal. Here the default signal
466 * handler is installed, we send ourself a signal and we wait for
467 * it to arrive. */
468 sigfillset(&act.sa_mask);
469 act.sa_handler = SIG_DFL;
470 act.sa_flags = 0;
471 sigaction(host_sig, &act, NULL);
473 /* For some reason raise(host_sig) doesn't send the signal when
474 * statically linked on x86-64. */
475 kill(getpid(), host_sig);
477 /* Make sure the signal isn't masked (just reuse the mask inside
478 of act) */
479 sigdelset(&act.sa_mask, host_sig);
480 sigsuspend(&act.sa_mask);
482 /* unreachable */
483 abort();
486 /* queue a signal so that it will be send to the virtual CPU as soon
487 as possible */
488 int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
490 CPUState *cpu = ENV_GET_CPU(env);
491 TaskState *ts = cpu->opaque;
492 struct emulated_sigtable *k;
493 struct sigqueue *q, **pq;
494 abi_ulong handler;
495 int queue;
497 #if defined(DEBUG_SIGNAL)
498 fprintf(stderr, "queue_signal: sig=%d\n",
499 sig);
500 #endif
501 k = &ts->sigtab[sig - 1];
502 queue = gdb_queuesig ();
503 handler = sigact_table[sig - 1]._sa_handler;
505 if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {
506 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
507 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
508 * because it got a real MMU fault). A blocked SIGSEGV in that
509 * situation is treated as if using the default handler. This is
510 * not correct if some other process has randomly sent us a SIGSEGV
511 * via kill(), but that is not easy to distinguish at this point,
512 * so we assume it doesn't happen.
514 handler = TARGET_SIG_DFL;
517 if (!queue && handler == TARGET_SIG_DFL) {
518 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
519 kill(getpid(),SIGSTOP);
520 return 0;
521 } else
522 /* default handler : ignore some signal. The other are fatal */
523 if (sig != TARGET_SIGCHLD &&
524 sig != TARGET_SIGURG &&
525 sig != TARGET_SIGWINCH &&
526 sig != TARGET_SIGCONT) {
527 force_sig(sig);
528 } else {
529 return 0; /* indicate ignored */
531 } else if (!queue && handler == TARGET_SIG_IGN) {
532 /* ignore signal */
533 return 0;
534 } else if (!queue && handler == TARGET_SIG_ERR) {
535 force_sig(sig);
536 } else {
537 pq = &k->first;
538 if (sig < TARGET_SIGRTMIN) {
539 /* if non real time signal, we queue exactly one signal */
540 if (!k->pending)
541 q = &k->info;
542 else
543 return 0;
544 } else {
545 if (!k->pending) {
546 /* first signal */
547 q = &k->info;
548 } else {
549 q = alloc_sigqueue(env);
550 if (!q)
551 return -EAGAIN;
552 while (*pq != NULL)
553 pq = &(*pq)->next;
556 *pq = q;
557 q->info = *info;
558 q->next = NULL;
559 k->pending = 1;
560 /* signal that a new signal is pending */
561 ts->signal_pending = 1;
562 return 1; /* indicates that the signal was queued */
566 static void host_signal_handler(int host_signum, siginfo_t *info,
567 void *puc)
569 CPUArchState *env = thread_cpu->env_ptr;
570 int sig;
571 target_siginfo_t tinfo;
573 /* the CPU emulator uses some host signals to detect exceptions,
574 we forward to it some signals */
575 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
576 && info->si_code > 0) {
577 if (cpu_signal_handler(host_signum, info, puc))
578 return;
581 /* get target signal number */
582 sig = host_to_target_signal(host_signum);
583 if (sig < 1 || sig > TARGET_NSIG)
584 return;
585 #if defined(DEBUG_SIGNAL)
586 fprintf(stderr, "qemu: got signal %d\n", sig);
587 #endif
588 host_to_target_siginfo_noswap(&tinfo, info);
589 if (queue_signal(env, sig, &tinfo) == 1) {
590 /* interrupt the virtual CPU as soon as possible */
591 cpu_exit(thread_cpu);
595 /* do_sigaltstack() returns target values and errnos. */
596 /* compare linux/kernel/signal.c:do_sigaltstack() */
597 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
599 int ret;
600 struct target_sigaltstack oss;
602 /* XXX: test errors */
603 if(uoss_addr)
605 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
606 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
607 __put_user(sas_ss_flags(sp), &oss.ss_flags);
610 if(uss_addr)
612 struct target_sigaltstack *uss;
613 struct target_sigaltstack ss;
614 size_t minstacksize = TARGET_MINSIGSTKSZ;
616 #if defined(TARGET_PPC64)
617 /* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
618 struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
619 if (get_ppc64_abi(image) > 1) {
620 minstacksize = 4096;
622 #endif
624 ret = -TARGET_EFAULT;
625 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
626 goto out;
628 __get_user(ss.ss_sp, &uss->ss_sp);
629 __get_user(ss.ss_size, &uss->ss_size);
630 __get_user(ss.ss_flags, &uss->ss_flags);
631 unlock_user_struct(uss, uss_addr, 0);
633 ret = -TARGET_EPERM;
634 if (on_sig_stack(sp))
635 goto out;
637 ret = -TARGET_EINVAL;
638 if (ss.ss_flags != TARGET_SS_DISABLE
639 && ss.ss_flags != TARGET_SS_ONSTACK
640 && ss.ss_flags != 0)
641 goto out;
643 if (ss.ss_flags == TARGET_SS_DISABLE) {
644 ss.ss_size = 0;
645 ss.ss_sp = 0;
646 } else {
647 ret = -TARGET_ENOMEM;
648 if (ss.ss_size < minstacksize) {
649 goto out;
653 target_sigaltstack_used.ss_sp = ss.ss_sp;
654 target_sigaltstack_used.ss_size = ss.ss_size;
657 if (uoss_addr) {
658 ret = -TARGET_EFAULT;
659 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
660 goto out;
663 ret = 0;
664 out:
665 return ret;
668 /* do_sigaction() return host values and errnos */
669 int do_sigaction(int sig, const struct target_sigaction *act,
670 struct target_sigaction *oact)
672 struct target_sigaction *k;
673 struct sigaction act1;
674 int host_sig;
675 int ret = 0;
677 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
678 return -EINVAL;
679 k = &sigact_table[sig - 1];
680 #if defined(DEBUG_SIGNAL)
681 fprintf(stderr, "sigaction sig=%d act=0x%p, oact=0x%p\n",
682 sig, act, oact);
683 #endif
684 if (oact) {
685 __put_user(k->_sa_handler, &oact->_sa_handler);
686 __put_user(k->sa_flags, &oact->sa_flags);
687 #if !defined(TARGET_MIPS)
688 __put_user(k->sa_restorer, &oact->sa_restorer);
689 #endif
690 /* Not swapped. */
691 oact->sa_mask = k->sa_mask;
693 if (act) {
694 /* FIXME: This is not threadsafe. */
695 __get_user(k->_sa_handler, &act->_sa_handler);
696 __get_user(k->sa_flags, &act->sa_flags);
697 #if !defined(TARGET_MIPS)
698 __get_user(k->sa_restorer, &act->sa_restorer);
699 #endif
700 /* To be swapped in target_to_host_sigset. */
701 k->sa_mask = act->sa_mask;
703 /* we update the host linux signal state */
704 host_sig = target_to_host_signal(sig);
705 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
706 sigfillset(&act1.sa_mask);
707 act1.sa_flags = SA_SIGINFO;
708 if (k->sa_flags & TARGET_SA_RESTART)
709 act1.sa_flags |= SA_RESTART;
710 /* NOTE: it is important to update the host kernel signal
711 ignore state to avoid getting unexpected interrupted
712 syscalls */
713 if (k->_sa_handler == TARGET_SIG_IGN) {
714 act1.sa_sigaction = (void *)SIG_IGN;
715 } else if (k->_sa_handler == TARGET_SIG_DFL) {
716 if (fatal_signal (sig))
717 act1.sa_sigaction = host_signal_handler;
718 else
719 act1.sa_sigaction = (void *)SIG_DFL;
720 } else {
721 act1.sa_sigaction = host_signal_handler;
723 ret = sigaction(host_sig, &act1, NULL);
726 return ret;
729 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
731 /* from the Linux kernel */
733 struct target_fpreg {
734 uint16_t significand[4];
735 uint16_t exponent;
738 struct target_fpxreg {
739 uint16_t significand[4];
740 uint16_t exponent;
741 uint16_t padding[3];
744 struct target_xmmreg {
745 abi_ulong element[4];
748 struct target_fpstate {
749 /* Regular FPU environment */
750 abi_ulong cw;
751 abi_ulong sw;
752 abi_ulong tag;
753 abi_ulong ipoff;
754 abi_ulong cssel;
755 abi_ulong dataoff;
756 abi_ulong datasel;
757 struct target_fpreg _st[8];
758 uint16_t status;
759 uint16_t magic; /* 0xffff = regular FPU data only */
761 /* FXSR FPU environment */
762 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
763 abi_ulong mxcsr;
764 abi_ulong reserved;
765 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
766 struct target_xmmreg _xmm[8];
767 abi_ulong padding[56];
770 #define X86_FXSR_MAGIC 0x0000
772 struct target_sigcontext {
773 uint16_t gs, __gsh;
774 uint16_t fs, __fsh;
775 uint16_t es, __esh;
776 uint16_t ds, __dsh;
777 abi_ulong edi;
778 abi_ulong esi;
779 abi_ulong ebp;
780 abi_ulong esp;
781 abi_ulong ebx;
782 abi_ulong edx;
783 abi_ulong ecx;
784 abi_ulong eax;
785 abi_ulong trapno;
786 abi_ulong err;
787 abi_ulong eip;
788 uint16_t cs, __csh;
789 abi_ulong eflags;
790 abi_ulong esp_at_signal;
791 uint16_t ss, __ssh;
792 abi_ulong fpstate; /* pointer */
793 abi_ulong oldmask;
794 abi_ulong cr2;
797 struct target_ucontext {
798 abi_ulong tuc_flags;
799 abi_ulong tuc_link;
800 target_stack_t tuc_stack;
801 struct target_sigcontext tuc_mcontext;
802 target_sigset_t tuc_sigmask; /* mask last for extensibility */
805 struct sigframe
807 abi_ulong pretcode;
808 int sig;
809 struct target_sigcontext sc;
810 struct target_fpstate fpstate;
811 abi_ulong extramask[TARGET_NSIG_WORDS-1];
812 char retcode[8];
815 struct rt_sigframe
817 abi_ulong pretcode;
818 int sig;
819 abi_ulong pinfo;
820 abi_ulong puc;
821 struct target_siginfo info;
822 struct target_ucontext uc;
823 struct target_fpstate fpstate;
824 char retcode[8];
828 * Set up a signal frame.
831 /* XXX: save x87 state */
832 static void setup_sigcontext(struct target_sigcontext *sc,
833 struct target_fpstate *fpstate, CPUX86State *env, abi_ulong mask,
834 abi_ulong fpstate_addr)
836 CPUState *cs = CPU(x86_env_get_cpu(env));
837 uint16_t magic;
839 /* already locked in setup_frame() */
840 __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
841 __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
842 __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
843 __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
844 __put_user(env->regs[R_EDI], &sc->edi);
845 __put_user(env->regs[R_ESI], &sc->esi);
846 __put_user(env->regs[R_EBP], &sc->ebp);
847 __put_user(env->regs[R_ESP], &sc->esp);
848 __put_user(env->regs[R_EBX], &sc->ebx);
849 __put_user(env->regs[R_EDX], &sc->edx);
850 __put_user(env->regs[R_ECX], &sc->ecx);
851 __put_user(env->regs[R_EAX], &sc->eax);
852 __put_user(cs->exception_index, &sc->trapno);
853 __put_user(env->error_code, &sc->err);
854 __put_user(env->eip, &sc->eip);
855 __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
856 __put_user(env->eflags, &sc->eflags);
857 __put_user(env->regs[R_ESP], &sc->esp_at_signal);
858 __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
860 cpu_x86_fsave(env, fpstate_addr, 1);
861 fpstate->status = fpstate->sw;
862 magic = 0xffff;
863 __put_user(magic, &fpstate->magic);
864 __put_user(fpstate_addr, &sc->fpstate);
866 /* non-iBCS2 extensions.. */
867 __put_user(mask, &sc->oldmask);
868 __put_user(env->cr[2], &sc->cr2);
872 * Determine which stack to use..
875 static inline abi_ulong
876 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
878 unsigned long esp;
880 /* Default to using normal stack */
881 esp = env->regs[R_ESP];
882 /* This is the X/Open sanctioned signal stack switching. */
883 if (ka->sa_flags & TARGET_SA_ONSTACK) {
884 if (sas_ss_flags(esp) == 0)
885 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
888 /* This is the legacy signal stack switching. */
889 else
890 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
891 !(ka->sa_flags & TARGET_SA_RESTORER) &&
892 ka->sa_restorer) {
893 esp = (unsigned long) ka->sa_restorer;
895 return (esp - frame_size) & -8ul;
898 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
899 static void setup_frame(int sig, struct target_sigaction *ka,
900 target_sigset_t *set, CPUX86State *env)
902 abi_ulong frame_addr;
903 struct sigframe *frame;
904 int i;
906 frame_addr = get_sigframe(ka, env, sizeof(*frame));
908 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
909 goto give_sigsegv;
911 __put_user(sig, &frame->sig);
913 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
914 frame_addr + offsetof(struct sigframe, fpstate));
916 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
917 __put_user(set->sig[i], &frame->extramask[i - 1]);
920 /* Set up to return from userspace. If provided, use a stub
921 already in userspace. */
922 if (ka->sa_flags & TARGET_SA_RESTORER) {
923 __put_user(ka->sa_restorer, &frame->pretcode);
924 } else {
925 uint16_t val16;
926 abi_ulong retcode_addr;
927 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
928 __put_user(retcode_addr, &frame->pretcode);
929 /* This is popl %eax ; movl $,%eax ; int $0x80 */
930 val16 = 0xb858;
931 __put_user(val16, (uint16_t *)(frame->retcode+0));
932 __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
933 val16 = 0x80cd;
934 __put_user(val16, (uint16_t *)(frame->retcode+6));
938 /* Set up registers for signal handler */
939 env->regs[R_ESP] = frame_addr;
940 env->eip = ka->_sa_handler;
942 cpu_x86_load_seg(env, R_DS, __USER_DS);
943 cpu_x86_load_seg(env, R_ES, __USER_DS);
944 cpu_x86_load_seg(env, R_SS, __USER_DS);
945 cpu_x86_load_seg(env, R_CS, __USER_CS);
946 env->eflags &= ~TF_MASK;
948 unlock_user_struct(frame, frame_addr, 1);
950 return;
952 give_sigsegv:
953 if (sig == TARGET_SIGSEGV)
954 ka->_sa_handler = TARGET_SIG_DFL;
955 force_sig(TARGET_SIGSEGV /* , current */);
958 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
959 static void setup_rt_frame(int sig, struct target_sigaction *ka,
960 target_siginfo_t *info,
961 target_sigset_t *set, CPUX86State *env)
963 abi_ulong frame_addr, addr;
964 struct rt_sigframe *frame;
965 int i;
967 frame_addr = get_sigframe(ka, env, sizeof(*frame));
969 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
970 goto give_sigsegv;
972 __put_user(sig, &frame->sig);
973 addr = frame_addr + offsetof(struct rt_sigframe, info);
974 __put_user(addr, &frame->pinfo);
975 addr = frame_addr + offsetof(struct rt_sigframe, uc);
976 __put_user(addr, &frame->puc);
977 tswap_siginfo(&frame->info, info);
979 /* Create the ucontext. */
980 __put_user(0, &frame->uc.tuc_flags);
981 __put_user(0, &frame->uc.tuc_link);
982 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
983 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
984 &frame->uc.tuc_stack.ss_flags);
985 __put_user(target_sigaltstack_used.ss_size,
986 &frame->uc.tuc_stack.ss_size);
987 setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, env,
988 set->sig[0], frame_addr + offsetof(struct rt_sigframe, fpstate));
990 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
991 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
994 /* Set up to return from userspace. If provided, use a stub
995 already in userspace. */
996 if (ka->sa_flags & TARGET_SA_RESTORER) {
997 __put_user(ka->sa_restorer, &frame->pretcode);
998 } else {
999 uint16_t val16;
1000 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
1001 __put_user(addr, &frame->pretcode);
1002 /* This is movl $,%eax ; int $0x80 */
1003 __put_user(0xb8, (char *)(frame->retcode+0));
1004 __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
1005 val16 = 0x80cd;
1006 __put_user(val16, (uint16_t *)(frame->retcode+5));
1009 /* Set up registers for signal handler */
1010 env->regs[R_ESP] = frame_addr;
1011 env->eip = ka->_sa_handler;
1013 cpu_x86_load_seg(env, R_DS, __USER_DS);
1014 cpu_x86_load_seg(env, R_ES, __USER_DS);
1015 cpu_x86_load_seg(env, R_SS, __USER_DS);
1016 cpu_x86_load_seg(env, R_CS, __USER_CS);
1017 env->eflags &= ~TF_MASK;
1019 unlock_user_struct(frame, frame_addr, 1);
1021 return;
1023 give_sigsegv:
1024 if (sig == TARGET_SIGSEGV)
1025 ka->_sa_handler = TARGET_SIG_DFL;
1026 force_sig(TARGET_SIGSEGV /* , current */);
1029 static int
1030 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
1032 unsigned int err = 0;
1033 abi_ulong fpstate_addr;
1034 unsigned int tmpflags;
1036 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
1037 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
1038 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
1039 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
1041 env->regs[R_EDI] = tswapl(sc->edi);
1042 env->regs[R_ESI] = tswapl(sc->esi);
1043 env->regs[R_EBP] = tswapl(sc->ebp);
1044 env->regs[R_ESP] = tswapl(sc->esp);
1045 env->regs[R_EBX] = tswapl(sc->ebx);
1046 env->regs[R_EDX] = tswapl(sc->edx);
1047 env->regs[R_ECX] = tswapl(sc->ecx);
1048 env->eip = tswapl(sc->eip);
1050 cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
1051 cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
1053 tmpflags = tswapl(sc->eflags);
1054 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
1055 // regs->orig_eax = -1; /* disable syscall checks */
1057 fpstate_addr = tswapl(sc->fpstate);
1058 if (fpstate_addr != 0) {
1059 if (!access_ok(VERIFY_READ, fpstate_addr,
1060 sizeof(struct target_fpstate)))
1061 goto badframe;
1062 cpu_x86_frstor(env, fpstate_addr, 1);
1065 *peax = tswapl(sc->eax);
1066 return err;
1067 badframe:
1068 return 1;
1071 long do_sigreturn(CPUX86State *env)
1073 struct sigframe *frame;
1074 abi_ulong frame_addr = env->regs[R_ESP] - 8;
1075 target_sigset_t target_set;
1076 sigset_t set;
1077 int eax, i;
1079 #if defined(DEBUG_SIGNAL)
1080 fprintf(stderr, "do_sigreturn\n");
1081 #endif
1082 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1083 goto badframe;
1084 /* set blocked signals */
1085 __get_user(target_set.sig[0], &frame->sc.oldmask);
1086 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1087 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
1090 target_to_host_sigset_internal(&set, &target_set);
1091 do_sigprocmask(SIG_SETMASK, &set, NULL);
1093 /* restore registers */
1094 if (restore_sigcontext(env, &frame->sc, &eax))
1095 goto badframe;
1096 unlock_user_struct(frame, frame_addr, 0);
1097 return eax;
1099 badframe:
1100 unlock_user_struct(frame, frame_addr, 0);
1101 force_sig(TARGET_SIGSEGV);
1102 return 0;
1105 long do_rt_sigreturn(CPUX86State *env)
1107 abi_ulong frame_addr;
1108 struct rt_sigframe *frame;
1109 sigset_t set;
1110 int eax;
1112 frame_addr = env->regs[R_ESP] - 4;
1113 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1114 goto badframe;
1115 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1116 do_sigprocmask(SIG_SETMASK, &set, NULL);
1118 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1119 goto badframe;
1121 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1122 get_sp_from_cpustate(env)) == -EFAULT)
1123 goto badframe;
1125 unlock_user_struct(frame, frame_addr, 0);
1126 return eax;
1128 badframe:
1129 unlock_user_struct(frame, frame_addr, 0);
1130 force_sig(TARGET_SIGSEGV);
1131 return 0;
1134 #elif defined(TARGET_AARCH64)
1136 struct target_sigcontext {
1137 uint64_t fault_address;
1138 /* AArch64 registers */
1139 uint64_t regs[31];
1140 uint64_t sp;
1141 uint64_t pc;
1142 uint64_t pstate;
1143 /* 4K reserved for FP/SIMD state and future expansion */
1144 char __reserved[4096] __attribute__((__aligned__(16)));
1147 struct target_ucontext {
1148 abi_ulong tuc_flags;
1149 abi_ulong tuc_link;
1150 target_stack_t tuc_stack;
1151 target_sigset_t tuc_sigmask;
1152 /* glibc uses a 1024-bit sigset_t */
1153 char __unused[1024 / 8 - sizeof(target_sigset_t)];
1154 /* last for future expansion */
1155 struct target_sigcontext tuc_mcontext;
1159 * Header to be used at the beginning of structures extending the user
1160 * context. Such structures must be placed after the rt_sigframe on the stack
1161 * and be 16-byte aligned. The last structure must be a dummy one with the
1162 * magic and size set to 0.
1164 struct target_aarch64_ctx {
1165 uint32_t magic;
1166 uint32_t size;
1169 #define TARGET_FPSIMD_MAGIC 0x46508001
1171 struct target_fpsimd_context {
1172 struct target_aarch64_ctx head;
1173 uint32_t fpsr;
1174 uint32_t fpcr;
1175 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
1179 * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
1180 * user space as it will change with the addition of new context. User space
1181 * should check the magic/size information.
1183 struct target_aux_context {
1184 struct target_fpsimd_context fpsimd;
1185 /* additional context to be added before "end" */
1186 struct target_aarch64_ctx end;
1189 struct target_rt_sigframe {
1190 struct target_siginfo info;
1191 struct target_ucontext uc;
1192 uint64_t fp;
1193 uint64_t lr;
1194 uint32_t tramp[2];
1197 static int target_setup_sigframe(struct target_rt_sigframe *sf,
1198 CPUARMState *env, target_sigset_t *set)
1200 int i;
1201 struct target_aux_context *aux =
1202 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1204 /* set up the stack frame for unwinding */
1205 __put_user(env->xregs[29], &sf->fp);
1206 __put_user(env->xregs[30], &sf->lr);
1208 for (i = 0; i < 31; i++) {
1209 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1211 __put_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1212 __put_user(env->pc, &sf->uc.tuc_mcontext.pc);
1213 __put_user(pstate_read(env), &sf->uc.tuc_mcontext.pstate);
1215 __put_user(env->exception.vaddress, &sf->uc.tuc_mcontext.fault_address);
1217 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
1218 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
1221 for (i = 0; i < 32; i++) {
1222 #ifdef TARGET_WORDS_BIGENDIAN
1223 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1224 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1225 #else
1226 __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1227 __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1228 #endif
1230 __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
1231 __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
1232 __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
1233 __put_user(sizeof(struct target_fpsimd_context),
1234 &aux->fpsimd.head.size);
1236 /* set the "end" magic */
1237 __put_user(0, &aux->end.magic);
1238 __put_user(0, &aux->end.size);
1240 return 0;
1243 static int target_restore_sigframe(CPUARMState *env,
1244 struct target_rt_sigframe *sf)
1246 sigset_t set;
1247 int i;
1248 struct target_aux_context *aux =
1249 (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
1250 uint32_t magic, size, fpsr, fpcr;
1251 uint64_t pstate;
1253 target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1254 do_sigprocmask(SIG_SETMASK, &set, NULL);
1256 for (i = 0; i < 31; i++) {
1257 __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
1260 __get_user(env->xregs[31], &sf->uc.tuc_mcontext.sp);
1261 __get_user(env->pc, &sf->uc.tuc_mcontext.pc);
1262 __get_user(pstate, &sf->uc.tuc_mcontext.pstate);
1263 pstate_write(env, pstate);
1265 __get_user(magic, &aux->fpsimd.head.magic);
1266 __get_user(size, &aux->fpsimd.head.size);
1268 if (magic != TARGET_FPSIMD_MAGIC
1269 || size != sizeof(struct target_fpsimd_context)) {
1270 return 1;
1273 for (i = 0; i < 32; i++) {
1274 #ifdef TARGET_WORDS_BIGENDIAN
1275 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
1276 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
1277 #else
1278 __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
1279 __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
1280 #endif
1282 __get_user(fpsr, &aux->fpsimd.fpsr);
1283 vfp_set_fpsr(env, fpsr);
1284 __get_user(fpcr, &aux->fpsimd.fpcr);
1285 vfp_set_fpcr(env, fpcr);
1287 return 0;
1290 static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
1292 abi_ulong sp;
1294 sp = env->xregs[31];
1297 * This is the X/Open sanctioned signal stack switching.
1299 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
1300 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1303 sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
1305 return sp;
1308 static void target_setup_frame(int usig, struct target_sigaction *ka,
1309 target_siginfo_t *info, target_sigset_t *set,
1310 CPUARMState *env)
1312 struct target_rt_sigframe *frame;
1313 abi_ulong frame_addr, return_addr;
1315 frame_addr = get_sigframe(ka, env);
1316 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
1317 goto give_sigsegv;
1320 __put_user(0, &frame->uc.tuc_flags);
1321 __put_user(0, &frame->uc.tuc_link);
1323 __put_user(target_sigaltstack_used.ss_sp,
1324 &frame->uc.tuc_stack.ss_sp);
1325 __put_user(sas_ss_flags(env->xregs[31]),
1326 &frame->uc.tuc_stack.ss_flags);
1327 __put_user(target_sigaltstack_used.ss_size,
1328 &frame->uc.tuc_stack.ss_size);
1329 target_setup_sigframe(frame, env, set);
1330 if (ka->sa_flags & TARGET_SA_RESTORER) {
1331 return_addr = ka->sa_restorer;
1332 } else {
1333 /* mov x8,#__NR_rt_sigreturn; svc #0 */
1334 __put_user(0xd2801168, &frame->tramp[0]);
1335 __put_user(0xd4000001, &frame->tramp[1]);
1336 return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
1338 env->xregs[0] = usig;
1339 env->xregs[31] = frame_addr;
1340 env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
1341 env->pc = ka->_sa_handler;
1342 env->xregs[30] = return_addr;
1343 if (info) {
1344 tswap_siginfo(&frame->info, info);
1345 env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
1346 env->xregs[2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
1349 unlock_user_struct(frame, frame_addr, 1);
1350 return;
1352 give_sigsegv:
1353 unlock_user_struct(frame, frame_addr, 1);
1354 force_sig(TARGET_SIGSEGV);
1357 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1358 target_siginfo_t *info, target_sigset_t *set,
1359 CPUARMState *env)
1361 target_setup_frame(sig, ka, info, set, env);
1364 static void setup_frame(int sig, struct target_sigaction *ka,
1365 target_sigset_t *set, CPUARMState *env)
1367 target_setup_frame(sig, ka, 0, set, env);
1370 long do_rt_sigreturn(CPUARMState *env)
1372 struct target_rt_sigframe *frame = NULL;
1373 abi_ulong frame_addr = env->xregs[31];
1375 if (frame_addr & 15) {
1376 goto badframe;
1379 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
1380 goto badframe;
1383 if (target_restore_sigframe(env, frame)) {
1384 goto badframe;
1387 if (do_sigaltstack(frame_addr +
1388 offsetof(struct target_rt_sigframe, uc.tuc_stack),
1389 0, get_sp_from_cpustate(env)) == -EFAULT) {
1390 goto badframe;
1393 unlock_user_struct(frame, frame_addr, 0);
1394 return env->xregs[0];
1396 badframe:
1397 unlock_user_struct(frame, frame_addr, 0);
1398 force_sig(TARGET_SIGSEGV);
1399 return 0;
1402 long do_sigreturn(CPUARMState *env)
1404 return do_rt_sigreturn(env);
1407 #elif defined(TARGET_ARM)
1409 struct target_sigcontext {
1410 abi_ulong trap_no;
1411 abi_ulong error_code;
1412 abi_ulong oldmask;
1413 abi_ulong arm_r0;
1414 abi_ulong arm_r1;
1415 abi_ulong arm_r2;
1416 abi_ulong arm_r3;
1417 abi_ulong arm_r4;
1418 abi_ulong arm_r5;
1419 abi_ulong arm_r6;
1420 abi_ulong arm_r7;
1421 abi_ulong arm_r8;
1422 abi_ulong arm_r9;
1423 abi_ulong arm_r10;
1424 abi_ulong arm_fp;
1425 abi_ulong arm_ip;
1426 abi_ulong arm_sp;
1427 abi_ulong arm_lr;
1428 abi_ulong arm_pc;
1429 abi_ulong arm_cpsr;
1430 abi_ulong fault_address;
1433 struct target_ucontext_v1 {
1434 abi_ulong tuc_flags;
1435 abi_ulong tuc_link;
1436 target_stack_t tuc_stack;
1437 struct target_sigcontext tuc_mcontext;
1438 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1441 struct target_ucontext_v2 {
1442 abi_ulong tuc_flags;
1443 abi_ulong tuc_link;
1444 target_stack_t tuc_stack;
1445 struct target_sigcontext tuc_mcontext;
1446 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1447 char __unused[128 - sizeof(target_sigset_t)];
1448 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1451 struct target_user_vfp {
1452 uint64_t fpregs[32];
1453 abi_ulong fpscr;
1456 struct target_user_vfp_exc {
1457 abi_ulong fpexc;
1458 abi_ulong fpinst;
1459 abi_ulong fpinst2;
1462 struct target_vfp_sigframe {
1463 abi_ulong magic;
1464 abi_ulong size;
1465 struct target_user_vfp ufp;
1466 struct target_user_vfp_exc ufp_exc;
1467 } __attribute__((__aligned__(8)));
1469 struct target_iwmmxt_sigframe {
1470 abi_ulong magic;
1471 abi_ulong size;
1472 uint64_t regs[16];
1473 /* Note that not all the coprocessor control registers are stored here */
1474 uint32_t wcssf;
1475 uint32_t wcasf;
1476 uint32_t wcgr0;
1477 uint32_t wcgr1;
1478 uint32_t wcgr2;
1479 uint32_t wcgr3;
1480 } __attribute__((__aligned__(8)));
1482 #define TARGET_VFP_MAGIC 0x56465001
1483 #define TARGET_IWMMXT_MAGIC 0x12ef842a
1485 struct sigframe_v1
1487 struct target_sigcontext sc;
1488 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1489 abi_ulong retcode;
1492 struct sigframe_v2
1494 struct target_ucontext_v2 uc;
1495 abi_ulong retcode;
1498 struct rt_sigframe_v1
1500 abi_ulong pinfo;
1501 abi_ulong puc;
1502 struct target_siginfo info;
1503 struct target_ucontext_v1 uc;
1504 abi_ulong retcode;
1507 struct rt_sigframe_v2
1509 struct target_siginfo info;
1510 struct target_ucontext_v2 uc;
1511 abi_ulong retcode;
1514 #define TARGET_CONFIG_CPU_32 1
1517 * For ARM syscalls, we encode the syscall number into the instruction.
1519 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1520 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1523 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1524 * need two 16-bit instructions.
1526 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1527 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1529 static const abi_ulong retcodes[4] = {
1530 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1531 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1535 static inline int valid_user_regs(CPUARMState *regs)
1537 return 1;
1540 static void
1541 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1542 CPUARMState *env, abi_ulong mask)
1544 __put_user(env->regs[0], &sc->arm_r0);
1545 __put_user(env->regs[1], &sc->arm_r1);
1546 __put_user(env->regs[2], &sc->arm_r2);
1547 __put_user(env->regs[3], &sc->arm_r3);
1548 __put_user(env->regs[4], &sc->arm_r4);
1549 __put_user(env->regs[5], &sc->arm_r5);
1550 __put_user(env->regs[6], &sc->arm_r6);
1551 __put_user(env->regs[7], &sc->arm_r7);
1552 __put_user(env->regs[8], &sc->arm_r8);
1553 __put_user(env->regs[9], &sc->arm_r9);
1554 __put_user(env->regs[10], &sc->arm_r10);
1555 __put_user(env->regs[11], &sc->arm_fp);
1556 __put_user(env->regs[12], &sc->arm_ip);
1557 __put_user(env->regs[13], &sc->arm_sp);
1558 __put_user(env->regs[14], &sc->arm_lr);
1559 __put_user(env->regs[15], &sc->arm_pc);
1560 #ifdef TARGET_CONFIG_CPU_32
1561 __put_user(cpsr_read(env), &sc->arm_cpsr);
1562 #endif
1564 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1565 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1566 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1567 __put_user(mask, &sc->oldmask);
1570 static inline abi_ulong
1571 get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
1573 unsigned long sp = regs->regs[13];
1576 * This is the X/Open sanctioned signal stack switching.
1578 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
1579 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1582 * ATPCS B01 mandates 8-byte alignment
1584 return (sp - framesize) & ~7;
1587 static void
1588 setup_return(CPUARMState *env, struct target_sigaction *ka,
1589 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1591 abi_ulong handler = ka->_sa_handler;
1592 abi_ulong retcode;
1593 int thumb = handler & 1;
1594 uint32_t cpsr = cpsr_read(env);
1596 cpsr &= ~CPSR_IT;
1597 if (thumb) {
1598 cpsr |= CPSR_T;
1599 } else {
1600 cpsr &= ~CPSR_T;
1603 if (ka->sa_flags & TARGET_SA_RESTORER) {
1604 retcode = ka->sa_restorer;
1605 } else {
1606 unsigned int idx = thumb;
1608 if (ka->sa_flags & TARGET_SA_SIGINFO) {
1609 idx += 2;
1612 __put_user(retcodes[idx], rc);
1614 retcode = rc_addr + thumb;
1617 env->regs[0] = usig;
1618 env->regs[13] = frame_addr;
1619 env->regs[14] = retcode;
1620 env->regs[15] = handler & (thumb ? ~1 : ~3);
1621 cpsr_write(env, cpsr, 0xffffffff);
1624 static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
1626 int i;
1627 struct target_vfp_sigframe *vfpframe;
1628 vfpframe = (struct target_vfp_sigframe *)regspace;
1629 __put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
1630 __put_user(sizeof(*vfpframe), &vfpframe->size);
1631 for (i = 0; i < 32; i++) {
1632 __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1634 __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
1635 __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
1636 __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1637 __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1638 return (abi_ulong*)(vfpframe+1);
1641 static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace,
1642 CPUARMState *env)
1644 int i;
1645 struct target_iwmmxt_sigframe *iwmmxtframe;
1646 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1647 __put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
1648 __put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
1649 for (i = 0; i < 16; i++) {
1650 __put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1652 __put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1653 __put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1654 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1655 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1656 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1657 __put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1658 return (abi_ulong*)(iwmmxtframe+1);
1661 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1662 target_sigset_t *set, CPUARMState *env)
1664 struct target_sigaltstack stack;
1665 int i;
1666 abi_ulong *regspace;
1668 /* Clear all the bits of the ucontext we don't use. */
1669 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1671 memset(&stack, 0, sizeof(stack));
1672 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1673 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1674 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1675 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1677 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1678 /* Save coprocessor signal frame. */
1679 regspace = uc->tuc_regspace;
1680 if (arm_feature(env, ARM_FEATURE_VFP)) {
1681 regspace = setup_sigframe_v2_vfp(regspace, env);
1683 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1684 regspace = setup_sigframe_v2_iwmmxt(regspace, env);
1687 /* Write terminating magic word */
1688 __put_user(0, regspace);
1690 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1691 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1695 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1696 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1697 target_sigset_t *set, CPUARMState *regs)
1699 struct sigframe_v1 *frame;
1700 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1701 int i;
1703 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1704 return;
1706 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1708 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1709 __put_user(set->sig[i], &frame->extramask[i - 1]);
1712 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1713 frame_addr + offsetof(struct sigframe_v1, retcode));
1715 unlock_user_struct(frame, frame_addr, 1);
1718 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1719 target_sigset_t *set, CPUARMState *regs)
1721 struct sigframe_v2 *frame;
1722 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1724 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1725 return;
1727 setup_sigframe_v2(&frame->uc, set, regs);
1729 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1730 frame_addr + offsetof(struct sigframe_v2, retcode));
1732 unlock_user_struct(frame, frame_addr, 1);
1735 static void setup_frame(int usig, struct target_sigaction *ka,
1736 target_sigset_t *set, CPUARMState *regs)
1738 if (get_osversion() >= 0x020612) {
1739 setup_frame_v2(usig, ka, set, regs);
1740 } else {
1741 setup_frame_v1(usig, ka, set, regs);
1745 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1746 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1747 target_siginfo_t *info,
1748 target_sigset_t *set, CPUARMState *env)
1750 struct rt_sigframe_v1 *frame;
1751 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1752 struct target_sigaltstack stack;
1753 int i;
1754 abi_ulong info_addr, uc_addr;
1756 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1757 return /* 1 */;
1759 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1760 __put_user(info_addr, &frame->pinfo);
1761 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1762 __put_user(uc_addr, &frame->puc);
1763 tswap_siginfo(&frame->info, info);
1765 /* Clear all the bits of the ucontext we don't use. */
1766 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1768 memset(&stack, 0, sizeof(stack));
1769 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1770 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1771 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1772 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1774 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1775 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1776 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
1779 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1780 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1782 env->regs[1] = info_addr;
1783 env->regs[2] = uc_addr;
1785 unlock_user_struct(frame, frame_addr, 1);
1788 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1789 target_siginfo_t *info,
1790 target_sigset_t *set, CPUARMState *env)
1792 struct rt_sigframe_v2 *frame;
1793 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1794 abi_ulong info_addr, uc_addr;
1796 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1797 return /* 1 */;
1799 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1800 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1801 tswap_siginfo(&frame->info, info);
1803 setup_sigframe_v2(&frame->uc, set, env);
1805 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1806 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1808 env->regs[1] = info_addr;
1809 env->regs[2] = uc_addr;
1811 unlock_user_struct(frame, frame_addr, 1);
1814 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1815 target_siginfo_t *info,
1816 target_sigset_t *set, CPUARMState *env)
1818 if (get_osversion() >= 0x020612) {
1819 setup_rt_frame_v2(usig, ka, info, set, env);
1820 } else {
1821 setup_rt_frame_v1(usig, ka, info, set, env);
1825 static int
1826 restore_sigcontext(CPUARMState *env, struct target_sigcontext *sc)
1828 int err = 0;
1829 uint32_t cpsr;
1831 __get_user(env->regs[0], &sc->arm_r0);
1832 __get_user(env->regs[1], &sc->arm_r1);
1833 __get_user(env->regs[2], &sc->arm_r2);
1834 __get_user(env->regs[3], &sc->arm_r3);
1835 __get_user(env->regs[4], &sc->arm_r4);
1836 __get_user(env->regs[5], &sc->arm_r5);
1837 __get_user(env->regs[6], &sc->arm_r6);
1838 __get_user(env->regs[7], &sc->arm_r7);
1839 __get_user(env->regs[8], &sc->arm_r8);
1840 __get_user(env->regs[9], &sc->arm_r9);
1841 __get_user(env->regs[10], &sc->arm_r10);
1842 __get_user(env->regs[11], &sc->arm_fp);
1843 __get_user(env->regs[12], &sc->arm_ip);
1844 __get_user(env->regs[13], &sc->arm_sp);
1845 __get_user(env->regs[14], &sc->arm_lr);
1846 __get_user(env->regs[15], &sc->arm_pc);
1847 #ifdef TARGET_CONFIG_CPU_32
1848 __get_user(cpsr, &sc->arm_cpsr);
1849 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1850 #endif
1852 err |= !valid_user_regs(env);
1854 return err;
1857 static long do_sigreturn_v1(CPUARMState *env)
1859 abi_ulong frame_addr;
1860 struct sigframe_v1 *frame = NULL;
1861 target_sigset_t set;
1862 sigset_t host_set;
1863 int i;
1866 * Since we stacked the signal on a 64-bit boundary,
1867 * then 'sp' should be word aligned here. If it's
1868 * not, then the user is trying to mess with us.
1870 frame_addr = env->regs[13];
1871 if (frame_addr & 7) {
1872 goto badframe;
1875 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1876 goto badframe;
1878 __get_user(set.sig[0], &frame->sc.oldmask);
1879 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1880 __get_user(set.sig[i], &frame->extramask[i - 1]);
1883 target_to_host_sigset_internal(&host_set, &set);
1884 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
1886 if (restore_sigcontext(env, &frame->sc))
1887 goto badframe;
1889 #if 0
1890 /* Send SIGTRAP if we're single-stepping */
1891 if (ptrace_cancel_bpt(current))
1892 send_sig(SIGTRAP, current, 1);
1893 #endif
1894 unlock_user_struct(frame, frame_addr, 0);
1895 return env->regs[0];
1897 badframe:
1898 force_sig(TARGET_SIGSEGV /* , current */);
1899 return 0;
1902 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
1904 int i;
1905 abi_ulong magic, sz;
1906 uint32_t fpscr, fpexc;
1907 struct target_vfp_sigframe *vfpframe;
1908 vfpframe = (struct target_vfp_sigframe *)regspace;
1910 __get_user(magic, &vfpframe->magic);
1911 __get_user(sz, &vfpframe->size);
1912 if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
1913 return 0;
1915 for (i = 0; i < 32; i++) {
1916 __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
1918 __get_user(fpscr, &vfpframe->ufp.fpscr);
1919 vfp_set_fpscr(env, fpscr);
1920 __get_user(fpexc, &vfpframe->ufp_exc.fpexc);
1921 /* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
1922 * and the exception flag is cleared
1924 fpexc |= (1 << 30);
1925 fpexc &= ~((1 << 31) | (1 << 28));
1926 env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
1927 __get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
1928 __get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
1929 return (abi_ulong*)(vfpframe + 1);
1932 static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
1933 abi_ulong *regspace)
1935 int i;
1936 abi_ulong magic, sz;
1937 struct target_iwmmxt_sigframe *iwmmxtframe;
1938 iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
1940 __get_user(magic, &iwmmxtframe->magic);
1941 __get_user(sz, &iwmmxtframe->size);
1942 if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
1943 return 0;
1945 for (i = 0; i < 16; i++) {
1946 __get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
1948 __get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
1949 __get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
1950 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
1951 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
1952 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
1953 __get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
1954 return (abi_ulong*)(iwmmxtframe + 1);
1957 static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
1958 struct target_ucontext_v2 *uc)
1960 sigset_t host_set;
1961 abi_ulong *regspace;
1963 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1964 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
1966 if (restore_sigcontext(env, &uc->tuc_mcontext))
1967 return 1;
1969 /* Restore coprocessor signal frame */
1970 regspace = uc->tuc_regspace;
1971 if (arm_feature(env, ARM_FEATURE_VFP)) {
1972 regspace = restore_sigframe_v2_vfp(env, regspace);
1973 if (!regspace) {
1974 return 1;
1977 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1978 regspace = restore_sigframe_v2_iwmmxt(env, regspace);
1979 if (!regspace) {
1980 return 1;
1984 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1985 return 1;
1987 #if 0
1988 /* Send SIGTRAP if we're single-stepping */
1989 if (ptrace_cancel_bpt(current))
1990 send_sig(SIGTRAP, current, 1);
1991 #endif
1993 return 0;
1996 static long do_sigreturn_v2(CPUARMState *env)
1998 abi_ulong frame_addr;
1999 struct sigframe_v2 *frame = NULL;
2002 * Since we stacked the signal on a 64-bit boundary,
2003 * then 'sp' should be word aligned here. If it's
2004 * not, then the user is trying to mess with us.
2006 frame_addr = env->regs[13];
2007 if (frame_addr & 7) {
2008 goto badframe;
2011 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2012 goto badframe;
2014 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2015 goto badframe;
2017 unlock_user_struct(frame, frame_addr, 0);
2018 return env->regs[0];
2020 badframe:
2021 unlock_user_struct(frame, frame_addr, 0);
2022 force_sig(TARGET_SIGSEGV /* , current */);
2023 return 0;
2026 long do_sigreturn(CPUARMState *env)
2028 if (get_osversion() >= 0x020612) {
2029 return do_sigreturn_v2(env);
2030 } else {
2031 return do_sigreturn_v1(env);
2035 static long do_rt_sigreturn_v1(CPUARMState *env)
2037 abi_ulong frame_addr;
2038 struct rt_sigframe_v1 *frame = NULL;
2039 sigset_t host_set;
2042 * Since we stacked the signal on a 64-bit boundary,
2043 * then 'sp' should be word aligned here. If it's
2044 * not, then the user is trying to mess with us.
2046 frame_addr = env->regs[13];
2047 if (frame_addr & 7) {
2048 goto badframe;
2051 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2052 goto badframe;
2054 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
2055 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
2057 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
2058 goto badframe;
2060 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
2061 goto badframe;
2063 #if 0
2064 /* Send SIGTRAP if we're single-stepping */
2065 if (ptrace_cancel_bpt(current))
2066 send_sig(SIGTRAP, current, 1);
2067 #endif
2068 unlock_user_struct(frame, frame_addr, 0);
2069 return env->regs[0];
2071 badframe:
2072 unlock_user_struct(frame, frame_addr, 0);
2073 force_sig(TARGET_SIGSEGV /* , current */);
2074 return 0;
2077 static long do_rt_sigreturn_v2(CPUARMState *env)
2079 abi_ulong frame_addr;
2080 struct rt_sigframe_v2 *frame = NULL;
2083 * Since we stacked the signal on a 64-bit boundary,
2084 * then 'sp' should be word aligned here. If it's
2085 * not, then the user is trying to mess with us.
2087 frame_addr = env->regs[13];
2088 if (frame_addr & 7) {
2089 goto badframe;
2092 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2093 goto badframe;
2095 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
2096 goto badframe;
2098 unlock_user_struct(frame, frame_addr, 0);
2099 return env->regs[0];
2101 badframe:
2102 unlock_user_struct(frame, frame_addr, 0);
2103 force_sig(TARGET_SIGSEGV /* , current */);
2104 return 0;
2107 long do_rt_sigreturn(CPUARMState *env)
2109 if (get_osversion() >= 0x020612) {
2110 return do_rt_sigreturn_v2(env);
2111 } else {
2112 return do_rt_sigreturn_v1(env);
2116 #elif defined(TARGET_SPARC)
2118 #define __SUNOS_MAXWIN 31
2120 /* This is what SunOS does, so shall I. */
2121 struct target_sigcontext {
2122 abi_ulong sigc_onstack; /* state to restore */
2124 abi_ulong sigc_mask; /* sigmask to restore */
2125 abi_ulong sigc_sp; /* stack pointer */
2126 abi_ulong sigc_pc; /* program counter */
2127 abi_ulong sigc_npc; /* next program counter */
2128 abi_ulong sigc_psr; /* for condition codes etc */
2129 abi_ulong sigc_g1; /* User uses these two registers */
2130 abi_ulong sigc_o0; /* within the trampoline code. */
2132 /* Now comes information regarding the users window set
2133 * at the time of the signal.
2135 abi_ulong sigc_oswins; /* outstanding windows */
2137 /* stack ptrs for each regwin buf */
2138 char *sigc_spbuf[__SUNOS_MAXWIN];
2140 /* Windows to restore after signal */
2141 struct {
2142 abi_ulong locals[8];
2143 abi_ulong ins[8];
2144 } sigc_wbuf[__SUNOS_MAXWIN];
2146 /* A Sparc stack frame */
2147 struct sparc_stackf {
2148 abi_ulong locals[8];
2149 abi_ulong ins[8];
2150 /* It's simpler to treat fp and callers_pc as elements of ins[]
2151 * since we never need to access them ourselves.
2153 char *structptr;
2154 abi_ulong xargs[6];
2155 abi_ulong xxargs[1];
2158 typedef struct {
2159 struct {
2160 abi_ulong psr;
2161 abi_ulong pc;
2162 abi_ulong npc;
2163 abi_ulong y;
2164 abi_ulong u_regs[16]; /* globals and ins */
2165 } si_regs;
2166 int si_mask;
2167 } __siginfo_t;
2169 typedef struct {
2170 abi_ulong si_float_regs[32];
2171 unsigned long si_fsr;
2172 unsigned long si_fpqdepth;
2173 struct {
2174 unsigned long *insn_addr;
2175 unsigned long insn;
2176 } si_fpqueue [16];
2177 } qemu_siginfo_fpu_t;
2180 struct target_signal_frame {
2181 struct sparc_stackf ss;
2182 __siginfo_t info;
2183 abi_ulong fpu_save;
2184 abi_ulong insns[2] __attribute__ ((aligned (8)));
2185 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
2186 abi_ulong extra_size; /* Should be 0 */
2187 qemu_siginfo_fpu_t fpu_state;
2189 struct target_rt_signal_frame {
2190 struct sparc_stackf ss;
2191 siginfo_t info;
2192 abi_ulong regs[20];
2193 sigset_t mask;
2194 abi_ulong fpu_save;
2195 unsigned int insns[2];
2196 stack_t stack;
2197 unsigned int extra_size; /* Should be 0 */
2198 qemu_siginfo_fpu_t fpu_state;
2201 #define UREG_O0 16
2202 #define UREG_O6 22
2203 #define UREG_I0 0
2204 #define UREG_I1 1
2205 #define UREG_I2 2
2206 #define UREG_I3 3
2207 #define UREG_I4 4
2208 #define UREG_I5 5
2209 #define UREG_I6 6
2210 #define UREG_I7 7
2211 #define UREG_L0 8
2212 #define UREG_FP UREG_I6
2213 #define UREG_SP UREG_O6
2215 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
2216 CPUSPARCState *env,
2217 unsigned long framesize)
2219 abi_ulong sp;
2221 sp = env->regwptr[UREG_FP];
2223 /* This is the X/Open sanctioned signal stack switching. */
2224 if (sa->sa_flags & TARGET_SA_ONSTACK) {
2225 if (!on_sig_stack(sp)
2226 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
2227 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2229 return sp - framesize;
2232 static int
2233 setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
2235 int err = 0, i;
2237 __put_user(env->psr, &si->si_regs.psr);
2238 __put_user(env->pc, &si->si_regs.pc);
2239 __put_user(env->npc, &si->si_regs.npc);
2240 __put_user(env->y, &si->si_regs.y);
2241 for (i=0; i < 8; i++) {
2242 __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
2244 for (i=0; i < 8; i++) {
2245 __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
2247 __put_user(mask, &si->si_mask);
2248 return err;
2251 #if 0
2252 static int
2253 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
2254 CPUSPARCState *env, unsigned long mask)
2256 int err = 0;
2258 __put_user(mask, &sc->sigc_mask);
2259 __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
2260 __put_user(env->pc, &sc->sigc_pc);
2261 __put_user(env->npc, &sc->sigc_npc);
2262 __put_user(env->psr, &sc->sigc_psr);
2263 __put_user(env->gregs[1], &sc->sigc_g1);
2264 __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
2266 return err;
2268 #endif
2269 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
2271 static void setup_frame(int sig, struct target_sigaction *ka,
2272 target_sigset_t *set, CPUSPARCState *env)
2274 abi_ulong sf_addr;
2275 struct target_signal_frame *sf;
2276 int sigframe_size, err, i;
2278 /* 1. Make sure everything is clean */
2279 //synchronize_user_stack();
2281 sigframe_size = NF_ALIGNEDSZ;
2282 sf_addr = get_sigframe(ka, env, sigframe_size);
2284 sf = lock_user(VERIFY_WRITE, sf_addr,
2285 sizeof(struct target_signal_frame), 0);
2286 if (!sf)
2287 goto sigsegv;
2289 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2290 #if 0
2291 if (invalid_frame_pointer(sf, sigframe_size))
2292 goto sigill_and_return;
2293 #endif
2294 /* 2. Save the current process state */
2295 err = setup___siginfo(&sf->info, env, set->sig[0]);
2296 __put_user(0, &sf->extra_size);
2298 //save_fpu_state(regs, &sf->fpu_state);
2299 //__put_user(&sf->fpu_state, &sf->fpu_save);
2301 __put_user(set->sig[0], &sf->info.si_mask);
2302 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2303 __put_user(set->sig[i + 1], &sf->extramask[i]);
2306 for (i = 0; i < 8; i++) {
2307 __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
2309 for (i = 0; i < 8; i++) {
2310 __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
2312 if (err)
2313 goto sigsegv;
2315 /* 3. signal handler back-trampoline and parameters */
2316 env->regwptr[UREG_FP] = sf_addr;
2317 env->regwptr[UREG_I0] = sig;
2318 env->regwptr[UREG_I1] = sf_addr +
2319 offsetof(struct target_signal_frame, info);
2320 env->regwptr[UREG_I2] = sf_addr +
2321 offsetof(struct target_signal_frame, info);
2323 /* 4. signal handler */
2324 env->pc = ka->_sa_handler;
2325 env->npc = (env->pc + 4);
2326 /* 5. return to kernel instructions */
2327 if (ka->sa_restorer)
2328 env->regwptr[UREG_I7] = ka->sa_restorer;
2329 else {
2330 uint32_t val32;
2332 env->regwptr[UREG_I7] = sf_addr +
2333 offsetof(struct target_signal_frame, insns) - 2 * 4;
2335 /* mov __NR_sigreturn, %g1 */
2336 val32 = 0x821020d8;
2337 __put_user(val32, &sf->insns[0]);
2339 /* t 0x10 */
2340 val32 = 0x91d02010;
2341 __put_user(val32, &sf->insns[1]);
2342 if (err)
2343 goto sigsegv;
2345 /* Flush instruction space. */
2346 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
2347 // tb_flush(env);
2349 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2350 return;
2351 #if 0
2352 sigill_and_return:
2353 force_sig(TARGET_SIGILL);
2354 #endif
2355 sigsegv:
2356 //fprintf(stderr, "force_sig\n");
2357 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
2358 force_sig(TARGET_SIGSEGV);
2361 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2362 target_siginfo_t *info,
2363 target_sigset_t *set, CPUSPARCState *env)
2365 fprintf(stderr, "setup_rt_frame: not implemented\n");
2368 long do_sigreturn(CPUSPARCState *env)
2370 abi_ulong sf_addr;
2371 struct target_signal_frame *sf;
2372 uint32_t up_psr, pc, npc;
2373 target_sigset_t set;
2374 sigset_t host_set;
2375 int err=0, i;
2377 sf_addr = env->regwptr[UREG_FP];
2378 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
2379 goto segv_and_exit;
2380 #if 0
2381 fprintf(stderr, "sigreturn\n");
2382 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
2383 #endif
2384 //cpu_dump_state(env, stderr, fprintf, 0);
2386 /* 1. Make sure we are not getting garbage from the user */
2388 if (sf_addr & 3)
2389 goto segv_and_exit;
2391 __get_user(pc, &sf->info.si_regs.pc);
2392 __get_user(npc, &sf->info.si_regs.npc);
2394 if ((pc | npc) & 3)
2395 goto segv_and_exit;
2397 /* 2. Restore the state */
2398 __get_user(up_psr, &sf->info.si_regs.psr);
2400 /* User can only change condition codes and FPU enabling in %psr. */
2401 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
2402 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
2404 env->pc = pc;
2405 env->npc = npc;
2406 __get_user(env->y, &sf->info.si_regs.y);
2407 for (i=0; i < 8; i++) {
2408 __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
2410 for (i=0; i < 8; i++) {
2411 __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
2414 /* FIXME: implement FPU save/restore:
2415 * __get_user(fpu_save, &sf->fpu_save);
2416 * if (fpu_save)
2417 * err |= restore_fpu_state(env, fpu_save);
2420 /* This is pretty much atomic, no amount locking would prevent
2421 * the races which exist anyways.
2423 __get_user(set.sig[0], &sf->info.si_mask);
2424 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2425 __get_user(set.sig[i], &sf->extramask[i - 1]);
2428 target_to_host_sigset_internal(&host_set, &set);
2429 do_sigprocmask(SIG_SETMASK, &host_set, NULL);
2431 if (err)
2432 goto segv_and_exit;
2433 unlock_user_struct(sf, sf_addr, 0);
2434 return env->regwptr[0];
2436 segv_and_exit:
2437 unlock_user_struct(sf, sf_addr, 0);
2438 force_sig(TARGET_SIGSEGV);
2441 long do_rt_sigreturn(CPUSPARCState *env)
2443 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2444 return -TARGET_ENOSYS;
2447 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
2448 #define MC_TSTATE 0
2449 #define MC_PC 1
2450 #define MC_NPC 2
2451 #define MC_Y 3
2452 #define MC_G1 4
2453 #define MC_G2 5
2454 #define MC_G3 6
2455 #define MC_G4 7
2456 #define MC_G5 8
2457 #define MC_G6 9
2458 #define MC_G7 10
2459 #define MC_O0 11
2460 #define MC_O1 12
2461 #define MC_O2 13
2462 #define MC_O3 14
2463 #define MC_O4 15
2464 #define MC_O5 16
2465 #define MC_O6 17
2466 #define MC_O7 18
2467 #define MC_NGREG 19
2469 typedef abi_ulong target_mc_greg_t;
2470 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
2472 struct target_mc_fq {
2473 abi_ulong *mcfq_addr;
2474 uint32_t mcfq_insn;
2477 struct target_mc_fpu {
2478 union {
2479 uint32_t sregs[32];
2480 uint64_t dregs[32];
2481 //uint128_t qregs[16];
2482 } mcfpu_fregs;
2483 abi_ulong mcfpu_fsr;
2484 abi_ulong mcfpu_fprs;
2485 abi_ulong mcfpu_gsr;
2486 struct target_mc_fq *mcfpu_fq;
2487 unsigned char mcfpu_qcnt;
2488 unsigned char mcfpu_qentsz;
2489 unsigned char mcfpu_enab;
2491 typedef struct target_mc_fpu target_mc_fpu_t;
2493 typedef struct {
2494 target_mc_gregset_t mc_gregs;
2495 target_mc_greg_t mc_fp;
2496 target_mc_greg_t mc_i7;
2497 target_mc_fpu_t mc_fpregs;
2498 } target_mcontext_t;
2500 struct target_ucontext {
2501 struct target_ucontext *tuc_link;
2502 abi_ulong tuc_flags;
2503 target_sigset_t tuc_sigmask;
2504 target_mcontext_t tuc_mcontext;
2507 /* A V9 register window */
2508 struct target_reg_window {
2509 abi_ulong locals[8];
2510 abi_ulong ins[8];
2513 #define TARGET_STACK_BIAS 2047
2515 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2516 void sparc64_set_context(CPUSPARCState *env)
2518 abi_ulong ucp_addr;
2519 struct target_ucontext *ucp;
2520 target_mc_gregset_t *grp;
2521 abi_ulong pc, npc, tstate;
2522 abi_ulong fp, i7, w_addr;
2523 unsigned int i;
2525 ucp_addr = env->regwptr[UREG_I0];
2526 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2527 goto do_sigsegv;
2528 grp = &ucp->tuc_mcontext.mc_gregs;
2529 __get_user(pc, &((*grp)[MC_PC]));
2530 __get_user(npc, &((*grp)[MC_NPC]));
2531 if ((pc | npc) & 3)
2532 goto do_sigsegv;
2533 if (env->regwptr[UREG_I1]) {
2534 target_sigset_t target_set;
2535 sigset_t set;
2537 if (TARGET_NSIG_WORDS == 1) {
2538 __get_user(target_set.sig[0], &ucp->tuc_sigmask.sig[0]);
2539 } else {
2540 abi_ulong *src, *dst;
2541 src = ucp->tuc_sigmask.sig;
2542 dst = target_set.sig;
2543 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2544 __get_user(*dst, src);
2547 target_to_host_sigset_internal(&set, &target_set);
2548 do_sigprocmask(SIG_SETMASK, &set, NULL);
2550 env->pc = pc;
2551 env->npc = npc;
2552 __get_user(env->y, &((*grp)[MC_Y]));
2553 __get_user(tstate, &((*grp)[MC_TSTATE]));
2554 env->asi = (tstate >> 24) & 0xff;
2555 cpu_put_ccr(env, tstate >> 32);
2556 cpu_put_cwp64(env, tstate & 0x1f);
2557 __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2558 __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2559 __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2560 __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2561 __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2562 __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2563 __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2564 __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2565 __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2566 __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2567 __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2568 __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2569 __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2570 __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2571 __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2573 __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
2574 __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
2576 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2577 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2578 abi_ulong) != 0)
2579 goto do_sigsegv;
2580 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2581 abi_ulong) != 0)
2582 goto do_sigsegv;
2583 /* FIXME this does not match how the kernel handles the FPU in
2584 * its sparc64_set_context implementation. In particular the FPU
2585 * is only restored if fenab is non-zero in:
2586 * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
2588 __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
2590 uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2591 for (i = 0; i < 64; i++, src++) {
2592 if (i & 1) {
2593 __get_user(env->fpr[i/2].l.lower, src);
2594 } else {
2595 __get_user(env->fpr[i/2].l.upper, src);
2599 __get_user(env->fsr,
2600 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr));
2601 __get_user(env->gsr,
2602 &(ucp->tuc_mcontext.mc_fpregs.mcfpu_gsr));
2603 unlock_user_struct(ucp, ucp_addr, 0);
2604 return;
2605 do_sigsegv:
2606 unlock_user_struct(ucp, ucp_addr, 0);
2607 force_sig(TARGET_SIGSEGV);
2610 void sparc64_get_context(CPUSPARCState *env)
2612 abi_ulong ucp_addr;
2613 struct target_ucontext *ucp;
2614 target_mc_gregset_t *grp;
2615 target_mcontext_t *mcp;
2616 abi_ulong fp, i7, w_addr;
2617 int err;
2618 unsigned int i;
2619 target_sigset_t target_set;
2620 sigset_t set;
2622 ucp_addr = env->regwptr[UREG_I0];
2623 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2624 goto do_sigsegv;
2626 mcp = &ucp->tuc_mcontext;
2627 grp = &mcp->mc_gregs;
2629 /* Skip over the trap instruction, first. */
2630 env->pc = env->npc;
2631 env->npc += 4;
2633 err = 0;
2635 do_sigprocmask(0, NULL, &set);
2636 host_to_target_sigset_internal(&target_set, &set);
2637 if (TARGET_NSIG_WORDS == 1) {
2638 __put_user(target_set.sig[0],
2639 (abi_ulong *)&ucp->tuc_sigmask);
2640 } else {
2641 abi_ulong *src, *dst;
2642 src = target_set.sig;
2643 dst = ucp->tuc_sigmask.sig;
2644 for (i = 0; i < TARGET_NSIG_WORDS; i++, dst++, src++) {
2645 __put_user(*src, dst);
2647 if (err)
2648 goto do_sigsegv;
2651 /* XXX: tstate must be saved properly */
2652 // __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2653 __put_user(env->pc, &((*grp)[MC_PC]));
2654 __put_user(env->npc, &((*grp)[MC_NPC]));
2655 __put_user(env->y, &((*grp)[MC_Y]));
2656 __put_user(env->gregs[1], &((*grp)[MC_G1]));
2657 __put_user(env->gregs[2], &((*grp)[MC_G2]));
2658 __put_user(env->gregs[3], &((*grp)[MC_G3]));
2659 __put_user(env->gregs[4], &((*grp)[MC_G4]));
2660 __put_user(env->gregs[5], &((*grp)[MC_G5]));
2661 __put_user(env->gregs[6], &((*grp)[MC_G6]));
2662 __put_user(env->gregs[7], &((*grp)[MC_G7]));
2663 __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2664 __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2665 __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2666 __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2667 __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2668 __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2669 __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2670 __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2672 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2673 fp = i7 = 0;
2674 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2675 abi_ulong) != 0)
2676 goto do_sigsegv;
2677 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2678 abi_ulong) != 0)
2679 goto do_sigsegv;
2680 __put_user(fp, &(mcp->mc_fp));
2681 __put_user(i7, &(mcp->mc_i7));
2684 uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2685 for (i = 0; i < 64; i++, dst++) {
2686 if (i & 1) {
2687 __put_user(env->fpr[i/2].l.lower, dst);
2688 } else {
2689 __put_user(env->fpr[i/2].l.upper, dst);
2693 __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2694 __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2695 __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2697 if (err)
2698 goto do_sigsegv;
2699 unlock_user_struct(ucp, ucp_addr, 1);
2700 return;
2701 do_sigsegv:
2702 unlock_user_struct(ucp, ucp_addr, 1);
2703 force_sig(TARGET_SIGSEGV);
2705 #endif
2706 #elif defined(TARGET_MIPS) || defined(TARGET_MIPS64)
2708 # if defined(TARGET_ABI_MIPSO32)
2709 struct target_sigcontext {
2710 uint32_t sc_regmask; /* Unused */
2711 uint32_t sc_status;
2712 uint64_t sc_pc;
2713 uint64_t sc_regs[32];
2714 uint64_t sc_fpregs[32];
2715 uint32_t sc_ownedfp; /* Unused */
2716 uint32_t sc_fpc_csr;
2717 uint32_t sc_fpc_eir; /* Unused */
2718 uint32_t sc_used_math;
2719 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2720 uint32_t pad0;
2721 uint64_t sc_mdhi;
2722 uint64_t sc_mdlo;
2723 target_ulong sc_hi1; /* Was sc_cause */
2724 target_ulong sc_lo1; /* Was sc_badvaddr */
2725 target_ulong sc_hi2; /* Was sc_sigset[4] */
2726 target_ulong sc_lo2;
2727 target_ulong sc_hi3;
2728 target_ulong sc_lo3;
2730 # else /* N32 || N64 */
2731 struct target_sigcontext {
2732 uint64_t sc_regs[32];
2733 uint64_t sc_fpregs[32];
2734 uint64_t sc_mdhi;
2735 uint64_t sc_hi1;
2736 uint64_t sc_hi2;
2737 uint64_t sc_hi3;
2738 uint64_t sc_mdlo;
2739 uint64_t sc_lo1;
2740 uint64_t sc_lo2;
2741 uint64_t sc_lo3;
2742 uint64_t sc_pc;
2743 uint32_t sc_fpc_csr;
2744 uint32_t sc_used_math;
2745 uint32_t sc_dsp;
2746 uint32_t sc_reserved;
2748 # endif /* O32 */
2750 struct sigframe {
2751 uint32_t sf_ass[4]; /* argument save space for o32 */
2752 uint32_t sf_code[2]; /* signal trampoline */
2753 struct target_sigcontext sf_sc;
2754 target_sigset_t sf_mask;
2757 struct target_ucontext {
2758 target_ulong tuc_flags;
2759 target_ulong tuc_link;
2760 target_stack_t tuc_stack;
2761 target_ulong pad0;
2762 struct target_sigcontext tuc_mcontext;
2763 target_sigset_t tuc_sigmask;
2766 struct target_rt_sigframe {
2767 uint32_t rs_ass[4]; /* argument save space for o32 */
2768 uint32_t rs_code[2]; /* signal trampoline */
2769 struct target_siginfo rs_info;
2770 struct target_ucontext rs_uc;
2773 /* Install trampoline to jump back from signal handler */
2774 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2776 int err = 0;
2779 * Set up the return code ...
2781 * li v0, __NR__foo_sigreturn
2782 * syscall
2785 __put_user(0x24020000 + syscall, tramp + 0);
2786 __put_user(0x0000000c , tramp + 1);
2787 return err;
2790 static inline void setup_sigcontext(CPUMIPSState *regs,
2791 struct target_sigcontext *sc)
2793 int i;
2795 __put_user(exception_resume_pc(regs), &sc->sc_pc);
2796 regs->hflags &= ~MIPS_HFLAG_BMASK;
2798 __put_user(0, &sc->sc_regs[0]);
2799 for (i = 1; i < 32; ++i) {
2800 __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2803 __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2804 __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2806 /* Rather than checking for dsp existence, always copy. The storage
2807 would just be garbage otherwise. */
2808 __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
2809 __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
2810 __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
2811 __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
2812 __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
2813 __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
2815 uint32_t dsp = cpu_rddsp(0x3ff, regs);
2816 __put_user(dsp, &sc->sc_dsp);
2819 __put_user(1, &sc->sc_used_math);
2821 for (i = 0; i < 32; ++i) {
2822 __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2826 static inline void
2827 restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
2829 int i;
2831 __get_user(regs->CP0_EPC, &sc->sc_pc);
2833 __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2834 __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2836 for (i = 1; i < 32; ++i) {
2837 __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
2840 __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
2841 __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
2842 __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
2843 __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
2844 __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
2845 __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
2847 uint32_t dsp;
2848 __get_user(dsp, &sc->sc_dsp);
2849 cpu_wrdsp(dsp, 0x3ff, regs);
2852 for (i = 0; i < 32; ++i) {
2853 __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
2858 * Determine which stack to use..
2860 static inline abi_ulong
2861 get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
2863 unsigned long sp;
2865 /* Default to using normal stack */
2866 sp = regs->active_tc.gpr[29];
2869 * FPU emulator may have its own trampoline active just
2870 * above the user stack, 16-bytes before the next lowest
2871 * 16 byte boundary. Try to avoid trashing it.
2873 sp -= 32;
2875 /* This is the X/Open sanctioned signal stack switching. */
2876 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2877 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2880 return (sp - frame_size) & ~7;
2883 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
2885 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
2886 env->hflags &= ~MIPS_HFLAG_M16;
2887 env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
2888 env->active_tc.PC &= ~(target_ulong) 1;
2892 # if defined(TARGET_ABI_MIPSO32)
2893 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2894 static void setup_frame(int sig, struct target_sigaction * ka,
2895 target_sigset_t *set, CPUMIPSState *regs)
2897 struct sigframe *frame;
2898 abi_ulong frame_addr;
2899 int i;
2901 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2902 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2903 goto give_sigsegv;
2905 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2907 setup_sigcontext(regs, &frame->sf_sc);
2909 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2910 __put_user(set->sig[i], &frame->sf_mask.sig[i]);
2914 * Arguments to signal handler:
2916 * a0 = signal number
2917 * a1 = 0 (should be cause)
2918 * a2 = pointer to struct sigcontext
2920 * $25 and PC point to the signal handler, $29 points to the
2921 * struct sigframe.
2923 regs->active_tc.gpr[ 4] = sig;
2924 regs->active_tc.gpr[ 5] = 0;
2925 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2926 regs->active_tc.gpr[29] = frame_addr;
2927 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2928 /* The original kernel code sets CP0_EPC to the handler
2929 * since it returns to userland using eret
2930 * we cannot do this here, and we must set PC directly */
2931 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2932 mips_set_hflags_isa_mode_from_pc(regs);
2933 unlock_user_struct(frame, frame_addr, 1);
2934 return;
2936 give_sigsegv:
2937 force_sig(TARGET_SIGSEGV/*, current*/);
2940 long do_sigreturn(CPUMIPSState *regs)
2942 struct sigframe *frame;
2943 abi_ulong frame_addr;
2944 sigset_t blocked;
2945 target_sigset_t target_set;
2946 int i;
2948 #if defined(DEBUG_SIGNAL)
2949 fprintf(stderr, "do_sigreturn\n");
2950 #endif
2951 frame_addr = regs->active_tc.gpr[29];
2952 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2953 goto badframe;
2955 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2956 __get_user(target_set.sig[i], &frame->sf_mask.sig[i]);
2959 target_to_host_sigset_internal(&blocked, &target_set);
2960 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
2962 restore_sigcontext(regs, &frame->sf_sc);
2964 #if 0
2966 * Don't let your children do this ...
2968 __asm__ __volatile__(
2969 "move\t$29, %0\n\t"
2970 "j\tsyscall_exit"
2971 :/* no outputs */
2972 :"r" (&regs));
2973 /* Unreached */
2974 #endif
2976 regs->active_tc.PC = regs->CP0_EPC;
2977 mips_set_hflags_isa_mode_from_pc(regs);
2978 /* I am not sure this is right, but it seems to work
2979 * maybe a problem with nested signals ? */
2980 regs->CP0_EPC = 0;
2981 return -TARGET_QEMU_ESIGRETURN;
2983 badframe:
2984 force_sig(TARGET_SIGSEGV/*, current*/);
2985 return 0;
2987 # endif /* O32 */
2989 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2990 target_siginfo_t *info,
2991 target_sigset_t *set, CPUMIPSState *env)
2993 struct target_rt_sigframe *frame;
2994 abi_ulong frame_addr;
2995 int i;
2997 frame_addr = get_sigframe(ka, env, sizeof(*frame));
2998 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2999 goto give_sigsegv;
3001 install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
3003 tswap_siginfo(&frame->rs_info, info);
3005 __put_user(0, &frame->rs_uc.tuc_flags);
3006 __put_user(0, &frame->rs_uc.tuc_link);
3007 __put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
3008 __put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
3009 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
3010 &frame->rs_uc.tuc_stack.ss_flags);
3012 setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3014 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3015 __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
3019 * Arguments to signal handler:
3021 * a0 = signal number
3022 * a1 = pointer to siginfo_t
3023 * a2 = pointer to struct ucontext
3025 * $25 and PC point to the signal handler, $29 points to the
3026 * struct sigframe.
3028 env->active_tc.gpr[ 4] = sig;
3029 env->active_tc.gpr[ 5] = frame_addr
3030 + offsetof(struct target_rt_sigframe, rs_info);
3031 env->active_tc.gpr[ 6] = frame_addr
3032 + offsetof(struct target_rt_sigframe, rs_uc);
3033 env->active_tc.gpr[29] = frame_addr;
3034 env->active_tc.gpr[31] = frame_addr
3035 + offsetof(struct target_rt_sigframe, rs_code);
3036 /* The original kernel code sets CP0_EPC to the handler
3037 * since it returns to userland using eret
3038 * we cannot do this here, and we must set PC directly */
3039 env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
3040 mips_set_hflags_isa_mode_from_pc(env);
3041 unlock_user_struct(frame, frame_addr, 1);
3042 return;
3044 give_sigsegv:
3045 unlock_user_struct(frame, frame_addr, 1);
3046 force_sig(TARGET_SIGSEGV/*, current*/);
3049 long do_rt_sigreturn(CPUMIPSState *env)
3051 struct target_rt_sigframe *frame;
3052 abi_ulong frame_addr;
3053 sigset_t blocked;
3055 #if defined(DEBUG_SIGNAL)
3056 fprintf(stderr, "do_rt_sigreturn\n");
3057 #endif
3058 frame_addr = env->active_tc.gpr[29];
3059 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3060 goto badframe;
3062 target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
3063 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3065 restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
3067 if (do_sigaltstack(frame_addr +
3068 offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
3069 0, get_sp_from_cpustate(env)) == -EFAULT)
3070 goto badframe;
3072 env->active_tc.PC = env->CP0_EPC;
3073 mips_set_hflags_isa_mode_from_pc(env);
3074 /* I am not sure this is right, but it seems to work
3075 * maybe a problem with nested signals ? */
3076 env->CP0_EPC = 0;
3077 return -TARGET_QEMU_ESIGRETURN;
3079 badframe:
3080 force_sig(TARGET_SIGSEGV/*, current*/);
3081 return 0;
3084 #elif defined(TARGET_SH4)
3087 * code and data structures from linux kernel:
3088 * include/asm-sh/sigcontext.h
3089 * arch/sh/kernel/signal.c
3092 struct target_sigcontext {
3093 target_ulong oldmask;
3095 /* CPU registers */
3096 target_ulong sc_gregs[16];
3097 target_ulong sc_pc;
3098 target_ulong sc_pr;
3099 target_ulong sc_sr;
3100 target_ulong sc_gbr;
3101 target_ulong sc_mach;
3102 target_ulong sc_macl;
3104 /* FPU registers */
3105 target_ulong sc_fpregs[16];
3106 target_ulong sc_xfpregs[16];
3107 unsigned int sc_fpscr;
3108 unsigned int sc_fpul;
3109 unsigned int sc_ownedfp;
3112 struct target_sigframe
3114 struct target_sigcontext sc;
3115 target_ulong extramask[TARGET_NSIG_WORDS-1];
3116 uint16_t retcode[3];
3120 struct target_ucontext {
3121 target_ulong tuc_flags;
3122 struct target_ucontext *tuc_link;
3123 target_stack_t tuc_stack;
3124 struct target_sigcontext tuc_mcontext;
3125 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3128 struct target_rt_sigframe
3130 struct target_siginfo info;
3131 struct target_ucontext uc;
3132 uint16_t retcode[3];
3136 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
3137 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
3139 static abi_ulong get_sigframe(struct target_sigaction *ka,
3140 unsigned long sp, size_t frame_size)
3142 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
3143 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3146 return (sp - frame_size) & -8ul;
3149 static void setup_sigcontext(struct target_sigcontext *sc,
3150 CPUSH4State *regs, unsigned long mask)
3152 int i;
3154 #define COPY(x) __put_user(regs->x, &sc->sc_##x)
3155 COPY(gregs[0]); COPY(gregs[1]);
3156 COPY(gregs[2]); COPY(gregs[3]);
3157 COPY(gregs[4]); COPY(gregs[5]);
3158 COPY(gregs[6]); COPY(gregs[7]);
3159 COPY(gregs[8]); COPY(gregs[9]);
3160 COPY(gregs[10]); COPY(gregs[11]);
3161 COPY(gregs[12]); COPY(gregs[13]);
3162 COPY(gregs[14]); COPY(gregs[15]);
3163 COPY(gbr); COPY(mach);
3164 COPY(macl); COPY(pr);
3165 COPY(sr); COPY(pc);
3166 #undef COPY
3168 for (i=0; i<16; i++) {
3169 __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
3171 __put_user(regs->fpscr, &sc->sc_fpscr);
3172 __put_user(regs->fpul, &sc->sc_fpul);
3174 /* non-iBCS2 extensions.. */
3175 __put_user(mask, &sc->oldmask);
3178 static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc,
3179 target_ulong *r0_p)
3181 int i;
3183 #define COPY(x) __get_user(regs->x, &sc->sc_##x)
3184 COPY(gregs[1]);
3185 COPY(gregs[2]); COPY(gregs[3]);
3186 COPY(gregs[4]); COPY(gregs[5]);
3187 COPY(gregs[6]); COPY(gregs[7]);
3188 COPY(gregs[8]); COPY(gregs[9]);
3189 COPY(gregs[10]); COPY(gregs[11]);
3190 COPY(gregs[12]); COPY(gregs[13]);
3191 COPY(gregs[14]); COPY(gregs[15]);
3192 COPY(gbr); COPY(mach);
3193 COPY(macl); COPY(pr);
3194 COPY(sr); COPY(pc);
3195 #undef COPY
3197 for (i=0; i<16; i++) {
3198 __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
3200 __get_user(regs->fpscr, &sc->sc_fpscr);
3201 __get_user(regs->fpul, &sc->sc_fpul);
3203 regs->tra = -1; /* disable syscall checks */
3204 __get_user(*r0_p, &sc->sc_gregs[0]);
3207 static void setup_frame(int sig, struct target_sigaction *ka,
3208 target_sigset_t *set, CPUSH4State *regs)
3210 struct target_sigframe *frame;
3211 abi_ulong frame_addr;
3212 int i;
3213 int err = 0;
3215 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3216 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3217 goto give_sigsegv;
3219 setup_sigcontext(&frame->sc, regs, set->sig[0]);
3221 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
3222 __put_user(set->sig[i + 1], &frame->extramask[i]);
3225 /* Set up to return from userspace. If provided, use a stub
3226 already in userspace. */
3227 if (ka->sa_flags & TARGET_SA_RESTORER) {
3228 regs->pr = (unsigned long) ka->sa_restorer;
3229 } else {
3230 /* Generate return code (system call to sigreturn) */
3231 __put_user(MOVW(2), &frame->retcode[0]);
3232 __put_user(TRAP_NOARG, &frame->retcode[1]);
3233 __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
3234 regs->pr = (unsigned long) frame->retcode;
3237 if (err)
3238 goto give_sigsegv;
3240 /* Set up registers for signal handler */
3241 regs->gregs[15] = frame_addr;
3242 regs->gregs[4] = sig; /* Arg for signal handler */
3243 regs->gregs[5] = 0;
3244 regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
3245 regs->pc = (unsigned long) ka->_sa_handler;
3247 unlock_user_struct(frame, frame_addr, 1);
3248 return;
3250 give_sigsegv:
3251 unlock_user_struct(frame, frame_addr, 1);
3252 force_sig(TARGET_SIGSEGV);
3255 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3256 target_siginfo_t *info,
3257 target_sigset_t *set, CPUSH4State *regs)
3259 struct target_rt_sigframe *frame;
3260 abi_ulong frame_addr;
3261 int i;
3262 int err = 0;
3264 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
3265 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3266 goto give_sigsegv;
3268 tswap_siginfo(&frame->info, info);
3270 /* Create the ucontext. */
3271 __put_user(0, &frame->uc.tuc_flags);
3272 __put_user(0, (unsigned long *)&frame->uc.tuc_link);
3273 __put_user((unsigned long)target_sigaltstack_used.ss_sp,
3274 &frame->uc.tuc_stack.ss_sp);
3275 __put_user(sas_ss_flags(regs->gregs[15]),
3276 &frame->uc.tuc_stack.ss_flags);
3277 __put_user(target_sigaltstack_used.ss_size,
3278 &frame->uc.tuc_stack.ss_size);
3279 setup_sigcontext(&frame->uc.tuc_mcontext,
3280 regs, set->sig[0]);
3281 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
3282 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
3285 /* Set up to return from userspace. If provided, use a stub
3286 already in userspace. */
3287 if (ka->sa_flags & TARGET_SA_RESTORER) {
3288 regs->pr = (unsigned long) ka->sa_restorer;
3289 } else {
3290 /* Generate return code (system call to sigreturn) */
3291 __put_user(MOVW(2), &frame->retcode[0]);
3292 __put_user(TRAP_NOARG, &frame->retcode[1]);
3293 __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
3294 regs->pr = (unsigned long) frame->retcode;
3297 if (err)
3298 goto give_sigsegv;
3300 /* Set up registers for signal handler */
3301 regs->gregs[15] = frame_addr;
3302 regs->gregs[4] = sig; /* Arg for signal handler */
3303 regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
3304 regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
3305 regs->pc = (unsigned long) ka->_sa_handler;
3307 unlock_user_struct(frame, frame_addr, 1);
3308 return;
3310 give_sigsegv:
3311 unlock_user_struct(frame, frame_addr, 1);
3312 force_sig(TARGET_SIGSEGV);
3315 long do_sigreturn(CPUSH4State *regs)
3317 struct target_sigframe *frame;
3318 abi_ulong frame_addr;
3319 sigset_t blocked;
3320 target_sigset_t target_set;
3321 target_ulong r0;
3322 int i;
3323 int err = 0;
3325 #if defined(DEBUG_SIGNAL)
3326 fprintf(stderr, "do_sigreturn\n");
3327 #endif
3328 frame_addr = regs->gregs[15];
3329 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3330 goto badframe;
3332 __get_user(target_set.sig[0], &frame->sc.oldmask);
3333 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3334 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
3337 if (err)
3338 goto badframe;
3340 target_to_host_sigset_internal(&blocked, &target_set);
3341 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3343 restore_sigcontext(regs, &frame->sc, &r0);
3345 unlock_user_struct(frame, frame_addr, 0);
3346 return r0;
3348 badframe:
3349 unlock_user_struct(frame, frame_addr, 0);
3350 force_sig(TARGET_SIGSEGV);
3351 return 0;
3354 long do_rt_sigreturn(CPUSH4State *regs)
3356 struct target_rt_sigframe *frame;
3357 abi_ulong frame_addr;
3358 sigset_t blocked;
3359 target_ulong r0;
3361 #if defined(DEBUG_SIGNAL)
3362 fprintf(stderr, "do_rt_sigreturn\n");
3363 #endif
3364 frame_addr = regs->gregs[15];
3365 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
3366 goto badframe;
3368 target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask);
3369 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
3371 restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0);
3373 if (do_sigaltstack(frame_addr +
3374 offsetof(struct target_rt_sigframe, uc.tuc_stack),
3375 0, get_sp_from_cpustate(regs)) == -EFAULT)
3376 goto badframe;
3378 unlock_user_struct(frame, frame_addr, 0);
3379 return r0;
3381 badframe:
3382 unlock_user_struct(frame, frame_addr, 0);
3383 force_sig(TARGET_SIGSEGV);
3384 return 0;
3386 #elif defined(TARGET_MICROBLAZE)
3388 struct target_sigcontext {
3389 struct target_pt_regs regs; /* needs to be first */
3390 uint32_t oldmask;
3393 struct target_stack_t {
3394 abi_ulong ss_sp;
3395 int ss_flags;
3396 unsigned int ss_size;
3399 struct target_ucontext {
3400 abi_ulong tuc_flags;
3401 abi_ulong tuc_link;
3402 struct target_stack_t tuc_stack;
3403 struct target_sigcontext tuc_mcontext;
3404 uint32_t tuc_extramask[TARGET_NSIG_WORDS - 1];
3407 /* Signal frames. */
3408 struct target_signal_frame {
3409 struct target_ucontext uc;
3410 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3411 uint32_t tramp[2];
3414 struct rt_signal_frame {
3415 siginfo_t info;
3416 struct ucontext uc;
3417 uint32_t tramp[2];
3420 static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3422 __put_user(env->regs[0], &sc->regs.r0);
3423 __put_user(env->regs[1], &sc->regs.r1);
3424 __put_user(env->regs[2], &sc->regs.r2);
3425 __put_user(env->regs[3], &sc->regs.r3);
3426 __put_user(env->regs[4], &sc->regs.r4);
3427 __put_user(env->regs[5], &sc->regs.r5);
3428 __put_user(env->regs[6], &sc->regs.r6);
3429 __put_user(env->regs[7], &sc->regs.r7);
3430 __put_user(env->regs[8], &sc->regs.r8);
3431 __put_user(env->regs[9], &sc->regs.r9);
3432 __put_user(env->regs[10], &sc->regs.r10);
3433 __put_user(env->regs[11], &sc->regs.r11);
3434 __put_user(env->regs[12], &sc->regs.r12);
3435 __put_user(env->regs[13], &sc->regs.r13);
3436 __put_user(env->regs[14], &sc->regs.r14);
3437 __put_user(env->regs[15], &sc->regs.r15);
3438 __put_user(env->regs[16], &sc->regs.r16);
3439 __put_user(env->regs[17], &sc->regs.r17);
3440 __put_user(env->regs[18], &sc->regs.r18);
3441 __put_user(env->regs[19], &sc->regs.r19);
3442 __put_user(env->regs[20], &sc->regs.r20);
3443 __put_user(env->regs[21], &sc->regs.r21);
3444 __put_user(env->regs[22], &sc->regs.r22);
3445 __put_user(env->regs[23], &sc->regs.r23);
3446 __put_user(env->regs[24], &sc->regs.r24);
3447 __put_user(env->regs[25], &sc->regs.r25);
3448 __put_user(env->regs[26], &sc->regs.r26);
3449 __put_user(env->regs[27], &sc->regs.r27);
3450 __put_user(env->regs[28], &sc->regs.r28);
3451 __put_user(env->regs[29], &sc->regs.r29);
3452 __put_user(env->regs[30], &sc->regs.r30);
3453 __put_user(env->regs[31], &sc->regs.r31);
3454 __put_user(env->sregs[SR_PC], &sc->regs.pc);
3457 static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
3459 __get_user(env->regs[0], &sc->regs.r0);
3460 __get_user(env->regs[1], &sc->regs.r1);
3461 __get_user(env->regs[2], &sc->regs.r2);
3462 __get_user(env->regs[3], &sc->regs.r3);
3463 __get_user(env->regs[4], &sc->regs.r4);
3464 __get_user(env->regs[5], &sc->regs.r5);
3465 __get_user(env->regs[6], &sc->regs.r6);
3466 __get_user(env->regs[7], &sc->regs.r7);
3467 __get_user(env->regs[8], &sc->regs.r8);
3468 __get_user(env->regs[9], &sc->regs.r9);
3469 __get_user(env->regs[10], &sc->regs.r10);
3470 __get_user(env->regs[11], &sc->regs.r11);
3471 __get_user(env->regs[12], &sc->regs.r12);
3472 __get_user(env->regs[13], &sc->regs.r13);
3473 __get_user(env->regs[14], &sc->regs.r14);
3474 __get_user(env->regs[15], &sc->regs.r15);
3475 __get_user(env->regs[16], &sc->regs.r16);
3476 __get_user(env->regs[17], &sc->regs.r17);
3477 __get_user(env->regs[18], &sc->regs.r18);
3478 __get_user(env->regs[19], &sc->regs.r19);
3479 __get_user(env->regs[20], &sc->regs.r20);
3480 __get_user(env->regs[21], &sc->regs.r21);
3481 __get_user(env->regs[22], &sc->regs.r22);
3482 __get_user(env->regs[23], &sc->regs.r23);
3483 __get_user(env->regs[24], &sc->regs.r24);
3484 __get_user(env->regs[25], &sc->regs.r25);
3485 __get_user(env->regs[26], &sc->regs.r26);
3486 __get_user(env->regs[27], &sc->regs.r27);
3487 __get_user(env->regs[28], &sc->regs.r28);
3488 __get_user(env->regs[29], &sc->regs.r29);
3489 __get_user(env->regs[30], &sc->regs.r30);
3490 __get_user(env->regs[31], &sc->regs.r31);
3491 __get_user(env->sregs[SR_PC], &sc->regs.pc);
3494 static abi_ulong get_sigframe(struct target_sigaction *ka,
3495 CPUMBState *env, int frame_size)
3497 abi_ulong sp = env->regs[1];
3499 if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !on_sig_stack(sp)) {
3500 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3503 return ((sp - frame_size) & -8UL);
3506 static void setup_frame(int sig, struct target_sigaction *ka,
3507 target_sigset_t *set, CPUMBState *env)
3509 struct target_signal_frame *frame;
3510 abi_ulong frame_addr;
3511 int i;
3513 frame_addr = get_sigframe(ka, env, sizeof *frame);
3514 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3515 goto badframe;
3517 /* Save the mask. */
3518 __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);
3520 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3521 __put_user(set->sig[i], &frame->extramask[i - 1]);
3524 setup_sigcontext(&frame->uc.tuc_mcontext, env);
3526 /* Set up to return from userspace. If provided, use a stub
3527 already in userspace. */
3528 /* minus 8 is offset to cater for "rtsd r15,8" offset */
3529 if (ka->sa_flags & TARGET_SA_RESTORER) {
3530 env->regs[15] = ((unsigned long)ka->sa_restorer)-8;
3531 } else {
3532 uint32_t t;
3533 /* Note, these encodings are _big endian_! */
3534 /* addi r12, r0, __NR_sigreturn */
3535 t = 0x31800000UL | TARGET_NR_sigreturn;
3536 __put_user(t, frame->tramp + 0);
3537 /* brki r14, 0x8 */
3538 t = 0xb9cc0008UL;
3539 __put_user(t, frame->tramp + 1);
3541 /* Return from sighandler will jump to the tramp.
3542 Negative 8 offset because return is rtsd r15, 8 */
3543 env->regs[15] = ((unsigned long)frame->tramp) - 8;
3546 /* Set up registers for signal handler */
3547 env->regs[1] = frame_addr;
3548 /* Signal handler args: */
3549 env->regs[5] = sig; /* Arg 0: signum */
3550 env->regs[6] = 0;
3551 /* arg 1: sigcontext */
3552 env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
3554 /* Offset of 4 to handle microblaze rtid r14, 0 */
3555 env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
3557 unlock_user_struct(frame, frame_addr, 1);
3558 return;
3559 badframe:
3560 force_sig(TARGET_SIGSEGV);
3563 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3564 target_siginfo_t *info,
3565 target_sigset_t *set, CPUMBState *env)
3567 fprintf(stderr, "Microblaze setup_rt_frame: not implemented\n");
3570 long do_sigreturn(CPUMBState *env)
3572 struct target_signal_frame *frame;
3573 abi_ulong frame_addr;
3574 target_sigset_t target_set;
3575 sigset_t set;
3576 int i;
3578 frame_addr = env->regs[R_SP];
3579 /* Make sure the guest isn't playing games. */
3580 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3581 goto badframe;
3583 /* Restore blocked signals */
3584 __get_user(target_set.sig[0], &frame->uc.tuc_mcontext.oldmask);
3585 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3586 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
3588 target_to_host_sigset_internal(&set, &target_set);
3589 do_sigprocmask(SIG_SETMASK, &set, NULL);
3591 restore_sigcontext(&frame->uc.tuc_mcontext, env);
3592 /* We got here through a sigreturn syscall, our path back is via an
3593 rtb insn so setup r14 for that. */
3594 env->regs[14] = env->sregs[SR_PC];
3596 unlock_user_struct(frame, frame_addr, 0);
3597 return env->regs[10];
3598 badframe:
3599 force_sig(TARGET_SIGSEGV);
3602 long do_rt_sigreturn(CPUMBState *env)
3604 fprintf(stderr, "Microblaze do_rt_sigreturn: not implemented\n");
3605 return -TARGET_ENOSYS;
3608 #elif defined(TARGET_CRIS)
3610 struct target_sigcontext {
3611 struct target_pt_regs regs; /* needs to be first */
3612 uint32_t oldmask;
3613 uint32_t usp; /* usp before stacking this gunk on it */
3616 /* Signal frames. */
3617 struct target_signal_frame {
3618 struct target_sigcontext sc;
3619 uint32_t extramask[TARGET_NSIG_WORDS - 1];
3620 uint16_t retcode[4]; /* Trampoline code. */
3623 struct rt_signal_frame {
3624 siginfo_t *pinfo;
3625 void *puc;
3626 siginfo_t info;
3627 struct ucontext uc;
3628 uint16_t retcode[4]; /* Trampoline code. */
3631 static void setup_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3633 __put_user(env->regs[0], &sc->regs.r0);
3634 __put_user(env->regs[1], &sc->regs.r1);
3635 __put_user(env->regs[2], &sc->regs.r2);
3636 __put_user(env->regs[3], &sc->regs.r3);
3637 __put_user(env->regs[4], &sc->regs.r4);
3638 __put_user(env->regs[5], &sc->regs.r5);
3639 __put_user(env->regs[6], &sc->regs.r6);
3640 __put_user(env->regs[7], &sc->regs.r7);
3641 __put_user(env->regs[8], &sc->regs.r8);
3642 __put_user(env->regs[9], &sc->regs.r9);
3643 __put_user(env->regs[10], &sc->regs.r10);
3644 __put_user(env->regs[11], &sc->regs.r11);
3645 __put_user(env->regs[12], &sc->regs.r12);
3646 __put_user(env->regs[13], &sc->regs.r13);
3647 __put_user(env->regs[14], &sc->usp);
3648 __put_user(env->regs[15], &sc->regs.acr);
3649 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
3650 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
3651 __put_user(env->pc, &sc->regs.erp);
3654 static void restore_sigcontext(struct target_sigcontext *sc, CPUCRISState *env)
3656 __get_user(env->regs[0], &sc->regs.r0);
3657 __get_user(env->regs[1], &sc->regs.r1);
3658 __get_user(env->regs[2], &sc->regs.r2);
3659 __get_user(env->regs[3], &sc->regs.r3);
3660 __get_user(env->regs[4], &sc->regs.r4);
3661 __get_user(env->regs[5], &sc->regs.r5);
3662 __get_user(env->regs[6], &sc->regs.r6);
3663 __get_user(env->regs[7], &sc->regs.r7);
3664 __get_user(env->regs[8], &sc->regs.r8);
3665 __get_user(env->regs[9], &sc->regs.r9);
3666 __get_user(env->regs[10], &sc->regs.r10);
3667 __get_user(env->regs[11], &sc->regs.r11);
3668 __get_user(env->regs[12], &sc->regs.r12);
3669 __get_user(env->regs[13], &sc->regs.r13);
3670 __get_user(env->regs[14], &sc->usp);
3671 __get_user(env->regs[15], &sc->regs.acr);
3672 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
3673 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
3674 __get_user(env->pc, &sc->regs.erp);
3677 static abi_ulong get_sigframe(CPUCRISState *env, int framesize)
3679 abi_ulong sp;
3680 /* Align the stack downwards to 4. */
3681 sp = (env->regs[R_SP] & ~3);
3682 return sp - framesize;
3685 static void setup_frame(int sig, struct target_sigaction *ka,
3686 target_sigset_t *set, CPUCRISState *env)
3688 struct target_signal_frame *frame;
3689 abi_ulong frame_addr;
3690 int i;
3692 frame_addr = get_sigframe(env, sizeof *frame);
3693 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
3694 goto badframe;
3697 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
3698 * use this trampoline anymore but it sets it up for GDB.
3699 * In QEMU, using the trampoline simplifies things a bit so we use it.
3701 * This is movu.w __NR_sigreturn, r9; break 13;
3703 __put_user(0x9c5f, frame->retcode+0);
3704 __put_user(TARGET_NR_sigreturn,
3705 frame->retcode + 1);
3706 __put_user(0xe93d, frame->retcode + 2);
3708 /* Save the mask. */
3709 __put_user(set->sig[0], &frame->sc.oldmask);
3711 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3712 __put_user(set->sig[i], &frame->extramask[i - 1]);
3715 setup_sigcontext(&frame->sc, env);
3717 /* Move the stack and setup the arguments for the handler. */
3718 env->regs[R_SP] = frame_addr;
3719 env->regs[10] = sig;
3720 env->pc = (unsigned long) ka->_sa_handler;
3721 /* Link SRP so the guest returns through the trampoline. */
3722 env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
3724 unlock_user_struct(frame, frame_addr, 1);
3725 return;
3726 badframe:
3727 force_sig(TARGET_SIGSEGV);
3730 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3731 target_siginfo_t *info,
3732 target_sigset_t *set, CPUCRISState *env)
3734 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3737 long do_sigreturn(CPUCRISState *env)
3739 struct target_signal_frame *frame;
3740 abi_ulong frame_addr;
3741 target_sigset_t target_set;
3742 sigset_t set;
3743 int i;
3745 frame_addr = env->regs[R_SP];
3746 /* Make sure the guest isn't playing games. */
3747 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3748 goto badframe;
3750 /* Restore blocked signals */
3751 __get_user(target_set.sig[0], &frame->sc.oldmask);
3752 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3753 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
3755 target_to_host_sigset_internal(&set, &target_set);
3756 do_sigprocmask(SIG_SETMASK, &set, NULL);
3758 restore_sigcontext(&frame->sc, env);
3759 unlock_user_struct(frame, frame_addr, 0);
3760 return env->regs[10];
3761 badframe:
3762 force_sig(TARGET_SIGSEGV);
3765 long do_rt_sigreturn(CPUCRISState *env)
3767 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3768 return -TARGET_ENOSYS;
3771 #elif defined(TARGET_OPENRISC)
3773 struct target_sigcontext {
3774 struct target_pt_regs regs;
3775 abi_ulong oldmask;
3776 abi_ulong usp;
3779 struct target_ucontext {
3780 abi_ulong tuc_flags;
3781 abi_ulong tuc_link;
3782 target_stack_t tuc_stack;
3783 struct target_sigcontext tuc_mcontext;
3784 target_sigset_t tuc_sigmask; /* mask last for extensibility */
3787 struct target_rt_sigframe {
3788 abi_ulong pinfo;
3789 uint64_t puc;
3790 struct target_siginfo info;
3791 struct target_sigcontext sc;
3792 struct target_ucontext uc;
3793 unsigned char retcode[16]; /* trampoline code */
3796 /* This is the asm-generic/ucontext.h version */
3797 #if 0
3798 static int restore_sigcontext(CPUOpenRISCState *regs,
3799 struct target_sigcontext *sc)
3801 unsigned int err = 0;
3802 unsigned long old_usp;
3804 /* Alwys make any pending restarted system call return -EINTR */
3805 current_thread_info()->restart_block.fn = do_no_restart_syscall;
3807 /* restore the regs from &sc->regs (same as sc, since regs is first)
3808 * (sc is already checked for VERIFY_READ since the sigframe was
3809 * checked in sys_sigreturn previously)
3812 if (copy_from_user(regs, &sc, sizeof(struct target_pt_regs))) {
3813 goto badframe;
3816 /* make sure the U-flag is set so user-mode cannot fool us */
3818 regs->sr &= ~SR_SM;
3820 /* restore the old USP as it was before we stacked the sc etc.
3821 * (we cannot just pop the sigcontext since we aligned the sp and
3822 * stuff after pushing it)
3825 __get_user(old_usp, &sc->usp);
3826 phx_signal("old_usp 0x%lx", old_usp);
3828 __PHX__ REALLY /* ??? */
3829 wrusp(old_usp);
3830 regs->gpr[1] = old_usp;
3832 /* TODO: the other ports use regs->orig_XX to disable syscall checks
3833 * after this completes, but we don't use that mechanism. maybe we can
3834 * use it now ?
3837 return err;
3839 badframe:
3840 return 1;
3842 #endif
3844 /* Set up a signal frame. */
3846 static void setup_sigcontext(struct target_sigcontext *sc,
3847 CPUOpenRISCState *regs,
3848 unsigned long mask)
3850 unsigned long usp = regs->gpr[1];
3852 /* copy the regs. they are first in sc so we can use sc directly */
3854 /*copy_to_user(&sc, regs, sizeof(struct target_pt_regs));*/
3856 /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
3857 the signal handler. The frametype will be restored to its previous
3858 value in restore_sigcontext. */
3859 /*regs->frametype = CRIS_FRAME_NORMAL;*/
3861 /* then some other stuff */
3862 __put_user(mask, &sc->oldmask);
3863 __put_user(usp, &sc->usp);
3866 static inline unsigned long align_sigframe(unsigned long sp)
3868 unsigned long i;
3869 i = sp & ~3UL;
3870 return i;
3873 static inline abi_ulong get_sigframe(struct target_sigaction *ka,
3874 CPUOpenRISCState *regs,
3875 size_t frame_size)
3877 unsigned long sp = regs->gpr[1];
3878 int onsigstack = on_sig_stack(sp);
3880 /* redzone */
3881 /* This is the X/Open sanctioned signal stack switching. */
3882 if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !onsigstack) {
3883 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
3886 sp = align_sigframe(sp - frame_size);
3889 * If we are on the alternate signal stack and would overflow it, don't.
3890 * Return an always-bogus address instead so we will die with SIGSEGV.
3893 if (onsigstack && !likely(on_sig_stack(sp))) {
3894 return -1L;
3897 return sp;
3900 static void setup_frame(int sig, struct target_sigaction *ka,
3901 target_sigset_t *set, CPUOpenRISCState *env)
3903 qemu_log("Not implement.\n");
3906 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3907 target_siginfo_t *info,
3908 target_sigset_t *set, CPUOpenRISCState *env)
3910 int err = 0;
3911 abi_ulong frame_addr;
3912 unsigned long return_ip;
3913 struct target_rt_sigframe *frame;
3914 abi_ulong info_addr, uc_addr;
3916 frame_addr = get_sigframe(ka, env, sizeof(*frame));
3917 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
3918 goto give_sigsegv;
3921 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
3922 __put_user(info_addr, &frame->pinfo);
3923 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
3924 __put_user(uc_addr, &frame->puc);
3926 if (ka->sa_flags & SA_SIGINFO) {
3927 tswap_siginfo(&frame->info, info);
3930 /*err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));*/
3931 __put_user(0, &frame->uc.tuc_flags);
3932 __put_user(0, &frame->uc.tuc_link);
3933 __put_user(target_sigaltstack_used.ss_sp,
3934 &frame->uc.tuc_stack.ss_sp);
3935 __put_user(sas_ss_flags(env->gpr[1]), &frame->uc.tuc_stack.ss_flags);
3936 __put_user(target_sigaltstack_used.ss_size,
3937 &frame->uc.tuc_stack.ss_size);
3938 setup_sigcontext(&frame->sc, env, set->sig[0]);
3940 /*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
3942 /* trampoline - the desired return ip is the retcode itself */
3943 return_ip = (unsigned long)&frame->retcode;
3944 /* This is l.ori r11,r0,__NR_sigreturn, l.sys 1 */
3945 __put_user(0xa960, (short *)(frame->retcode + 0));
3946 __put_user(TARGET_NR_rt_sigreturn, (short *)(frame->retcode + 2));
3947 __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
3948 __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
3950 if (err) {
3951 goto give_sigsegv;
3954 /* TODO what is the current->exec_domain stuff and invmap ? */
3956 /* Set up registers for signal handler */
3957 env->pc = (unsigned long)ka->_sa_handler; /* what we enter NOW */
3958 env->gpr[9] = (unsigned long)return_ip; /* what we enter LATER */
3959 env->gpr[3] = (unsigned long)sig; /* arg 1: signo */
3960 env->gpr[4] = (unsigned long)&frame->info; /* arg 2: (siginfo_t*) */
3961 env->gpr[5] = (unsigned long)&frame->uc; /* arg 3: ucontext */
3963 /* actually move the usp to reflect the stacked frame */
3964 env->gpr[1] = (unsigned long)frame;
3966 return;
3968 give_sigsegv:
3969 unlock_user_struct(frame, frame_addr, 1);
3970 if (sig == TARGET_SIGSEGV) {
3971 ka->_sa_handler = TARGET_SIG_DFL;
3973 force_sig(TARGET_SIGSEGV);
3976 long do_sigreturn(CPUOpenRISCState *env)
3979 qemu_log("do_sigreturn: not implemented\n");
3980 return -TARGET_ENOSYS;
3983 long do_rt_sigreturn(CPUOpenRISCState *env)
3985 qemu_log("do_rt_sigreturn: not implemented\n");
3986 return -TARGET_ENOSYS;
3988 /* TARGET_OPENRISC */
3990 #elif defined(TARGET_S390X)
3992 #define __NUM_GPRS 16
3993 #define __NUM_FPRS 16
3994 #define __NUM_ACRS 16
3996 #define S390_SYSCALL_SIZE 2
3997 #define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
3999 #define _SIGCONTEXT_NSIG 64
4000 #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
4001 #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
4002 #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
4003 #define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
4004 #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
4006 typedef struct {
4007 target_psw_t psw;
4008 target_ulong gprs[__NUM_GPRS];
4009 unsigned int acrs[__NUM_ACRS];
4010 } target_s390_regs_common;
4012 typedef struct {
4013 unsigned int fpc;
4014 double fprs[__NUM_FPRS];
4015 } target_s390_fp_regs;
4017 typedef struct {
4018 target_s390_regs_common regs;
4019 target_s390_fp_regs fpregs;
4020 } target_sigregs;
4022 struct target_sigcontext {
4023 target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
4024 target_sigregs *sregs;
4027 typedef struct {
4028 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4029 struct target_sigcontext sc;
4030 target_sigregs sregs;
4031 int signo;
4032 uint8_t retcode[S390_SYSCALL_SIZE];
4033 } sigframe;
4035 struct target_ucontext {
4036 target_ulong tuc_flags;
4037 struct target_ucontext *tuc_link;
4038 target_stack_t tuc_stack;
4039 target_sigregs tuc_mcontext;
4040 target_sigset_t tuc_sigmask; /* mask last for extensibility */
4043 typedef struct {
4044 uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
4045 uint8_t retcode[S390_SYSCALL_SIZE];
4046 struct target_siginfo info;
4047 struct target_ucontext uc;
4048 } rt_sigframe;
4050 static inline abi_ulong
4051 get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
4053 abi_ulong sp;
4055 /* Default to using normal stack */
4056 sp = env->regs[15];
4058 /* This is the X/Open sanctioned signal stack switching. */
4059 if (ka->sa_flags & TARGET_SA_ONSTACK) {
4060 if (!sas_ss_flags(sp)) {
4061 sp = target_sigaltstack_used.ss_sp +
4062 target_sigaltstack_used.ss_size;
4066 /* This is the legacy signal stack switching. */
4067 else if (/* FIXME !user_mode(regs) */ 0 &&
4068 !(ka->sa_flags & TARGET_SA_RESTORER) &&
4069 ka->sa_restorer) {
4070 sp = (abi_ulong) ka->sa_restorer;
4073 return (sp - frame_size) & -8ul;
4076 static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
4078 int i;
4079 //save_access_regs(current->thread.acrs); FIXME
4081 /* Copy a 'clean' PSW mask to the user to avoid leaking
4082 information about whether PER is currently on. */
4083 __put_user(env->psw.mask, &sregs->regs.psw.mask);
4084 __put_user(env->psw.addr, &sregs->regs.psw.addr);
4085 for (i = 0; i < 16; i++) {
4086 __put_user(env->regs[i], &sregs->regs.gprs[i]);
4088 for (i = 0; i < 16; i++) {
4089 __put_user(env->aregs[i], &sregs->regs.acrs[i]);
4092 * We have to store the fp registers to current->thread.fp_regs
4093 * to merge them with the emulated registers.
4095 //save_fp_regs(&current->thread.fp_regs); FIXME
4096 for (i = 0; i < 16; i++) {
4097 __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]);
4101 static void setup_frame(int sig, struct target_sigaction *ka,
4102 target_sigset_t *set, CPUS390XState *env)
4104 sigframe *frame;
4105 abi_ulong frame_addr;
4107 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4108 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4109 (unsigned long long)frame_addr);
4110 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4111 goto give_sigsegv;
4114 qemu_log("%s: 1\n", __FUNCTION__);
4115 __put_user(set->sig[0], &frame->sc.oldmask[0]);
4117 save_sigregs(env, &frame->sregs);
4119 __put_user((abi_ulong)(unsigned long)&frame->sregs,
4120 (abi_ulong *)&frame->sc.sregs);
4122 /* Set up to return from userspace. If provided, use a stub
4123 already in userspace. */
4124 if (ka->sa_flags & TARGET_SA_RESTORER) {
4125 env->regs[14] = (unsigned long)
4126 ka->sa_restorer | PSW_ADDR_AMODE;
4127 } else {
4128 env->regs[14] = (unsigned long)
4129 frame->retcode | PSW_ADDR_AMODE;
4130 __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
4131 (uint16_t *)(frame->retcode));
4134 /* Set up backchain. */
4135 __put_user(env->regs[15], (abi_ulong *) frame);
4137 /* Set up registers for signal handler */
4138 env->regs[15] = frame_addr;
4139 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4141 env->regs[2] = sig; //map_signal(sig);
4142 env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
4144 /* We forgot to include these in the sigcontext.
4145 To avoid breaking binary compatibility, they are passed as args. */
4146 env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
4147 env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
4149 /* Place signal number on stack to allow backtrace from handler. */
4150 __put_user(env->regs[2], (int *) &frame->signo);
4151 unlock_user_struct(frame, frame_addr, 1);
4152 return;
4154 give_sigsegv:
4155 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4156 force_sig(TARGET_SIGSEGV);
4159 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4160 target_siginfo_t *info,
4161 target_sigset_t *set, CPUS390XState *env)
4163 int i;
4164 rt_sigframe *frame;
4165 abi_ulong frame_addr;
4167 frame_addr = get_sigframe(ka, env, sizeof *frame);
4168 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4169 (unsigned long long)frame_addr);
4170 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4171 goto give_sigsegv;
4174 qemu_log("%s: 1\n", __FUNCTION__);
4175 tswap_siginfo(&frame->info, info);
4177 /* Create the ucontext. */
4178 __put_user(0, &frame->uc.tuc_flags);
4179 __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
4180 __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
4181 __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
4182 &frame->uc.tuc_stack.ss_flags);
4183 __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
4184 save_sigregs(env, &frame->uc.tuc_mcontext);
4185 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
4186 __put_user((abi_ulong)set->sig[i],
4187 (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
4190 /* Set up to return from userspace. If provided, use a stub
4191 already in userspace. */
4192 if (ka->sa_flags & TARGET_SA_RESTORER) {
4193 env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE;
4194 } else {
4195 env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE;
4196 __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
4197 (uint16_t *)(frame->retcode));
4200 /* Set up backchain. */
4201 __put_user(env->regs[15], (abi_ulong *) frame);
4203 /* Set up registers for signal handler */
4204 env->regs[15] = frame_addr;
4205 env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
4207 env->regs[2] = sig; //map_signal(sig);
4208 env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
4209 env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
4210 return;
4212 give_sigsegv:
4213 qemu_log("%s: give_sigsegv\n", __FUNCTION__);
4214 force_sig(TARGET_SIGSEGV);
4217 static int
4218 restore_sigregs(CPUS390XState *env, target_sigregs *sc)
4220 int err = 0;
4221 int i;
4223 for (i = 0; i < 16; i++) {
4224 __get_user(env->regs[i], &sc->regs.gprs[i]);
4227 __get_user(env->psw.mask, &sc->regs.psw.mask);
4228 qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n",
4229 __FUNCTION__, (unsigned long long)sc->regs.psw.addr,
4230 (unsigned long long)env->psw.addr);
4231 __get_user(env->psw.addr, &sc->regs.psw.addr);
4232 /* FIXME: 31-bit -> | PSW_ADDR_AMODE */
4234 for (i = 0; i < 16; i++) {
4235 __get_user(env->aregs[i], &sc->regs.acrs[i]);
4237 for (i = 0; i < 16; i++) {
4238 __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]);
4241 return err;
4244 long do_sigreturn(CPUS390XState *env)
4246 sigframe *frame;
4247 abi_ulong frame_addr = env->regs[15];
4248 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4249 (unsigned long long)frame_addr);
4250 target_sigset_t target_set;
4251 sigset_t set;
4253 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4254 goto badframe;
4256 __get_user(target_set.sig[0], &frame->sc.oldmask[0]);
4258 target_to_host_sigset_internal(&set, &target_set);
4259 do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4261 if (restore_sigregs(env, &frame->sregs)) {
4262 goto badframe;
4265 unlock_user_struct(frame, frame_addr, 0);
4266 return env->regs[2];
4268 badframe:
4269 force_sig(TARGET_SIGSEGV);
4270 return 0;
4273 long do_rt_sigreturn(CPUS390XState *env)
4275 rt_sigframe *frame;
4276 abi_ulong frame_addr = env->regs[15];
4277 qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__,
4278 (unsigned long long)frame_addr);
4279 sigset_t set;
4281 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4282 goto badframe;
4284 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
4286 do_sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */
4288 if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
4289 goto badframe;
4292 if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
4293 get_sp_from_cpustate(env)) == -EFAULT) {
4294 goto badframe;
4296 unlock_user_struct(frame, frame_addr, 0);
4297 return env->regs[2];
4299 badframe:
4300 unlock_user_struct(frame, frame_addr, 0);
4301 force_sig(TARGET_SIGSEGV);
4302 return 0;
4305 #elif defined(TARGET_PPC)
4307 /* Size of dummy stack frame allocated when calling signal handler.
4308 See arch/powerpc/include/asm/ptrace.h. */
4309 #if defined(TARGET_PPC64)
4310 #define SIGNAL_FRAMESIZE 128
4311 #else
4312 #define SIGNAL_FRAMESIZE 64
4313 #endif
4315 /* See arch/powerpc/include/asm/ucontext.h. Only used for 32-bit PPC;
4316 on 64-bit PPC, sigcontext and mcontext are one and the same. */
4317 struct target_mcontext {
4318 target_ulong mc_gregs[48];
4319 /* Includes fpscr. */
4320 uint64_t mc_fregs[33];
4321 target_ulong mc_pad[2];
4322 /* We need to handle Altivec and SPE at the same time, which no
4323 kernel needs to do. Fortunately, the kernel defines this bit to
4324 be Altivec-register-large all the time, rather than trying to
4325 twiddle it based on the specific platform. */
4326 union {
4327 /* SPE vector registers. One extra for SPEFSCR. */
4328 uint32_t spe[33];
4329 /* Altivec vector registers. The packing of VSCR and VRSAVE
4330 varies depending on whether we're PPC64 or not: PPC64 splits
4331 them apart; PPC32 stuffs them together. */
4332 #if defined(TARGET_PPC64)
4333 #define QEMU_NVRREG 34
4334 #else
4335 #define QEMU_NVRREG 33
4336 #endif
4337 ppc_avr_t altivec[QEMU_NVRREG];
4338 #undef QEMU_NVRREG
4339 } mc_vregs __attribute__((__aligned__(16)));
4342 /* See arch/powerpc/include/asm/sigcontext.h. */
4343 struct target_sigcontext {
4344 target_ulong _unused[4];
4345 int32_t signal;
4346 #if defined(TARGET_PPC64)
4347 int32_t pad0;
4348 #endif
4349 target_ulong handler;
4350 target_ulong oldmask;
4351 target_ulong regs; /* struct pt_regs __user * */
4352 #if defined(TARGET_PPC64)
4353 struct target_mcontext mcontext;
4354 #endif
4357 /* Indices for target_mcontext.mc_gregs, below.
4358 See arch/powerpc/include/asm/ptrace.h for details. */
4359 enum {
4360 TARGET_PT_R0 = 0,
4361 TARGET_PT_R1 = 1,
4362 TARGET_PT_R2 = 2,
4363 TARGET_PT_R3 = 3,
4364 TARGET_PT_R4 = 4,
4365 TARGET_PT_R5 = 5,
4366 TARGET_PT_R6 = 6,
4367 TARGET_PT_R7 = 7,
4368 TARGET_PT_R8 = 8,
4369 TARGET_PT_R9 = 9,
4370 TARGET_PT_R10 = 10,
4371 TARGET_PT_R11 = 11,
4372 TARGET_PT_R12 = 12,
4373 TARGET_PT_R13 = 13,
4374 TARGET_PT_R14 = 14,
4375 TARGET_PT_R15 = 15,
4376 TARGET_PT_R16 = 16,
4377 TARGET_PT_R17 = 17,
4378 TARGET_PT_R18 = 18,
4379 TARGET_PT_R19 = 19,
4380 TARGET_PT_R20 = 20,
4381 TARGET_PT_R21 = 21,
4382 TARGET_PT_R22 = 22,
4383 TARGET_PT_R23 = 23,
4384 TARGET_PT_R24 = 24,
4385 TARGET_PT_R25 = 25,
4386 TARGET_PT_R26 = 26,
4387 TARGET_PT_R27 = 27,
4388 TARGET_PT_R28 = 28,
4389 TARGET_PT_R29 = 29,
4390 TARGET_PT_R30 = 30,
4391 TARGET_PT_R31 = 31,
4392 TARGET_PT_NIP = 32,
4393 TARGET_PT_MSR = 33,
4394 TARGET_PT_ORIG_R3 = 34,
4395 TARGET_PT_CTR = 35,
4396 TARGET_PT_LNK = 36,
4397 TARGET_PT_XER = 37,
4398 TARGET_PT_CCR = 38,
4399 /* Yes, there are two registers with #39. One is 64-bit only. */
4400 TARGET_PT_MQ = 39,
4401 TARGET_PT_SOFTE = 39,
4402 TARGET_PT_TRAP = 40,
4403 TARGET_PT_DAR = 41,
4404 TARGET_PT_DSISR = 42,
4405 TARGET_PT_RESULT = 43,
4406 TARGET_PT_REGS_COUNT = 44
4410 struct target_ucontext {
4411 target_ulong tuc_flags;
4412 target_ulong tuc_link; /* struct ucontext __user * */
4413 struct target_sigaltstack tuc_stack;
4414 #if !defined(TARGET_PPC64)
4415 int32_t tuc_pad[7];
4416 target_ulong tuc_regs; /* struct mcontext __user *
4417 points to uc_mcontext field */
4418 #endif
4419 target_sigset_t tuc_sigmask;
4420 #if defined(TARGET_PPC64)
4421 target_sigset_t unused[15]; /* Allow for uc_sigmask growth */
4422 struct target_sigcontext tuc_sigcontext;
4423 #else
4424 int32_t tuc_maskext[30];
4425 int32_t tuc_pad2[3];
4426 struct target_mcontext tuc_mcontext;
4427 #endif
4430 /* See arch/powerpc/kernel/signal_32.c. */
4431 struct target_sigframe {
4432 struct target_sigcontext sctx;
4433 struct target_mcontext mctx;
4434 int32_t abigap[56];
4437 #if defined(TARGET_PPC64)
4439 #define TARGET_TRAMP_SIZE 6
4441 struct target_rt_sigframe {
4442 /* sys_rt_sigreturn requires the ucontext be the first field */
4443 struct target_ucontext uc;
4444 target_ulong _unused[2];
4445 uint32_t trampoline[TARGET_TRAMP_SIZE];
4446 target_ulong pinfo; /* struct siginfo __user * */
4447 target_ulong puc; /* void __user * */
4448 struct target_siginfo info;
4449 /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
4450 char abigap[288];
4451 } __attribute__((aligned(16)));
4453 #else
4455 struct target_rt_sigframe {
4456 struct target_siginfo info;
4457 struct target_ucontext uc;
4458 int32_t abigap[56];
4461 #endif
4463 #if defined(TARGET_PPC64)
4465 struct target_func_ptr {
4466 target_ulong entry;
4467 target_ulong toc;
4470 #endif
4472 /* We use the mc_pad field for the signal return trampoline. */
4473 #define tramp mc_pad
4475 /* See arch/powerpc/kernel/signal.c. */
4476 static target_ulong get_sigframe(struct target_sigaction *ka,
4477 CPUPPCState *env,
4478 int frame_size)
4480 target_ulong oldsp, newsp;
4482 oldsp = env->gpr[1];
4484 if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
4485 (sas_ss_flags(oldsp) == 0)) {
4486 oldsp = (target_sigaltstack_used.ss_sp
4487 + target_sigaltstack_used.ss_size);
4490 newsp = (oldsp - frame_size) & ~0xFUL;
4492 return newsp;
4495 static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
4497 target_ulong msr = env->msr;
4498 int i;
4499 target_ulong ccr = 0;
4501 /* In general, the kernel attempts to be intelligent about what it
4502 needs to save for Altivec/FP/SPE registers. We don't care that
4503 much, so we just go ahead and save everything. */
4505 /* Save general registers. */
4506 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4507 __put_user(env->gpr[i], &frame->mc_gregs[i]);
4509 __put_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP]);
4510 __put_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR]);
4511 __put_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK]);
4512 __put_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]);
4514 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4515 ccr |= env->crf[i] << (32 - ((i + 1) * 4));
4517 __put_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]);
4519 /* Save Altivec registers if necessary. */
4520 if (env->insns_flags & PPC_ALTIVEC) {
4521 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4522 ppc_avr_t *avr = &env->avr[i];
4523 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4525 __put_user(avr->u64[0], &vreg->u64[0]);
4526 __put_user(avr->u64[1], &vreg->u64[1]);
4528 /* Set MSR_VR in the saved MSR value to indicate that
4529 frame->mc_vregs contains valid data. */
4530 msr |= MSR_VR;
4531 __put_user((uint32_t)env->spr[SPR_VRSAVE],
4532 &frame->mc_vregs.altivec[32].u32[3]);
4535 /* Save floating point registers. */
4536 if (env->insns_flags & PPC_FLOAT) {
4537 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4538 __put_user(env->fpr[i], &frame->mc_fregs[i]);
4540 __put_user((uint64_t) env->fpscr, &frame->mc_fregs[32]);
4543 /* Save SPE registers. The kernel only saves the high half. */
4544 if (env->insns_flags & PPC_SPE) {
4545 #if defined(TARGET_PPC64)
4546 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4547 __put_user(env->gpr[i] >> 32, &frame->mc_vregs.spe[i]);
4549 #else
4550 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4551 __put_user(env->gprh[i], &frame->mc_vregs.spe[i]);
4553 #endif
4554 /* Set MSR_SPE in the saved MSR value to indicate that
4555 frame->mc_vregs contains valid data. */
4556 msr |= MSR_SPE;
4557 __put_user(env->spe_fscr, &frame->mc_vregs.spe[32]);
4560 /* Store MSR. */
4561 __put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]);
4564 static void encode_trampoline(int sigret, uint32_t *tramp)
4566 /* Set up the sigreturn trampoline: li r0,sigret; sc. */
4567 if (sigret) {
4568 __put_user(0x38000000 | sigret, &tramp[0]);
4569 __put_user(0x44000002, &tramp[1]);
4573 static void restore_user_regs(CPUPPCState *env,
4574 struct target_mcontext *frame, int sig)
4576 target_ulong save_r2 = 0;
4577 target_ulong msr;
4578 target_ulong ccr;
4580 int i;
4582 if (!sig) {
4583 save_r2 = env->gpr[2];
4586 /* Restore general registers. */
4587 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4588 __get_user(env->gpr[i], &frame->mc_gregs[i]);
4590 __get_user(env->nip, &frame->mc_gregs[TARGET_PT_NIP]);
4591 __get_user(env->ctr, &frame->mc_gregs[TARGET_PT_CTR]);
4592 __get_user(env->lr, &frame->mc_gregs[TARGET_PT_LNK]);
4593 __get_user(env->xer, &frame->mc_gregs[TARGET_PT_XER]);
4594 __get_user(ccr, &frame->mc_gregs[TARGET_PT_CCR]);
4596 for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
4597 env->crf[i] = (ccr >> (32 - ((i + 1) * 4))) & 0xf;
4600 if (!sig) {
4601 env->gpr[2] = save_r2;
4603 /* Restore MSR. */
4604 __get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]);
4606 /* If doing signal return, restore the previous little-endian mode. */
4607 if (sig)
4608 env->msr = (env->msr & ~MSR_LE) | (msr & MSR_LE);
4610 /* Restore Altivec registers if necessary. */
4611 if (env->insns_flags & PPC_ALTIVEC) {
4612 for (i = 0; i < ARRAY_SIZE(env->avr); i++) {
4613 ppc_avr_t *avr = &env->avr[i];
4614 ppc_avr_t *vreg = &frame->mc_vregs.altivec[i];
4616 __get_user(avr->u64[0], &vreg->u64[0]);
4617 __get_user(avr->u64[1], &vreg->u64[1]);
4619 /* Set MSR_VEC in the saved MSR value to indicate that
4620 frame->mc_vregs contains valid data. */
4621 __get_user(env->spr[SPR_VRSAVE],
4622 (target_ulong *)(&frame->mc_vregs.altivec[32].u32[3]));
4625 /* Restore floating point registers. */
4626 if (env->insns_flags & PPC_FLOAT) {
4627 uint64_t fpscr;
4628 for (i = 0; i < ARRAY_SIZE(env->fpr); i++) {
4629 __get_user(env->fpr[i], &frame->mc_fregs[i]);
4631 __get_user(fpscr, &frame->mc_fregs[32]);
4632 env->fpscr = (uint32_t) fpscr;
4635 /* Save SPE registers. The kernel only saves the high half. */
4636 if (env->insns_flags & PPC_SPE) {
4637 #if defined(TARGET_PPC64)
4638 for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
4639 uint32_t hi;
4641 __get_user(hi, &frame->mc_vregs.spe[i]);
4642 env->gpr[i] = ((uint64_t)hi << 32) | ((uint32_t) env->gpr[i]);
4644 #else
4645 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
4646 __get_user(env->gprh[i], &frame->mc_vregs.spe[i]);
4648 #endif
4649 __get_user(env->spe_fscr, &frame->mc_vregs.spe[32]);
4653 static void setup_frame(int sig, struct target_sigaction *ka,
4654 target_sigset_t *set, CPUPPCState *env)
4656 struct target_sigframe *frame;
4657 struct target_sigcontext *sc;
4658 target_ulong frame_addr, newsp;
4659 int err = 0;
4660 #if defined(TARGET_PPC64)
4661 struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
4662 #endif
4664 frame_addr = get_sigframe(ka, env, sizeof(*frame));
4665 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
4666 goto sigsegv;
4667 sc = &frame->sctx;
4669 __put_user(ka->_sa_handler, &sc->handler);
4670 __put_user(set->sig[0], &sc->oldmask);
4671 #if TARGET_ABI_BITS == 64
4672 __put_user(set->sig[0] >> 32, &sc->_unused[3]);
4673 #else
4674 __put_user(set->sig[1], &sc->_unused[3]);
4675 #endif
4676 __put_user(h2g(&frame->mctx), &sc->regs);
4677 __put_user(sig, &sc->signal);
4679 /* Save user regs. */
4680 save_user_regs(env, &frame->mctx);
4682 /* Construct the trampoline code on the stack. */
4683 encode_trampoline(TARGET_NR_sigreturn, (uint32_t *)&frame->mctx.tramp);
4685 /* The kernel checks for the presence of a VDSO here. We don't
4686 emulate a vdso, so use a sigreturn system call. */
4687 env->lr = (target_ulong) h2g(frame->mctx.tramp);
4689 /* Turn off all fp exceptions. */
4690 env->fpscr = 0;
4692 /* Create a stack frame for the caller of the handler. */
4693 newsp = frame_addr - SIGNAL_FRAMESIZE;
4694 err |= put_user(env->gpr[1], newsp, target_ulong);
4696 if (err)
4697 goto sigsegv;
4699 /* Set up registers for signal handler. */
4700 env->gpr[1] = newsp;
4701 env->gpr[3] = sig;
4702 env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
4704 #if defined(TARGET_PPC64)
4705 if (get_ppc64_abi(image) < 2) {
4706 /* ELFv1 PPC64 function pointers are pointers to OPD entries. */
4707 struct target_func_ptr *handler =
4708 (struct target_func_ptr *)g2h(ka->_sa_handler);
4709 env->nip = tswapl(handler->entry);
4710 env->gpr[2] = tswapl(handler->toc);
4711 } else {
4712 /* ELFv2 PPC64 function pointers are entry points, but R12
4713 * must also be set */
4714 env->nip = tswapl((target_ulong) ka->_sa_handler);
4715 env->gpr[12] = env->nip;
4717 #else
4718 env->nip = (target_ulong) ka->_sa_handler;
4719 #endif
4721 /* Signal handlers are entered in big-endian mode. */
4722 env->msr &= ~MSR_LE;
4724 unlock_user_struct(frame, frame_addr, 1);
4725 return;
4727 sigsegv:
4728 unlock_user_struct(frame, frame_addr, 1);
4729 qemu_log("segfaulting from setup_frame\n");
4730 force_sig(TARGET_SIGSEGV);
4733 static void setup_rt_frame(int sig, struct target_sigaction *ka,
4734 target_siginfo_t *info,
4735 target_sigset_t *set, CPUPPCState *env)
4737 struct target_rt_sigframe *rt_sf;
4738 uint32_t *trampptr = 0;
4739 struct target_mcontext *mctx = 0;
4740 target_ulong rt_sf_addr, newsp = 0;
4741 int i, err = 0;
4742 #if defined(TARGET_PPC64)
4743 struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
4744 #endif
4746 rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
4747 if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
4748 goto sigsegv;
4750 tswap_siginfo(&rt_sf->info, info);
4752 __put_user(0, &rt_sf->uc.tuc_flags);
4753 __put_user(0, &rt_sf->uc.tuc_link);
4754 __put_user((target_ulong)target_sigaltstack_used.ss_sp,
4755 &rt_sf->uc.tuc_stack.ss_sp);
4756 __put_user(sas_ss_flags(env->gpr[1]),
4757 &rt_sf->uc.tuc_stack.ss_flags);
4758 __put_user(target_sigaltstack_used.ss_size,
4759 &rt_sf->uc.tuc_stack.ss_size);
4760 #if !defined(TARGET_PPC64)
4761 __put_user(h2g (&rt_sf->uc.tuc_mcontext),
4762 &rt_sf->uc.tuc_regs);
4763 #endif
4764 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
4765 __put_user(set->sig[i], &rt_sf->uc.tuc_sigmask.sig[i]);
4768 #if defined(TARGET_PPC64)
4769 mctx = &rt_sf->uc.tuc_sigcontext.mcontext;
4770 trampptr = &rt_sf->trampoline[0];
4771 #else
4772 mctx = &rt_sf->uc.tuc_mcontext;
4773 trampptr = (uint32_t *)&rt_sf->uc.tuc_mcontext.tramp;
4774 #endif
4776 save_user_regs(env, mctx);
4777 encode_trampoline(TARGET_NR_rt_sigreturn, trampptr);
4779 /* The kernel checks for the presence of a VDSO here. We don't
4780 emulate a vdso, so use a sigreturn system call. */
4781 env->lr = (target_ulong) h2g(trampptr);
4783 /* Turn off all fp exceptions. */
4784 env->fpscr = 0;
4786 /* Create a stack frame for the caller of the handler. */
4787 newsp = rt_sf_addr - (SIGNAL_FRAMESIZE + 16);
4788 err |= put_user(env->gpr[1], newsp, target_ulong);
4790 if (err)
4791 goto sigsegv;
4793 /* Set up registers for signal handler. */
4794 env->gpr[1] = newsp;
4795 env->gpr[3] = (target_ulong) sig;
4796 env->gpr[4] = (target_ulong) h2g(&rt_sf->info);
4797 env->gpr[5] = (target_ulong) h2g(&rt_sf->uc);
4798 env->gpr[6] = (target_ulong) h2g(rt_sf);
4800 #if defined(TARGET_PPC64)
4801 if (get_ppc64_abi(image) < 2) {
4802 /* ELFv1 PPC64 function pointers are pointers to OPD entries. */
4803 struct target_func_ptr *handler =
4804 (struct target_func_ptr *)g2h(ka->_sa_handler);
4805 env->nip = tswapl(handler->entry);
4806 env->gpr[2] = tswapl(handler->toc);
4807 } else {
4808 /* ELFv2 PPC64 function pointers are entry points, but R12
4809 * must also be set */
4810 env->nip = tswapl((target_ulong) ka->_sa_handler);
4811 env->gpr[12] = env->nip;
4813 #else
4814 env->nip = (target_ulong) ka->_sa_handler;
4815 #endif
4817 /* Signal handlers are entered in big-endian mode. */
4818 env->msr &= ~MSR_LE;
4820 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4821 return;
4823 sigsegv:
4824 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4825 qemu_log("segfaulting from setup_rt_frame\n");
4826 force_sig(TARGET_SIGSEGV);
4830 long do_sigreturn(CPUPPCState *env)
4832 struct target_sigcontext *sc = NULL;
4833 struct target_mcontext *sr = NULL;
4834 target_ulong sr_addr = 0, sc_addr;
4835 sigset_t blocked;
4836 target_sigset_t set;
4838 sc_addr = env->gpr[1] + SIGNAL_FRAMESIZE;
4839 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1))
4840 goto sigsegv;
4842 #if defined(TARGET_PPC64)
4843 set.sig[0] = sc->oldmask + ((uint64_t)(sc->_unused[3]) << 32);
4844 #else
4845 __get_user(set.sig[0], &sc->oldmask);
4846 __get_user(set.sig[1], &sc->_unused[3]);
4847 #endif
4848 target_to_host_sigset_internal(&blocked, &set);
4849 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
4851 __get_user(sr_addr, &sc->regs);
4852 if (!lock_user_struct(VERIFY_READ, sr, sr_addr, 1))
4853 goto sigsegv;
4854 restore_user_regs(env, sr, 1);
4856 unlock_user_struct(sr, sr_addr, 1);
4857 unlock_user_struct(sc, sc_addr, 1);
4858 return -TARGET_QEMU_ESIGRETURN;
4860 sigsegv:
4861 unlock_user_struct(sr, sr_addr, 1);
4862 unlock_user_struct(sc, sc_addr, 1);
4863 qemu_log("segfaulting from do_sigreturn\n");
4864 force_sig(TARGET_SIGSEGV);
4865 return 0;
4868 /* See arch/powerpc/kernel/signal_32.c. */
4869 static int do_setcontext(struct target_ucontext *ucp, CPUPPCState *env, int sig)
4871 struct target_mcontext *mcp;
4872 target_ulong mcp_addr;
4873 sigset_t blocked;
4874 target_sigset_t set;
4876 if (copy_from_user(&set, h2g(ucp) + offsetof(struct target_ucontext, tuc_sigmask),
4877 sizeof (set)))
4878 return 1;
4880 #if defined(TARGET_PPC64)
4881 mcp_addr = h2g(ucp) +
4882 offsetof(struct target_ucontext, tuc_sigcontext.mcontext);
4883 #else
4884 __get_user(mcp_addr, &ucp->tuc_regs);
4885 #endif
4887 if (!lock_user_struct(VERIFY_READ, mcp, mcp_addr, 1))
4888 return 1;
4890 target_to_host_sigset_internal(&blocked, &set);
4891 do_sigprocmask(SIG_SETMASK, &blocked, NULL);
4892 restore_user_regs(env, mcp, sig);
4894 unlock_user_struct(mcp, mcp_addr, 1);
4895 return 0;
4898 long do_rt_sigreturn(CPUPPCState *env)
4900 struct target_rt_sigframe *rt_sf = NULL;
4901 target_ulong rt_sf_addr;
4903 rt_sf_addr = env->gpr[1] + SIGNAL_FRAMESIZE + 16;
4904 if (!lock_user_struct(VERIFY_READ, rt_sf, rt_sf_addr, 1))
4905 goto sigsegv;
4907 if (do_setcontext(&rt_sf->uc, env, 1))
4908 goto sigsegv;
4910 do_sigaltstack(rt_sf_addr
4911 + offsetof(struct target_rt_sigframe, uc.tuc_stack),
4912 0, env->gpr[1]);
4914 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4915 return -TARGET_QEMU_ESIGRETURN;
4917 sigsegv:
4918 unlock_user_struct(rt_sf, rt_sf_addr, 1);
4919 qemu_log("segfaulting from do_rt_sigreturn\n");
4920 force_sig(TARGET_SIGSEGV);
4921 return 0;
4924 #elif defined(TARGET_M68K)
4926 struct target_sigcontext {
4927 abi_ulong sc_mask;
4928 abi_ulong sc_usp;
4929 abi_ulong sc_d0;
4930 abi_ulong sc_d1;
4931 abi_ulong sc_a0;
4932 abi_ulong sc_a1;
4933 unsigned short sc_sr;
4934 abi_ulong sc_pc;
4937 struct target_sigframe
4939 abi_ulong pretcode;
4940 int sig;
4941 int code;
4942 abi_ulong psc;
4943 char retcode[8];
4944 abi_ulong extramask[TARGET_NSIG_WORDS-1];
4945 struct target_sigcontext sc;
4948 typedef int target_greg_t;
4949 #define TARGET_NGREG 18
4950 typedef target_greg_t target_gregset_t[TARGET_NGREG];
4952 typedef struct target_fpregset {
4953 int f_fpcntl[3];
4954 int f_fpregs[8*3];
4955 } target_fpregset_t;
4957 struct target_mcontext {
4958 int version;
4959 target_gregset_t gregs;
4960 target_fpregset_t fpregs;
4963 #define TARGET_MCONTEXT_VERSION 2
4965 struct target_ucontext {
4966 abi_ulong tuc_flags;
4967 abi_ulong tuc_link;
4968 target_stack_t tuc_stack;
4969 struct target_mcontext tuc_mcontext;
4970 abi_long tuc_filler[80];
4971 target_sigset_t tuc_sigmask;
4974 struct target_rt_sigframe
4976 abi_ulong pretcode;
4977 int sig;
4978 abi_ulong pinfo;
4979 abi_ulong puc;
4980 char retcode[8];
4981 struct target_siginfo info;
4982 struct target_ucontext uc;
4985 static void setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env,
4986 abi_ulong mask)
4988 __put_user(mask, &sc->sc_mask);
4989 __put_user(env->aregs[7], &sc->sc_usp);
4990 __put_user(env->dregs[0], &sc->sc_d0);
4991 __put_user(env->dregs[1], &sc->sc_d1);
4992 __put_user(env->aregs[0], &sc->sc_a0);
4993 __put_user(env->aregs[1], &sc->sc_a1);
4994 __put_user(env->sr, &sc->sc_sr);
4995 __put_user(env->pc, &sc->sc_pc);
4998 static void
4999 restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc, int *pd0)
5001 int temp;
5003 __get_user(env->aregs[7], &sc->sc_usp);
5004 __get_user(env->dregs[1], &sc->sc_d1);
5005 __get_user(env->aregs[0], &sc->sc_a0);
5006 __get_user(env->aregs[1], &sc->sc_a1);
5007 __get_user(env->pc, &sc->sc_pc);
5008 __get_user(temp, &sc->sc_sr);
5009 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5011 *pd0 = tswapl(sc->sc_d0);
5015 * Determine which stack to use..
5017 static inline abi_ulong
5018 get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
5019 size_t frame_size)
5021 unsigned long sp;
5023 sp = regs->aregs[7];
5025 /* This is the X/Open sanctioned signal stack switching. */
5026 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
5027 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5030 return ((sp - frame_size) & -8UL);
5033 static void setup_frame(int sig, struct target_sigaction *ka,
5034 target_sigset_t *set, CPUM68KState *env)
5036 struct target_sigframe *frame;
5037 abi_ulong frame_addr;
5038 abi_ulong retcode_addr;
5039 abi_ulong sc_addr;
5040 int i;
5042 frame_addr = get_sigframe(ka, env, sizeof *frame);
5043 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5044 goto give_sigsegv;
5046 __put_user(sig, &frame->sig);
5048 sc_addr = frame_addr + offsetof(struct target_sigframe, sc);
5049 __put_user(sc_addr, &frame->psc);
5051 setup_sigcontext(&frame->sc, env, set->sig[0]);
5053 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5054 __put_user(set->sig[i], &frame->extramask[i - 1]);
5057 /* Set up to return from userspace. */
5059 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5060 __put_user(retcode_addr, &frame->pretcode);
5062 /* moveq #,d0; trap #0 */
5064 __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),
5065 (uint32_t *)(frame->retcode));
5067 /* Set up to return from userspace */
5069 env->aregs[7] = frame_addr;
5070 env->pc = ka->_sa_handler;
5072 unlock_user_struct(frame, frame_addr, 1);
5073 return;
5075 give_sigsegv:
5076 force_sig(TARGET_SIGSEGV);
5079 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
5080 CPUM68KState *env)
5082 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5084 __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version);
5085 __put_user(env->dregs[0], &gregs[0]);
5086 __put_user(env->dregs[1], &gregs[1]);
5087 __put_user(env->dregs[2], &gregs[2]);
5088 __put_user(env->dregs[3], &gregs[3]);
5089 __put_user(env->dregs[4], &gregs[4]);
5090 __put_user(env->dregs[5], &gregs[5]);
5091 __put_user(env->dregs[6], &gregs[6]);
5092 __put_user(env->dregs[7], &gregs[7]);
5093 __put_user(env->aregs[0], &gregs[8]);
5094 __put_user(env->aregs[1], &gregs[9]);
5095 __put_user(env->aregs[2], &gregs[10]);
5096 __put_user(env->aregs[3], &gregs[11]);
5097 __put_user(env->aregs[4], &gregs[12]);
5098 __put_user(env->aregs[5], &gregs[13]);
5099 __put_user(env->aregs[6], &gregs[14]);
5100 __put_user(env->aregs[7], &gregs[15]);
5101 __put_user(env->pc, &gregs[16]);
5102 __put_user(env->sr, &gregs[17]);
5104 return 0;
5107 static inline int target_rt_restore_ucontext(CPUM68KState *env,
5108 struct target_ucontext *uc,
5109 int *pd0)
5111 int temp;
5112 target_greg_t *gregs = uc->tuc_mcontext.gregs;
5114 __get_user(temp, &uc->tuc_mcontext.version);
5115 if (temp != TARGET_MCONTEXT_VERSION)
5116 goto badframe;
5118 /* restore passed registers */
5119 __get_user(env->dregs[0], &gregs[0]);
5120 __get_user(env->dregs[1], &gregs[1]);
5121 __get_user(env->dregs[2], &gregs[2]);
5122 __get_user(env->dregs[3], &gregs[3]);
5123 __get_user(env->dregs[4], &gregs[4]);
5124 __get_user(env->dregs[5], &gregs[5]);
5125 __get_user(env->dregs[6], &gregs[6]);
5126 __get_user(env->dregs[7], &gregs[7]);
5127 __get_user(env->aregs[0], &gregs[8]);
5128 __get_user(env->aregs[1], &gregs[9]);
5129 __get_user(env->aregs[2], &gregs[10]);
5130 __get_user(env->aregs[3], &gregs[11]);
5131 __get_user(env->aregs[4], &gregs[12]);
5132 __get_user(env->aregs[5], &gregs[13]);
5133 __get_user(env->aregs[6], &gregs[14]);
5134 __get_user(env->aregs[7], &gregs[15]);
5135 __get_user(env->pc, &gregs[16]);
5136 __get_user(temp, &gregs[17]);
5137 env->sr = (env->sr & 0xff00) | (temp & 0xff);
5139 *pd0 = env->dregs[0];
5140 return 0;
5142 badframe:
5143 return 1;
5146 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5147 target_siginfo_t *info,
5148 target_sigset_t *set, CPUM68KState *env)
5150 struct target_rt_sigframe *frame;
5151 abi_ulong frame_addr;
5152 abi_ulong retcode_addr;
5153 abi_ulong info_addr;
5154 abi_ulong uc_addr;
5155 int err = 0;
5156 int i;
5158 frame_addr = get_sigframe(ka, env, sizeof *frame);
5159 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
5160 goto give_sigsegv;
5162 __put_user(sig, &frame->sig);
5164 info_addr = frame_addr + offsetof(struct target_rt_sigframe, info);
5165 __put_user(info_addr, &frame->pinfo);
5167 uc_addr = frame_addr + offsetof(struct target_rt_sigframe, uc);
5168 __put_user(uc_addr, &frame->puc);
5170 tswap_siginfo(&frame->info, info);
5172 /* Create the ucontext */
5174 __put_user(0, &frame->uc.tuc_flags);
5175 __put_user(0, &frame->uc.tuc_link);
5176 __put_user(target_sigaltstack_used.ss_sp,
5177 &frame->uc.tuc_stack.ss_sp);
5178 __put_user(sas_ss_flags(env->aregs[7]),
5179 &frame->uc.tuc_stack.ss_flags);
5180 __put_user(target_sigaltstack_used.ss_size,
5181 &frame->uc.tuc_stack.ss_size);
5182 err |= target_rt_setup_ucontext(&frame->uc, env);
5184 if (err)
5185 goto give_sigsegv;
5187 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
5188 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5191 /* Set up to return from userspace. */
5193 retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);
5194 __put_user(retcode_addr, &frame->pretcode);
5196 /* moveq #,d0; notb d0; trap #0 */
5198 __put_user(0x70004600 + ((TARGET_NR_rt_sigreturn ^ 0xff) << 16),
5199 (uint32_t *)(frame->retcode + 0));
5200 __put_user(0x4e40, (uint16_t *)(frame->retcode + 4));
5202 if (err)
5203 goto give_sigsegv;
5205 /* Set up to return from userspace */
5207 env->aregs[7] = frame_addr;
5208 env->pc = ka->_sa_handler;
5210 unlock_user_struct(frame, frame_addr, 1);
5211 return;
5213 give_sigsegv:
5214 unlock_user_struct(frame, frame_addr, 1);
5215 force_sig(TARGET_SIGSEGV);
5218 long do_sigreturn(CPUM68KState *env)
5220 struct target_sigframe *frame;
5221 abi_ulong frame_addr = env->aregs[7] - 4;
5222 target_sigset_t target_set;
5223 sigset_t set;
5224 int d0, i;
5226 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5227 goto badframe;
5229 /* set blocked signals */
5231 __get_user(target_set.sig[0], &frame->sc.sc_mask);
5233 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
5234 __get_user(target_set.sig[i], &frame->extramask[i - 1]);
5237 target_to_host_sigset_internal(&set, &target_set);
5238 do_sigprocmask(SIG_SETMASK, &set, NULL);
5240 /* restore registers */
5242 restore_sigcontext(env, &frame->sc, &d0);
5244 unlock_user_struct(frame, frame_addr, 0);
5245 return d0;
5247 badframe:
5248 force_sig(TARGET_SIGSEGV);
5249 return 0;
5252 long do_rt_sigreturn(CPUM68KState *env)
5254 struct target_rt_sigframe *frame;
5255 abi_ulong frame_addr = env->aregs[7] - 4;
5256 target_sigset_t target_set;
5257 sigset_t set;
5258 int d0;
5260 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
5261 goto badframe;
5263 target_to_host_sigset_internal(&set, &target_set);
5264 do_sigprocmask(SIG_SETMASK, &set, NULL);
5266 /* restore registers */
5268 if (target_rt_restore_ucontext(env, &frame->uc, &d0))
5269 goto badframe;
5271 if (do_sigaltstack(frame_addr +
5272 offsetof(struct target_rt_sigframe, uc.tuc_stack),
5273 0, get_sp_from_cpustate(env)) == -EFAULT)
5274 goto badframe;
5276 unlock_user_struct(frame, frame_addr, 0);
5277 return d0;
5279 badframe:
5280 unlock_user_struct(frame, frame_addr, 0);
5281 force_sig(TARGET_SIGSEGV);
5282 return 0;
5285 #elif defined(TARGET_ALPHA)
5287 struct target_sigcontext {
5288 abi_long sc_onstack;
5289 abi_long sc_mask;
5290 abi_long sc_pc;
5291 abi_long sc_ps;
5292 abi_long sc_regs[32];
5293 abi_long sc_ownedfp;
5294 abi_long sc_fpregs[32];
5295 abi_ulong sc_fpcr;
5296 abi_ulong sc_fp_control;
5297 abi_ulong sc_reserved1;
5298 abi_ulong sc_reserved2;
5299 abi_ulong sc_ssize;
5300 abi_ulong sc_sbase;
5301 abi_ulong sc_traparg_a0;
5302 abi_ulong sc_traparg_a1;
5303 abi_ulong sc_traparg_a2;
5304 abi_ulong sc_fp_trap_pc;
5305 abi_ulong sc_fp_trigger_sum;
5306 abi_ulong sc_fp_trigger_inst;
5309 struct target_ucontext {
5310 abi_ulong tuc_flags;
5311 abi_ulong tuc_link;
5312 abi_ulong tuc_osf_sigmask;
5313 target_stack_t tuc_stack;
5314 struct target_sigcontext tuc_mcontext;
5315 target_sigset_t tuc_sigmask;
5318 struct target_sigframe {
5319 struct target_sigcontext sc;
5320 unsigned int retcode[3];
5323 struct target_rt_sigframe {
5324 target_siginfo_t info;
5325 struct target_ucontext uc;
5326 unsigned int retcode[3];
5329 #define INSN_MOV_R30_R16 0x47fe0410
5330 #define INSN_LDI_R0 0x201f0000
5331 #define INSN_CALLSYS 0x00000083
5333 static void setup_sigcontext(struct target_sigcontext *sc, CPUAlphaState *env,
5334 abi_ulong frame_addr, target_sigset_t *set)
5336 int i;
5338 __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
5339 __put_user(set->sig[0], &sc->sc_mask);
5340 __put_user(env->pc, &sc->sc_pc);
5341 __put_user(8, &sc->sc_ps);
5343 for (i = 0; i < 31; ++i) {
5344 __put_user(env->ir[i], &sc->sc_regs[i]);
5346 __put_user(0, &sc->sc_regs[31]);
5348 for (i = 0; i < 31; ++i) {
5349 __put_user(env->fir[i], &sc->sc_fpregs[i]);
5351 __put_user(0, &sc->sc_fpregs[31]);
5352 __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
5354 __put_user(0, &sc->sc_traparg_a0); /* FIXME */
5355 __put_user(0, &sc->sc_traparg_a1); /* FIXME */
5356 __put_user(0, &sc->sc_traparg_a2); /* FIXME */
5359 static void restore_sigcontext(CPUAlphaState *env,
5360 struct target_sigcontext *sc)
5362 uint64_t fpcr;
5363 int i;
5365 __get_user(env->pc, &sc->sc_pc);
5367 for (i = 0; i < 31; ++i) {
5368 __get_user(env->ir[i], &sc->sc_regs[i]);
5370 for (i = 0; i < 31; ++i) {
5371 __get_user(env->fir[i], &sc->sc_fpregs[i]);
5374 __get_user(fpcr, &sc->sc_fpcr);
5375 cpu_alpha_store_fpcr(env, fpcr);
5378 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
5379 CPUAlphaState *env,
5380 unsigned long framesize)
5382 abi_ulong sp = env->ir[IR_SP];
5384 /* This is the X/Open sanctioned signal stack switching. */
5385 if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
5386 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
5388 return (sp - framesize) & -32;
5391 static void setup_frame(int sig, struct target_sigaction *ka,
5392 target_sigset_t *set, CPUAlphaState *env)
5394 abi_ulong frame_addr, r26;
5395 struct target_sigframe *frame;
5396 int err = 0;
5398 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5399 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5400 goto give_sigsegv;
5403 setup_sigcontext(&frame->sc, env, frame_addr, set);
5405 if (ka->sa_restorer) {
5406 r26 = ka->sa_restorer;
5407 } else {
5408 __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5409 __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
5410 &frame->retcode[1]);
5411 __put_user(INSN_CALLSYS, &frame->retcode[2]);
5412 /* imb() */
5413 r26 = frame_addr;
5416 unlock_user_struct(frame, frame_addr, 1);
5418 if (err) {
5419 give_sigsegv:
5420 if (sig == TARGET_SIGSEGV) {
5421 ka->_sa_handler = TARGET_SIG_DFL;
5423 force_sig(TARGET_SIGSEGV);
5426 env->ir[IR_RA] = r26;
5427 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5428 env->ir[IR_A0] = sig;
5429 env->ir[IR_A1] = 0;
5430 env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
5431 env->ir[IR_SP] = frame_addr;
5434 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5435 target_siginfo_t *info,
5436 target_sigset_t *set, CPUAlphaState *env)
5438 abi_ulong frame_addr, r26;
5439 struct target_rt_sigframe *frame;
5440 int i, err = 0;
5442 frame_addr = get_sigframe(ka, env, sizeof(*frame));
5443 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
5444 goto give_sigsegv;
5447 tswap_siginfo(&frame->info, info);
5449 __put_user(0, &frame->uc.tuc_flags);
5450 __put_user(0, &frame->uc.tuc_link);
5451 __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
5452 __put_user(target_sigaltstack_used.ss_sp,
5453 &frame->uc.tuc_stack.ss_sp);
5454 __put_user(sas_ss_flags(env->ir[IR_SP]),
5455 &frame->uc.tuc_stack.ss_flags);
5456 __put_user(target_sigaltstack_used.ss_size,
5457 &frame->uc.tuc_stack.ss_size);
5458 setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
5459 for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
5460 __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
5463 if (ka->sa_restorer) {
5464 r26 = ka->sa_restorer;
5465 } else {
5466 __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
5467 __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
5468 &frame->retcode[1]);
5469 __put_user(INSN_CALLSYS, &frame->retcode[2]);
5470 /* imb(); */
5471 r26 = frame_addr;
5474 if (err) {
5475 give_sigsegv:
5476 if (sig == TARGET_SIGSEGV) {
5477 ka->_sa_handler = TARGET_SIG_DFL;
5479 force_sig(TARGET_SIGSEGV);
5482 env->ir[IR_RA] = r26;
5483 env->ir[IR_PV] = env->pc = ka->_sa_handler;
5484 env->ir[IR_A0] = sig;
5485 env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
5486 env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
5487 env->ir[IR_SP] = frame_addr;
5490 long do_sigreturn(CPUAlphaState *env)
5492 struct target_sigcontext *sc;
5493 abi_ulong sc_addr = env->ir[IR_A0];
5494 target_sigset_t target_set;
5495 sigset_t set;
5497 if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
5498 goto badframe;
5501 target_sigemptyset(&target_set);
5502 __get_user(target_set.sig[0], &sc->sc_mask);
5504 target_to_host_sigset_internal(&set, &target_set);
5505 do_sigprocmask(SIG_SETMASK, &set, NULL);
5507 restore_sigcontext(env, sc);
5508 unlock_user_struct(sc, sc_addr, 0);
5509 return env->ir[IR_V0];
5511 badframe:
5512 force_sig(TARGET_SIGSEGV);
5515 long do_rt_sigreturn(CPUAlphaState *env)
5517 abi_ulong frame_addr = env->ir[IR_A0];
5518 struct target_rt_sigframe *frame;
5519 sigset_t set;
5521 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
5522 goto badframe;
5524 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
5525 do_sigprocmask(SIG_SETMASK, &set, NULL);
5527 restore_sigcontext(env, &frame->uc.tuc_mcontext);
5528 if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
5529 uc.tuc_stack),
5530 0, env->ir[IR_SP]) == -EFAULT) {
5531 goto badframe;
5534 unlock_user_struct(frame, frame_addr, 0);
5535 return env->ir[IR_V0];
5538 badframe:
5539 unlock_user_struct(frame, frame_addr, 0);
5540 force_sig(TARGET_SIGSEGV);
5543 #else
5545 static void setup_frame(int sig, struct target_sigaction *ka,
5546 target_sigset_t *set, CPUArchState *env)
5548 fprintf(stderr, "setup_frame: not implemented\n");
5551 static void setup_rt_frame(int sig, struct target_sigaction *ka,
5552 target_siginfo_t *info,
5553 target_sigset_t *set, CPUArchState *env)
5555 fprintf(stderr, "setup_rt_frame: not implemented\n");
5558 long do_sigreturn(CPUArchState *env)
5560 fprintf(stderr, "do_sigreturn: not implemented\n");
5561 return -TARGET_ENOSYS;
5564 long do_rt_sigreturn(CPUArchState *env)
5566 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
5567 return -TARGET_ENOSYS;
5570 #endif
5572 void process_pending_signals(CPUArchState *cpu_env)
5574 CPUState *cpu = ENV_GET_CPU(cpu_env);
5575 int sig;
5576 abi_ulong handler;
5577 sigset_t set, old_set;
5578 target_sigset_t target_old_set;
5579 struct emulated_sigtable *k;
5580 struct target_sigaction *sa;
5581 struct sigqueue *q;
5582 TaskState *ts = cpu->opaque;
5584 if (!ts->signal_pending)
5585 return;
5587 /* FIXME: This is not threadsafe. */
5588 k = ts->sigtab;
5589 for(sig = 1; sig <= TARGET_NSIG; sig++) {
5590 if (k->pending)
5591 goto handle_signal;
5592 k++;
5594 /* if no signal is pending, just return */
5595 ts->signal_pending = 0;
5596 return;
5598 handle_signal:
5599 #ifdef DEBUG_SIGNAL
5600 fprintf(stderr, "qemu: process signal %d\n", sig);
5601 #endif
5602 /* dequeue signal */
5603 q = k->first;
5604 k->first = q->next;
5605 if (!k->first)
5606 k->pending = 0;
5608 sig = gdb_handlesig(cpu, sig);
5609 if (!sig) {
5610 sa = NULL;
5611 handler = TARGET_SIG_IGN;
5612 } else {
5613 sa = &sigact_table[sig - 1];
5614 handler = sa->_sa_handler;
5617 if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {
5618 /* Guest has blocked SIGSEGV but we got one anyway. Assume this
5619 * is a forced SIGSEGV (ie one the kernel handles via force_sig_info
5620 * because it got a real MMU fault), and treat as if default handler.
5622 handler = TARGET_SIG_DFL;
5625 if (handler == TARGET_SIG_DFL) {
5626 /* default handler : ignore some signal. The other are job control or fatal */
5627 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
5628 kill(getpid(),SIGSTOP);
5629 } else if (sig != TARGET_SIGCHLD &&
5630 sig != TARGET_SIGURG &&
5631 sig != TARGET_SIGWINCH &&
5632 sig != TARGET_SIGCONT) {
5633 force_sig(sig);
5635 } else if (handler == TARGET_SIG_IGN) {
5636 /* ignore sig */
5637 } else if (handler == TARGET_SIG_ERR) {
5638 force_sig(sig);
5639 } else {
5640 /* compute the blocked signals during the handler execution */
5641 target_to_host_sigset(&set, &sa->sa_mask);
5642 /* SA_NODEFER indicates that the current signal should not be
5643 blocked during the handler */
5644 if (!(sa->sa_flags & TARGET_SA_NODEFER))
5645 sigaddset(&set, target_to_host_signal(sig));
5647 /* block signals in the handler using Linux */
5648 do_sigprocmask(SIG_BLOCK, &set, &old_set);
5649 /* save the previous blocked signal state to restore it at the
5650 end of the signal execution (see do_sigreturn) */
5651 host_to_target_sigset_internal(&target_old_set, &old_set);
5653 /* if the CPU is in VM86 mode, we restore the 32 bit values */
5654 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
5656 CPUX86State *env = cpu_env;
5657 if (env->eflags & VM_MASK)
5658 save_v86_state(env);
5660 #endif
5661 /* prepare the stack frame of the virtual CPU */
5662 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
5663 /* These targets do not have traditional signals. */
5664 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5665 #else
5666 if (sa->sa_flags & TARGET_SA_SIGINFO)
5667 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
5668 else
5669 setup_frame(sig, sa, &target_old_set, cpu_env);
5670 #endif
5671 if (sa->sa_flags & TARGET_SA_RESETHAND)
5672 sa->_sa_handler = TARGET_SIG_DFL;
5674 if (q != &k->info)
5675 free_sigqueue(cpu_env, q);