Revert r6408
[sniper_test.git] / linux-user / signal.c
blobfc37dc11ffd58494ad9bc1291998b33e1dea3ab4
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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 * MA 02110-1301, USA.
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include <errno.h>
28 #include <sys/ucontext.h>
30 #include "qemu.h"
31 #include "qemu-common.h"
32 #include "target_signal.h"
34 //#define DEBUG_SIGNAL
36 static struct target_sigaltstack target_sigaltstack_used = {
37 .ss_sp = 0,
38 .ss_size = 0,
39 .ss_flags = TARGET_SS_DISABLE,
42 static struct target_sigaction sigact_table[TARGET_NSIG];
44 static void host_signal_handler(int host_signum, siginfo_t *info,
45 void *puc);
47 static uint8_t host_to_target_signal_table[65] = {
48 [SIGHUP] = TARGET_SIGHUP,
49 [SIGINT] = TARGET_SIGINT,
50 [SIGQUIT] = TARGET_SIGQUIT,
51 [SIGILL] = TARGET_SIGILL,
52 [SIGTRAP] = TARGET_SIGTRAP,
53 [SIGABRT] = TARGET_SIGABRT,
54 /* [SIGIOT] = TARGET_SIGIOT,*/
55 [SIGBUS] = TARGET_SIGBUS,
56 [SIGFPE] = TARGET_SIGFPE,
57 [SIGKILL] = TARGET_SIGKILL,
58 [SIGUSR1] = TARGET_SIGUSR1,
59 [SIGSEGV] = TARGET_SIGSEGV,
60 [SIGUSR2] = TARGET_SIGUSR2,
61 [SIGPIPE] = TARGET_SIGPIPE,
62 [SIGALRM] = TARGET_SIGALRM,
63 [SIGTERM] = TARGET_SIGTERM,
64 #ifdef SIGSTKFLT
65 [SIGSTKFLT] = TARGET_SIGSTKFLT,
66 #endif
67 [SIGCHLD] = TARGET_SIGCHLD,
68 [SIGCONT] = TARGET_SIGCONT,
69 [SIGSTOP] = TARGET_SIGSTOP,
70 [SIGTSTP] = TARGET_SIGTSTP,
71 [SIGTTIN] = TARGET_SIGTTIN,
72 [SIGTTOU] = TARGET_SIGTTOU,
73 [SIGURG] = TARGET_SIGURG,
74 [SIGXCPU] = TARGET_SIGXCPU,
75 [SIGXFSZ] = TARGET_SIGXFSZ,
76 [SIGVTALRM] = TARGET_SIGVTALRM,
77 [SIGPROF] = TARGET_SIGPROF,
78 [SIGWINCH] = TARGET_SIGWINCH,
79 [SIGIO] = TARGET_SIGIO,
80 [SIGPWR] = TARGET_SIGPWR,
81 [SIGSYS] = TARGET_SIGSYS,
82 /* next signals stay the same */
83 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
84 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
85 To fix this properly we need to do manual signal delivery multiplexed
86 over a single host signal. */
87 [__SIGRTMIN] = __SIGRTMAX,
88 [__SIGRTMAX] = __SIGRTMIN,
90 static uint8_t target_to_host_signal_table[65];
92 static inline int on_sig_stack(unsigned long sp)
94 return (sp - target_sigaltstack_used.ss_sp
95 < target_sigaltstack_used.ss_size);
98 static inline int sas_ss_flags(unsigned long sp)
100 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
101 : on_sig_stack(sp) ? SS_ONSTACK : 0);
104 static inline int host_to_target_signal(int sig)
106 if (sig > 64)
107 return sig;
108 return host_to_target_signal_table[sig];
111 int target_to_host_signal(int sig)
113 if (sig > 64)
114 return sig;
115 return target_to_host_signal_table[sig];
118 static inline void target_sigemptyset(target_sigset_t *set)
120 memset(set, 0, sizeof(*set));
123 static inline void target_sigaddset(target_sigset_t *set, int signum)
125 signum--;
126 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
127 set->sig[signum / TARGET_NSIG_BPW] |= mask;
130 static inline int target_sigismember(const target_sigset_t *set, int signum)
132 signum--;
133 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
134 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
137 static void host_to_target_sigset_internal(target_sigset_t *d,
138 const sigset_t *s)
140 int i;
141 target_sigemptyset(d);
142 for (i = 1; i <= TARGET_NSIG; i++) {
143 if (sigismember(s, i)) {
144 target_sigaddset(d, host_to_target_signal(i));
149 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
151 target_sigset_t d1;
152 int i;
154 host_to_target_sigset_internal(&d1, s);
155 for(i = 0;i < TARGET_NSIG_WORDS; i++)
156 d->sig[i] = tswapl(d1.sig[i]);
159 static void target_to_host_sigset_internal(sigset_t *d,
160 const target_sigset_t *s)
162 int i;
163 sigemptyset(d);
164 for (i = 1; i <= TARGET_NSIG; i++) {
165 if (target_sigismember(s, i)) {
166 sigaddset(d, target_to_host_signal(i));
171 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
173 target_sigset_t s1;
174 int i;
176 for(i = 0;i < TARGET_NSIG_WORDS; i++)
177 s1.sig[i] = tswapl(s->sig[i]);
178 target_to_host_sigset_internal(d, &s1);
181 void host_to_target_old_sigset(abi_ulong *old_sigset,
182 const sigset_t *sigset)
184 target_sigset_t d;
185 host_to_target_sigset(&d, sigset);
186 *old_sigset = d.sig[0];
189 void target_to_host_old_sigset(sigset_t *sigset,
190 const abi_ulong *old_sigset)
192 target_sigset_t d;
193 int i;
195 d.sig[0] = *old_sigset;
196 for(i = 1;i < TARGET_NSIG_WORDS; i++)
197 d.sig[i] = 0;
198 target_to_host_sigset(sigset, &d);
201 /* siginfo conversion */
203 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
204 const siginfo_t *info)
206 int sig;
207 sig = host_to_target_signal(info->si_signo);
208 tinfo->si_signo = sig;
209 tinfo->si_errno = 0;
210 tinfo->si_code = info->si_code;
211 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
212 sig == SIGBUS || sig == SIGTRAP) {
213 /* should never come here, but who knows. The information for
214 the target is irrelevant */
215 tinfo->_sifields._sigfault._addr = 0;
216 } else if (sig == SIGIO) {
217 tinfo->_sifields._sigpoll._fd = info->si_fd;
218 } else if (sig >= TARGET_SIGRTMIN) {
219 tinfo->_sifields._rt._pid = info->si_pid;
220 tinfo->_sifields._rt._uid = info->si_uid;
221 /* XXX: potential problem if 64 bit */
222 tinfo->_sifields._rt._sigval.sival_ptr =
223 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
227 static void tswap_siginfo(target_siginfo_t *tinfo,
228 const target_siginfo_t *info)
230 int sig;
231 sig = info->si_signo;
232 tinfo->si_signo = tswap32(sig);
233 tinfo->si_errno = tswap32(info->si_errno);
234 tinfo->si_code = tswap32(info->si_code);
235 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
236 sig == SIGBUS || sig == SIGTRAP) {
237 tinfo->_sifields._sigfault._addr =
238 tswapl(info->_sifields._sigfault._addr);
239 } else if (sig == SIGIO) {
240 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
241 } else if (sig >= TARGET_SIGRTMIN) {
242 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
243 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
244 tinfo->_sifields._rt._sigval.sival_ptr =
245 tswapl(info->_sifields._rt._sigval.sival_ptr);
250 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
252 host_to_target_siginfo_noswap(tinfo, info);
253 tswap_siginfo(tinfo, tinfo);
256 /* XXX: we support only POSIX RT signals are used. */
257 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
258 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
260 info->si_signo = tswap32(tinfo->si_signo);
261 info->si_errno = tswap32(tinfo->si_errno);
262 info->si_code = tswap32(tinfo->si_code);
263 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
264 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
265 info->si_value.sival_ptr =
266 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
269 static int fatal_signal (int sig)
271 switch (sig) {
272 case TARGET_SIGCHLD:
273 case TARGET_SIGURG:
274 case TARGET_SIGWINCH:
275 /* Ignored by default. */
276 return 0;
277 case TARGET_SIGCONT:
278 case TARGET_SIGSTOP:
279 case TARGET_SIGTSTP:
280 case TARGET_SIGTTIN:
281 case TARGET_SIGTTOU:
282 /* Job control signals. */
283 return 0;
284 default:
285 return 1;
289 void signal_init(void)
291 struct sigaction act;
292 struct sigaction oact;
293 int i, j;
294 int host_sig;
296 /* generate signal conversion tables */
297 for(i = 1; i <= 64; i++) {
298 if (host_to_target_signal_table[i] == 0)
299 host_to_target_signal_table[i] = i;
301 for(i = 1; i <= 64; i++) {
302 j = host_to_target_signal_table[i];
303 target_to_host_signal_table[j] = i;
306 /* set all host signal handlers. ALL signals are blocked during
307 the handlers to serialize them. */
308 memset(sigact_table, 0, sizeof(sigact_table));
310 sigfillset(&act.sa_mask);
311 act.sa_flags = SA_SIGINFO;
312 act.sa_sigaction = host_signal_handler;
313 for(i = 1; i <= TARGET_NSIG; i++) {
314 host_sig = target_to_host_signal(i);
315 sigaction(host_sig, NULL, &oact);
316 if (oact.sa_sigaction == (void *)SIG_IGN) {
317 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
318 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
319 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
321 /* If there's already a handler installed then something has
322 gone horribly wrong, so don't even try to handle that case. */
323 /* Install some handlers for our own use. We need at least
324 SIGSEGV and SIGBUS, to detect exceptions. We can not just
325 trap all signals because it affects syscall interrupt
326 behavior. But do trap all default-fatal signals. */
327 if (fatal_signal (i))
328 sigaction(host_sig, &act, NULL);
332 /* signal queue handling */
334 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
336 TaskState *ts = env->opaque;
337 struct sigqueue *q = ts->first_free;
338 if (!q)
339 return NULL;
340 ts->first_free = q->next;
341 return q;
344 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
346 TaskState *ts = env->opaque;
347 q->next = ts->first_free;
348 ts->first_free = q;
351 /* abort execution with signal */
352 static void QEMU_NORETURN force_sig(int sig)
354 int host_sig;
355 host_sig = target_to_host_signal(sig);
356 fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
357 sig, strsignal(host_sig));
358 #if 1
359 gdb_signalled(thread_env, sig);
360 _exit(-host_sig);
361 #else
363 struct sigaction act;
364 sigemptyset(&act.sa_mask);
365 act.sa_flags = SA_SIGINFO;
366 act.sa_sigaction = SIG_DFL;
367 sigaction(SIGABRT, &act, NULL);
368 abort();
370 #endif
373 /* queue a signal so that it will be send to the virtual CPU as soon
374 as possible */
375 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
377 TaskState *ts = env->opaque;
378 struct emulated_sigtable *k;
379 struct sigqueue *q, **pq;
380 abi_ulong handler;
381 int queue;
383 #if defined(DEBUG_SIGNAL)
384 fprintf(stderr, "queue_signal: sig=%d\n",
385 sig);
386 #endif
387 k = &ts->sigtab[sig - 1];
388 queue = gdb_queuesig ();
389 handler = sigact_table[sig - 1]._sa_handler;
390 if (!queue && handler == TARGET_SIG_DFL) {
391 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
392 kill(getpid(),SIGSTOP);
393 return 0;
394 } else
395 /* default handler : ignore some signal. The other are fatal */
396 if (sig != TARGET_SIGCHLD &&
397 sig != TARGET_SIGURG &&
398 sig != TARGET_SIGWINCH &&
399 sig != TARGET_SIGCONT) {
400 force_sig(sig);
401 } else {
402 return 0; /* indicate ignored */
404 } else if (!queue && handler == TARGET_SIG_IGN) {
405 /* ignore signal */
406 return 0;
407 } else if (!queue && handler == TARGET_SIG_ERR) {
408 force_sig(sig);
409 } else {
410 pq = &k->first;
411 if (sig < TARGET_SIGRTMIN) {
412 /* if non real time signal, we queue exactly one signal */
413 if (!k->pending)
414 q = &k->info;
415 else
416 return 0;
417 } else {
418 if (!k->pending) {
419 /* first signal */
420 q = &k->info;
421 } else {
422 q = alloc_sigqueue(env);
423 if (!q)
424 return -EAGAIN;
425 while (*pq != NULL)
426 pq = &(*pq)->next;
429 *pq = q;
430 q->info = *info;
431 q->next = NULL;
432 k->pending = 1;
433 /* signal that a new signal is pending */
434 ts->signal_pending = 1;
435 return 1; /* indicates that the signal was queued */
439 static void host_signal_handler(int host_signum, siginfo_t *info,
440 void *puc)
442 int sig;
443 target_siginfo_t tinfo;
445 /* the CPU emulator uses some host signals to detect exceptions,
446 we forward to it some signals */
447 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
448 && info->si_code > 0) {
449 if (cpu_signal_handler(host_signum, info, puc))
450 return;
453 /* get target signal number */
454 sig = host_to_target_signal(host_signum);
455 if (sig < 1 || sig > TARGET_NSIG)
456 return;
457 #if defined(DEBUG_SIGNAL)
458 fprintf(stderr, "qemu: got signal %d\n", sig);
459 #endif
460 host_to_target_siginfo_noswap(&tinfo, info);
461 if (queue_signal(thread_env, sig, &tinfo) == 1) {
462 /* interrupt the virtual CPU as soon as possible */
463 cpu_exit(thread_env);
467 /* do_sigaltstack() returns target values and errnos. */
468 /* compare linux/kernel/signal.c:do_sigaltstack() */
469 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
471 int ret;
472 struct target_sigaltstack oss;
474 /* XXX: test errors */
475 if(uoss_addr)
477 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
478 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
479 __put_user(sas_ss_flags(sp), &oss.ss_flags);
482 if(uss_addr)
484 struct target_sigaltstack *uss;
485 struct target_sigaltstack ss;
487 ret = -TARGET_EFAULT;
488 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
489 || __get_user(ss.ss_sp, &uss->ss_sp)
490 || __get_user(ss.ss_size, &uss->ss_size)
491 || __get_user(ss.ss_flags, &uss->ss_flags))
492 goto out;
493 unlock_user_struct(uss, uss_addr, 0);
495 ret = -TARGET_EPERM;
496 if (on_sig_stack(sp))
497 goto out;
499 ret = -TARGET_EINVAL;
500 if (ss.ss_flags != TARGET_SS_DISABLE
501 && ss.ss_flags != TARGET_SS_ONSTACK
502 && ss.ss_flags != 0)
503 goto out;
505 if (ss.ss_flags == TARGET_SS_DISABLE) {
506 ss.ss_size = 0;
507 ss.ss_sp = 0;
508 } else {
509 ret = -TARGET_ENOMEM;
510 if (ss.ss_size < MINSIGSTKSZ)
511 goto out;
514 target_sigaltstack_used.ss_sp = ss.ss_sp;
515 target_sigaltstack_used.ss_size = ss.ss_size;
518 if (uoss_addr) {
519 ret = -TARGET_EFAULT;
520 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
521 goto out;
524 ret = 0;
525 out:
526 return ret;
529 /* do_sigaction() return host values and errnos */
530 int do_sigaction(int sig, const struct target_sigaction *act,
531 struct target_sigaction *oact)
533 struct target_sigaction *k;
534 struct sigaction act1;
535 int host_sig;
536 int ret = 0;
538 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
539 return -EINVAL;
540 k = &sigact_table[sig - 1];
541 #if defined(DEBUG_SIGNAL)
542 fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
543 sig, (int)act, (int)oact);
544 #endif
545 if (oact) {
546 oact->_sa_handler = tswapl(k->_sa_handler);
547 oact->sa_flags = tswapl(k->sa_flags);
548 #if !defined(TARGET_MIPS)
549 oact->sa_restorer = tswapl(k->sa_restorer);
550 #endif
551 oact->sa_mask = k->sa_mask;
553 if (act) {
554 /* FIXME: This is not threadsafe. */
555 k->_sa_handler = tswapl(act->_sa_handler);
556 k->sa_flags = tswapl(act->sa_flags);
557 #if !defined(TARGET_MIPS)
558 k->sa_restorer = tswapl(act->sa_restorer);
559 #endif
560 k->sa_mask = act->sa_mask;
562 /* we update the host linux signal state */
563 host_sig = target_to_host_signal(sig);
564 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
565 sigfillset(&act1.sa_mask);
566 act1.sa_flags = SA_SIGINFO;
567 if (k->sa_flags & TARGET_SA_RESTART)
568 act1.sa_flags |= SA_RESTART;
569 /* NOTE: it is important to update the host kernel signal
570 ignore state to avoid getting unexpected interrupted
571 syscalls */
572 if (k->_sa_handler == TARGET_SIG_IGN) {
573 act1.sa_sigaction = (void *)SIG_IGN;
574 } else if (k->_sa_handler == TARGET_SIG_DFL) {
575 if (fatal_signal (sig))
576 act1.sa_sigaction = host_signal_handler;
577 else
578 act1.sa_sigaction = (void *)SIG_DFL;
579 } else {
580 act1.sa_sigaction = host_signal_handler;
582 ret = sigaction(host_sig, &act1, NULL);
585 return ret;
588 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
589 const target_siginfo_t *info)
591 tswap_siginfo(tinfo, info);
592 return 0;
595 static inline int current_exec_domain_sig(int sig)
597 return /* current->exec_domain && current->exec_domain->signal_invmap
598 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
601 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
603 /* from the Linux kernel */
605 struct target_fpreg {
606 uint16_t significand[4];
607 uint16_t exponent;
610 struct target_fpxreg {
611 uint16_t significand[4];
612 uint16_t exponent;
613 uint16_t padding[3];
616 struct target_xmmreg {
617 abi_ulong element[4];
620 struct target_fpstate {
621 /* Regular FPU environment */
622 abi_ulong cw;
623 abi_ulong sw;
624 abi_ulong tag;
625 abi_ulong ipoff;
626 abi_ulong cssel;
627 abi_ulong dataoff;
628 abi_ulong datasel;
629 struct target_fpreg _st[8];
630 uint16_t status;
631 uint16_t magic; /* 0xffff = regular FPU data only */
633 /* FXSR FPU environment */
634 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
635 abi_ulong mxcsr;
636 abi_ulong reserved;
637 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
638 struct target_xmmreg _xmm[8];
639 abi_ulong padding[56];
642 #define X86_FXSR_MAGIC 0x0000
644 struct target_sigcontext {
645 uint16_t gs, __gsh;
646 uint16_t fs, __fsh;
647 uint16_t es, __esh;
648 uint16_t ds, __dsh;
649 abi_ulong edi;
650 abi_ulong esi;
651 abi_ulong ebp;
652 abi_ulong esp;
653 abi_ulong ebx;
654 abi_ulong edx;
655 abi_ulong ecx;
656 abi_ulong eax;
657 abi_ulong trapno;
658 abi_ulong err;
659 abi_ulong eip;
660 uint16_t cs, __csh;
661 abi_ulong eflags;
662 abi_ulong esp_at_signal;
663 uint16_t ss, __ssh;
664 abi_ulong fpstate; /* pointer */
665 abi_ulong oldmask;
666 abi_ulong cr2;
669 struct target_ucontext {
670 abi_ulong tuc_flags;
671 abi_ulong tuc_link;
672 target_stack_t tuc_stack;
673 struct target_sigcontext tuc_mcontext;
674 target_sigset_t tuc_sigmask; /* mask last for extensibility */
677 struct sigframe
679 abi_ulong pretcode;
680 int sig;
681 struct target_sigcontext sc;
682 struct target_fpstate fpstate;
683 abi_ulong extramask[TARGET_NSIG_WORDS-1];
684 char retcode[8];
687 struct rt_sigframe
689 abi_ulong pretcode;
690 int sig;
691 abi_ulong pinfo;
692 abi_ulong puc;
693 struct target_siginfo info;
694 struct target_ucontext uc;
695 struct target_fpstate fpstate;
696 char retcode[8];
700 * Set up a signal frame.
703 /* XXX: save x87 state */
704 static int
705 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
706 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
708 int err = 0;
709 uint16_t magic;
711 /* already locked in setup_frame() */
712 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
713 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
714 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
715 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
716 err |= __put_user(env->regs[R_EDI], &sc->edi);
717 err |= __put_user(env->regs[R_ESI], &sc->esi);
718 err |= __put_user(env->regs[R_EBP], &sc->ebp);
719 err |= __put_user(env->regs[R_ESP], &sc->esp);
720 err |= __put_user(env->regs[R_EBX], &sc->ebx);
721 err |= __put_user(env->regs[R_EDX], &sc->edx);
722 err |= __put_user(env->regs[R_ECX], &sc->ecx);
723 err |= __put_user(env->regs[R_EAX], &sc->eax);
724 err |= __put_user(env->exception_index, &sc->trapno);
725 err |= __put_user(env->error_code, &sc->err);
726 err |= __put_user(env->eip, &sc->eip);
727 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
728 err |= __put_user(env->eflags, &sc->eflags);
729 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
730 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
732 cpu_x86_fsave(env, fpstate_addr, 1);
733 fpstate->status = fpstate->sw;
734 magic = 0xffff;
735 err |= __put_user(magic, &fpstate->magic);
736 err |= __put_user(fpstate_addr, &sc->fpstate);
738 /* non-iBCS2 extensions.. */
739 err |= __put_user(mask, &sc->oldmask);
740 err |= __put_user(env->cr[2], &sc->cr2);
741 return err;
745 * Determine which stack to use..
748 static inline abi_ulong
749 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
751 unsigned long esp;
753 /* Default to using normal stack */
754 esp = env->regs[R_ESP];
755 /* This is the X/Open sanctioned signal stack switching. */
756 if (ka->sa_flags & TARGET_SA_ONSTACK) {
757 if (sas_ss_flags(esp) == 0)
758 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
761 /* This is the legacy signal stack switching. */
762 else
763 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
764 !(ka->sa_flags & TARGET_SA_RESTORER) &&
765 ka->sa_restorer) {
766 esp = (unsigned long) ka->sa_restorer;
768 return (esp - frame_size) & -8ul;
771 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
772 static void setup_frame(int sig, struct target_sigaction *ka,
773 target_sigset_t *set, CPUX86State *env)
775 abi_ulong frame_addr;
776 struct sigframe *frame;
777 int i, err = 0;
779 frame_addr = get_sigframe(ka, env, sizeof(*frame));
781 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
782 goto give_sigsegv;
784 err |= __put_user(current_exec_domain_sig(sig),
785 &frame->sig);
786 if (err)
787 goto give_sigsegv;
789 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
790 frame_addr + offsetof(struct sigframe, fpstate));
791 if (err)
792 goto give_sigsegv;
794 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
795 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
796 goto give_sigsegv;
799 /* Set up to return from userspace. If provided, use a stub
800 already in userspace. */
801 if (ka->sa_flags & TARGET_SA_RESTORER) {
802 err |= __put_user(ka->sa_restorer, &frame->pretcode);
803 } else {
804 uint16_t val16;
805 abi_ulong retcode_addr;
806 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
807 err |= __put_user(retcode_addr, &frame->pretcode);
808 /* This is popl %eax ; movl $,%eax ; int $0x80 */
809 val16 = 0xb858;
810 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
811 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
812 val16 = 0x80cd;
813 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
816 if (err)
817 goto give_sigsegv;
819 /* Set up registers for signal handler */
820 env->regs[R_ESP] = frame_addr;
821 env->eip = ka->_sa_handler;
823 cpu_x86_load_seg(env, R_DS, __USER_DS);
824 cpu_x86_load_seg(env, R_ES, __USER_DS);
825 cpu_x86_load_seg(env, R_SS, __USER_DS);
826 cpu_x86_load_seg(env, R_CS, __USER_CS);
827 env->eflags &= ~TF_MASK;
829 unlock_user_struct(frame, frame_addr, 1);
831 return;
833 give_sigsegv:
834 unlock_user_struct(frame, frame_addr, 1);
835 if (sig == TARGET_SIGSEGV)
836 ka->_sa_handler = TARGET_SIG_DFL;
837 force_sig(TARGET_SIGSEGV /* , current */);
840 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
841 static void setup_rt_frame(int sig, struct target_sigaction *ka,
842 target_siginfo_t *info,
843 target_sigset_t *set, CPUX86State *env)
845 abi_ulong frame_addr, addr;
846 struct rt_sigframe *frame;
847 int i, err = 0;
849 frame_addr = get_sigframe(ka, env, sizeof(*frame));
851 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
852 goto give_sigsegv;
854 err |= __put_user(current_exec_domain_sig(sig),
855 &frame->sig);
856 addr = frame_addr + offsetof(struct rt_sigframe, info);
857 err |= __put_user(addr, &frame->pinfo);
858 addr = frame_addr + offsetof(struct rt_sigframe, uc);
859 err |= __put_user(addr, &frame->puc);
860 err |= copy_siginfo_to_user(&frame->info, info);
861 if (err)
862 goto give_sigsegv;
864 /* Create the ucontext. */
865 err |= __put_user(0, &frame->uc.tuc_flags);
866 err |= __put_user(0, &frame->uc.tuc_link);
867 err |= __put_user(target_sigaltstack_used.ss_sp,
868 &frame->uc.tuc_stack.ss_sp);
869 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
870 &frame->uc.tuc_stack.ss_flags);
871 err |= __put_user(target_sigaltstack_used.ss_size,
872 &frame->uc.tuc_stack.ss_size);
873 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
874 env, set->sig[0],
875 frame_addr + offsetof(struct rt_sigframe, fpstate));
876 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
877 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
878 goto give_sigsegv;
881 /* Set up to return from userspace. If provided, use a stub
882 already in userspace. */
883 if (ka->sa_flags & TARGET_SA_RESTORER) {
884 err |= __put_user(ka->sa_restorer, &frame->pretcode);
885 } else {
886 uint16_t val16;
887 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
888 err |= __put_user(addr, &frame->pretcode);
889 /* This is movl $,%eax ; int $0x80 */
890 err |= __put_user(0xb8, (char *)(frame->retcode+0));
891 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
892 val16 = 0x80cd;
893 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
896 if (err)
897 goto give_sigsegv;
899 /* Set up registers for signal handler */
900 env->regs[R_ESP] = frame_addr;
901 env->eip = ka->_sa_handler;
903 cpu_x86_load_seg(env, R_DS, __USER_DS);
904 cpu_x86_load_seg(env, R_ES, __USER_DS);
905 cpu_x86_load_seg(env, R_SS, __USER_DS);
906 cpu_x86_load_seg(env, R_CS, __USER_CS);
907 env->eflags &= ~TF_MASK;
909 unlock_user_struct(frame, frame_addr, 1);
911 return;
913 give_sigsegv:
914 unlock_user_struct(frame, frame_addr, 1);
915 if (sig == TARGET_SIGSEGV)
916 ka->_sa_handler = TARGET_SIG_DFL;
917 force_sig(TARGET_SIGSEGV /* , current */);
920 static int
921 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
923 unsigned int err = 0;
924 abi_ulong fpstate_addr;
925 unsigned int tmpflags;
927 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
928 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
929 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
930 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
932 env->regs[R_EDI] = tswapl(sc->edi);
933 env->regs[R_ESI] = tswapl(sc->esi);
934 env->regs[R_EBP] = tswapl(sc->ebp);
935 env->regs[R_ESP] = tswapl(sc->esp);
936 env->regs[R_EBX] = tswapl(sc->ebx);
937 env->regs[R_EDX] = tswapl(sc->edx);
938 env->regs[R_ECX] = tswapl(sc->ecx);
939 env->eip = tswapl(sc->eip);
941 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
942 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
944 tmpflags = tswapl(sc->eflags);
945 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
946 // regs->orig_eax = -1; /* disable syscall checks */
948 fpstate_addr = tswapl(sc->fpstate);
949 if (fpstate_addr != 0) {
950 if (!access_ok(VERIFY_READ, fpstate_addr,
951 sizeof(struct target_fpstate)))
952 goto badframe;
953 cpu_x86_frstor(env, fpstate_addr, 1);
956 *peax = tswapl(sc->eax);
957 return err;
958 badframe:
959 return 1;
962 long do_sigreturn(CPUX86State *env)
964 struct sigframe *frame;
965 abi_ulong frame_addr = env->regs[R_ESP] - 8;
966 target_sigset_t target_set;
967 sigset_t set;
968 int eax, i;
970 #if defined(DEBUG_SIGNAL)
971 fprintf(stderr, "do_sigreturn\n");
972 #endif
973 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
974 goto badframe;
975 /* set blocked signals */
976 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
977 goto badframe;
978 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
979 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
980 goto badframe;
983 target_to_host_sigset_internal(&set, &target_set);
984 sigprocmask(SIG_SETMASK, &set, NULL);
986 /* restore registers */
987 if (restore_sigcontext(env, &frame->sc, &eax))
988 goto badframe;
989 unlock_user_struct(frame, frame_addr, 0);
990 return eax;
992 badframe:
993 unlock_user_struct(frame, frame_addr, 0);
994 force_sig(TARGET_SIGSEGV);
995 return 0;
998 long do_rt_sigreturn(CPUX86State *env)
1000 abi_ulong frame_addr;
1001 struct rt_sigframe *frame;
1002 sigset_t set;
1003 int eax;
1005 frame_addr = env->regs[R_ESP] - 4;
1006 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1007 goto badframe;
1008 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1009 sigprocmask(SIG_SETMASK, &set, NULL);
1011 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1012 goto badframe;
1014 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1015 get_sp_from_cpustate(env)) == -EFAULT)
1016 goto badframe;
1018 unlock_user_struct(frame, frame_addr, 0);
1019 return eax;
1021 badframe:
1022 unlock_user_struct(frame, frame_addr, 0);
1023 force_sig(TARGET_SIGSEGV);
1024 return 0;
1027 #elif defined(TARGET_ARM)
1029 struct target_sigcontext {
1030 abi_ulong trap_no;
1031 abi_ulong error_code;
1032 abi_ulong oldmask;
1033 abi_ulong arm_r0;
1034 abi_ulong arm_r1;
1035 abi_ulong arm_r2;
1036 abi_ulong arm_r3;
1037 abi_ulong arm_r4;
1038 abi_ulong arm_r5;
1039 abi_ulong arm_r6;
1040 abi_ulong arm_r7;
1041 abi_ulong arm_r8;
1042 abi_ulong arm_r9;
1043 abi_ulong arm_r10;
1044 abi_ulong arm_fp;
1045 abi_ulong arm_ip;
1046 abi_ulong arm_sp;
1047 abi_ulong arm_lr;
1048 abi_ulong arm_pc;
1049 abi_ulong arm_cpsr;
1050 abi_ulong fault_address;
1053 struct target_ucontext_v1 {
1054 abi_ulong tuc_flags;
1055 abi_ulong tuc_link;
1056 target_stack_t tuc_stack;
1057 struct target_sigcontext tuc_mcontext;
1058 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1061 struct target_ucontext_v2 {
1062 abi_ulong tuc_flags;
1063 abi_ulong tuc_link;
1064 target_stack_t tuc_stack;
1065 struct target_sigcontext tuc_mcontext;
1066 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1067 char __unused[128 - sizeof(sigset_t)];
1068 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1071 struct sigframe_v1
1073 struct target_sigcontext sc;
1074 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1075 abi_ulong retcode;
1078 struct sigframe_v2
1080 struct target_ucontext_v2 uc;
1081 abi_ulong retcode;
1084 struct rt_sigframe_v1
1086 abi_ulong pinfo;
1087 abi_ulong puc;
1088 struct target_siginfo info;
1089 struct target_ucontext_v1 uc;
1090 abi_ulong retcode;
1093 struct rt_sigframe_v2
1095 struct target_siginfo info;
1096 struct target_ucontext_v2 uc;
1097 abi_ulong retcode;
1100 #define TARGET_CONFIG_CPU_32 1
1103 * For ARM syscalls, we encode the syscall number into the instruction.
1105 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1106 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1109 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1110 * need two 16-bit instructions.
1112 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1113 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1115 static const abi_ulong retcodes[4] = {
1116 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1117 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1121 #define __get_user_error(x,p,e) __get_user(x, p)
1123 static inline int valid_user_regs(CPUState *regs)
1125 return 1;
1128 static void
1129 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1130 CPUState *env, abi_ulong mask)
1132 __put_user(env->regs[0], &sc->arm_r0);
1133 __put_user(env->regs[1], &sc->arm_r1);
1134 __put_user(env->regs[2], &sc->arm_r2);
1135 __put_user(env->regs[3], &sc->arm_r3);
1136 __put_user(env->regs[4], &sc->arm_r4);
1137 __put_user(env->regs[5], &sc->arm_r5);
1138 __put_user(env->regs[6], &sc->arm_r6);
1139 __put_user(env->regs[7], &sc->arm_r7);
1140 __put_user(env->regs[8], &sc->arm_r8);
1141 __put_user(env->regs[9], &sc->arm_r9);
1142 __put_user(env->regs[10], &sc->arm_r10);
1143 __put_user(env->regs[11], &sc->arm_fp);
1144 __put_user(env->regs[12], &sc->arm_ip);
1145 __put_user(env->regs[13], &sc->arm_sp);
1146 __put_user(env->regs[14], &sc->arm_lr);
1147 __put_user(env->regs[15], &sc->arm_pc);
1148 #ifdef TARGET_CONFIG_CPU_32
1149 __put_user(cpsr_read(env), &sc->arm_cpsr);
1150 #endif
1152 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1153 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1154 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1155 __put_user(mask, &sc->oldmask);
1158 static inline abi_ulong
1159 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1161 unsigned long sp = regs->regs[13];
1164 * This is the X/Open sanctioned signal stack switching.
1166 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1167 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1169 * ATPCS B01 mandates 8-byte alignment
1171 return (sp - framesize) & ~7;
1174 static int
1175 setup_return(CPUState *env, struct target_sigaction *ka,
1176 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1178 abi_ulong handler = ka->_sa_handler;
1179 abi_ulong retcode;
1180 int thumb = handler & 1;
1182 if (ka->sa_flags & TARGET_SA_RESTORER) {
1183 retcode = ka->sa_restorer;
1184 } else {
1185 unsigned int idx = thumb;
1187 if (ka->sa_flags & TARGET_SA_SIGINFO)
1188 idx += 2;
1190 if (__put_user(retcodes[idx], rc))
1191 return 1;
1192 #if 0
1193 flush_icache_range((abi_ulong)rc,
1194 (abi_ulong)(rc + 1));
1195 #endif
1196 retcode = rc_addr + thumb;
1199 env->regs[0] = usig;
1200 env->regs[13] = frame_addr;
1201 env->regs[14] = retcode;
1202 env->regs[15] = handler & (thumb ? ~1 : ~3);
1203 env->thumb = thumb;
1205 #if 0
1206 #ifdef TARGET_CONFIG_CPU_32
1207 env->cpsr = cpsr;
1208 #endif
1209 #endif
1211 return 0;
1214 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1215 target_sigset_t *set, CPUState *env)
1217 struct target_sigaltstack stack;
1218 int i;
1220 /* Clear all the bits of the ucontext we don't use. */
1221 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1223 memset(&stack, 0, sizeof(stack));
1224 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1225 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1226 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1227 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1229 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1230 /* FIXME: Save coprocessor signal frame. */
1231 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1232 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1236 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1237 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1238 target_sigset_t *set, CPUState *regs)
1240 struct sigframe_v1 *frame;
1241 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1242 int i;
1244 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1245 return;
1247 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1249 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1250 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1251 goto end;
1254 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1255 frame_addr + offsetof(struct sigframe_v1, retcode));
1257 end:
1258 unlock_user_struct(frame, frame_addr, 1);
1261 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1262 target_sigset_t *set, CPUState *regs)
1264 struct sigframe_v2 *frame;
1265 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1267 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1268 return;
1270 setup_sigframe_v2(&frame->uc, set, regs);
1272 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1273 frame_addr + offsetof(struct sigframe_v2, retcode));
1275 unlock_user_struct(frame, frame_addr, 1);
1278 static void setup_frame(int usig, struct target_sigaction *ka,
1279 target_sigset_t *set, CPUState *regs)
1281 if (get_osversion() >= 0x020612) {
1282 setup_frame_v2(usig, ka, set, regs);
1283 } else {
1284 setup_frame_v1(usig, ka, set, regs);
1288 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1289 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1290 target_siginfo_t *info,
1291 target_sigset_t *set, CPUState *env)
1293 struct rt_sigframe_v1 *frame;
1294 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1295 struct target_sigaltstack stack;
1296 int i;
1297 abi_ulong info_addr, uc_addr;
1299 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1300 return /* 1 */;
1302 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1303 __put_user(info_addr, &frame->pinfo);
1304 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1305 __put_user(uc_addr, &frame->puc);
1306 copy_siginfo_to_user(&frame->info, info);
1308 /* Clear all the bits of the ucontext we don't use. */
1309 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1311 memset(&stack, 0, sizeof(stack));
1312 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1313 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1314 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1315 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1317 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1318 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1319 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1320 goto end;
1323 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1324 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1326 env->regs[1] = info_addr;
1327 env->regs[2] = uc_addr;
1329 end:
1330 unlock_user_struct(frame, frame_addr, 1);
1333 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1334 target_siginfo_t *info,
1335 target_sigset_t *set, CPUState *env)
1337 struct rt_sigframe_v2 *frame;
1338 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1339 abi_ulong info_addr, uc_addr;
1341 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1342 return /* 1 */;
1344 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1345 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1346 copy_siginfo_to_user(&frame->info, info);
1348 setup_sigframe_v2(&frame->uc, set, env);
1350 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1351 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1353 env->regs[1] = info_addr;
1354 env->regs[2] = uc_addr;
1356 unlock_user_struct(frame, frame_addr, 1);
1359 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1360 target_siginfo_t *info,
1361 target_sigset_t *set, CPUState *env)
1363 if (get_osversion() >= 0x020612) {
1364 setup_rt_frame_v2(usig, ka, info, set, env);
1365 } else {
1366 setup_rt_frame_v1(usig, ka, info, set, env);
1370 static int
1371 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1373 int err = 0;
1374 uint32_t cpsr;
1376 __get_user_error(env->regs[0], &sc->arm_r0, err);
1377 __get_user_error(env->regs[1], &sc->arm_r1, err);
1378 __get_user_error(env->regs[2], &sc->arm_r2, err);
1379 __get_user_error(env->regs[3], &sc->arm_r3, err);
1380 __get_user_error(env->regs[4], &sc->arm_r4, err);
1381 __get_user_error(env->regs[5], &sc->arm_r5, err);
1382 __get_user_error(env->regs[6], &sc->arm_r6, err);
1383 __get_user_error(env->regs[7], &sc->arm_r7, err);
1384 __get_user_error(env->regs[8], &sc->arm_r8, err);
1385 __get_user_error(env->regs[9], &sc->arm_r9, err);
1386 __get_user_error(env->regs[10], &sc->arm_r10, err);
1387 __get_user_error(env->regs[11], &sc->arm_fp, err);
1388 __get_user_error(env->regs[12], &sc->arm_ip, err);
1389 __get_user_error(env->regs[13], &sc->arm_sp, err);
1390 __get_user_error(env->regs[14], &sc->arm_lr, err);
1391 __get_user_error(env->regs[15], &sc->arm_pc, err);
1392 #ifdef TARGET_CONFIG_CPU_32
1393 __get_user_error(cpsr, &sc->arm_cpsr, err);
1394 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1395 #endif
1397 err |= !valid_user_regs(env);
1399 return err;
1402 static long do_sigreturn_v1(CPUState *env)
1404 abi_ulong frame_addr;
1405 struct sigframe_v1 *frame;
1406 target_sigset_t set;
1407 sigset_t host_set;
1408 int i;
1411 * Since we stacked the signal on a 64-bit boundary,
1412 * then 'sp' should be word aligned here. If it's
1413 * not, then the user is trying to mess with us.
1415 if (env->regs[13] & 7)
1416 goto badframe;
1418 frame_addr = env->regs[13];
1419 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1420 goto badframe;
1422 if (__get_user(set.sig[0], &frame->sc.oldmask))
1423 goto badframe;
1424 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1425 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1426 goto badframe;
1429 target_to_host_sigset_internal(&host_set, &set);
1430 sigprocmask(SIG_SETMASK, &host_set, NULL);
1432 if (restore_sigcontext(env, &frame->sc))
1433 goto badframe;
1435 #if 0
1436 /* Send SIGTRAP if we're single-stepping */
1437 if (ptrace_cancel_bpt(current))
1438 send_sig(SIGTRAP, current, 1);
1439 #endif
1440 unlock_user_struct(frame, frame_addr, 0);
1441 return env->regs[0];
1443 badframe:
1444 unlock_user_struct(frame, frame_addr, 0);
1445 force_sig(SIGSEGV /* , current */);
1446 return 0;
1449 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1450 struct target_ucontext_v2 *uc)
1452 sigset_t host_set;
1454 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1455 sigprocmask(SIG_SETMASK, &host_set, NULL);
1457 if (restore_sigcontext(env, &uc->tuc_mcontext))
1458 return 1;
1460 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1461 return 1;
1463 #if 0
1464 /* Send SIGTRAP if we're single-stepping */
1465 if (ptrace_cancel_bpt(current))
1466 send_sig(SIGTRAP, current, 1);
1467 #endif
1469 return 0;
1472 static long do_sigreturn_v2(CPUState *env)
1474 abi_ulong frame_addr;
1475 struct sigframe_v2 *frame;
1478 * Since we stacked the signal on a 64-bit boundary,
1479 * then 'sp' should be word aligned here. If it's
1480 * not, then the user is trying to mess with us.
1482 if (env->regs[13] & 7)
1483 goto badframe;
1485 frame_addr = env->regs[13];
1486 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1487 goto badframe;
1489 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1490 goto badframe;
1492 unlock_user_struct(frame, frame_addr, 0);
1493 return env->regs[0];
1495 badframe:
1496 unlock_user_struct(frame, frame_addr, 0);
1497 force_sig(SIGSEGV /* , current */);
1498 return 0;
1501 long do_sigreturn(CPUState *env)
1503 if (get_osversion() >= 0x020612) {
1504 return do_sigreturn_v2(env);
1505 } else {
1506 return do_sigreturn_v1(env);
1510 static long do_rt_sigreturn_v1(CPUState *env)
1512 abi_ulong frame_addr;
1513 struct rt_sigframe_v1 *frame;
1514 sigset_t host_set;
1517 * Since we stacked the signal on a 64-bit boundary,
1518 * then 'sp' should be word aligned here. If it's
1519 * not, then the user is trying to mess with us.
1521 if (env->regs[13] & 7)
1522 goto badframe;
1524 frame_addr = env->regs[13];
1525 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1526 goto badframe;
1528 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1529 sigprocmask(SIG_SETMASK, &host_set, NULL);
1531 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1532 goto badframe;
1534 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1535 goto badframe;
1537 #if 0
1538 /* Send SIGTRAP if we're single-stepping */
1539 if (ptrace_cancel_bpt(current))
1540 send_sig(SIGTRAP, current, 1);
1541 #endif
1542 unlock_user_struct(frame, frame_addr, 0);
1543 return env->regs[0];
1545 badframe:
1546 unlock_user_struct(frame, frame_addr, 0);
1547 force_sig(SIGSEGV /* , current */);
1548 return 0;
1551 static long do_rt_sigreturn_v2(CPUState *env)
1553 abi_ulong frame_addr;
1554 struct rt_sigframe_v2 *frame;
1557 * Since we stacked the signal on a 64-bit boundary,
1558 * then 'sp' should be word aligned here. If it's
1559 * not, then the user is trying to mess with us.
1561 if (env->regs[13] & 7)
1562 goto badframe;
1564 frame_addr = env->regs[13];
1565 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1566 goto badframe;
1568 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1569 goto badframe;
1571 unlock_user_struct(frame, frame_addr, 0);
1572 return env->regs[0];
1574 badframe:
1575 unlock_user_struct(frame, frame_addr, 0);
1576 force_sig(SIGSEGV /* , current */);
1577 return 0;
1580 long do_rt_sigreturn(CPUState *env)
1582 if (get_osversion() >= 0x020612) {
1583 return do_rt_sigreturn_v2(env);
1584 } else {
1585 return do_rt_sigreturn_v1(env);
1589 #elif defined(TARGET_SPARC)
1591 #define __SUNOS_MAXWIN 31
1593 /* This is what SunOS does, so shall I. */
1594 struct target_sigcontext {
1595 abi_ulong sigc_onstack; /* state to restore */
1597 abi_ulong sigc_mask; /* sigmask to restore */
1598 abi_ulong sigc_sp; /* stack pointer */
1599 abi_ulong sigc_pc; /* program counter */
1600 abi_ulong sigc_npc; /* next program counter */
1601 abi_ulong sigc_psr; /* for condition codes etc */
1602 abi_ulong sigc_g1; /* User uses these two registers */
1603 abi_ulong sigc_o0; /* within the trampoline code. */
1605 /* Now comes information regarding the users window set
1606 * at the time of the signal.
1608 abi_ulong sigc_oswins; /* outstanding windows */
1610 /* stack ptrs for each regwin buf */
1611 char *sigc_spbuf[__SUNOS_MAXWIN];
1613 /* Windows to restore after signal */
1614 struct {
1615 abi_ulong locals[8];
1616 abi_ulong ins[8];
1617 } sigc_wbuf[__SUNOS_MAXWIN];
1619 /* A Sparc stack frame */
1620 struct sparc_stackf {
1621 abi_ulong locals[8];
1622 abi_ulong ins[6];
1623 struct sparc_stackf *fp;
1624 abi_ulong callers_pc;
1625 char *structptr;
1626 abi_ulong xargs[6];
1627 abi_ulong xxargs[1];
1630 typedef struct {
1631 struct {
1632 abi_ulong psr;
1633 abi_ulong pc;
1634 abi_ulong npc;
1635 abi_ulong y;
1636 abi_ulong u_regs[16]; /* globals and ins */
1637 } si_regs;
1638 int si_mask;
1639 } __siginfo_t;
1641 typedef struct {
1642 unsigned long si_float_regs [32];
1643 unsigned long si_fsr;
1644 unsigned long si_fpqdepth;
1645 struct {
1646 unsigned long *insn_addr;
1647 unsigned long insn;
1648 } si_fpqueue [16];
1649 } qemu_siginfo_fpu_t;
1652 struct target_signal_frame {
1653 struct sparc_stackf ss;
1654 __siginfo_t info;
1655 abi_ulong fpu_save;
1656 abi_ulong insns[2] __attribute__ ((aligned (8)));
1657 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1658 abi_ulong extra_size; /* Should be 0 */
1659 qemu_siginfo_fpu_t fpu_state;
1661 struct target_rt_signal_frame {
1662 struct sparc_stackf ss;
1663 siginfo_t info;
1664 abi_ulong regs[20];
1665 sigset_t mask;
1666 abi_ulong fpu_save;
1667 unsigned int insns[2];
1668 stack_t stack;
1669 unsigned int extra_size; /* Should be 0 */
1670 qemu_siginfo_fpu_t fpu_state;
1673 #define UREG_O0 16
1674 #define UREG_O6 22
1675 #define UREG_I0 0
1676 #define UREG_I1 1
1677 #define UREG_I2 2
1678 #define UREG_I3 3
1679 #define UREG_I4 4
1680 #define UREG_I5 5
1681 #define UREG_I6 6
1682 #define UREG_I7 7
1683 #define UREG_L0 8
1684 #define UREG_FP UREG_I6
1685 #define UREG_SP UREG_O6
1687 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1688 CPUState *env, unsigned long framesize)
1690 abi_ulong sp;
1692 sp = env->regwptr[UREG_FP];
1694 /* This is the X/Open sanctioned signal stack switching. */
1695 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1696 if (!on_sig_stack(sp)
1697 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1698 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1700 return sp - framesize;
1703 static int
1704 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1706 int err = 0, i;
1708 err |= __put_user(env->psr, &si->si_regs.psr);
1709 err |= __put_user(env->pc, &si->si_regs.pc);
1710 err |= __put_user(env->npc, &si->si_regs.npc);
1711 err |= __put_user(env->y, &si->si_regs.y);
1712 for (i=0; i < 8; i++) {
1713 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1715 for (i=0; i < 8; i++) {
1716 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1718 err |= __put_user(mask, &si->si_mask);
1719 return err;
1722 #if 0
1723 static int
1724 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1725 CPUState *env, unsigned long mask)
1727 int err = 0;
1729 err |= __put_user(mask, &sc->sigc_mask);
1730 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1731 err |= __put_user(env->pc, &sc->sigc_pc);
1732 err |= __put_user(env->npc, &sc->sigc_npc);
1733 err |= __put_user(env->psr, &sc->sigc_psr);
1734 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1735 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1737 return err;
1739 #endif
1740 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1742 static void setup_frame(int sig, struct target_sigaction *ka,
1743 target_sigset_t *set, CPUState *env)
1745 abi_ulong sf_addr;
1746 struct target_signal_frame *sf;
1747 int sigframe_size, err, i;
1749 /* 1. Make sure everything is clean */
1750 //synchronize_user_stack();
1752 sigframe_size = NF_ALIGNEDSZ;
1753 sf_addr = get_sigframe(ka, env, sigframe_size);
1755 sf = lock_user(VERIFY_WRITE, sf_addr,
1756 sizeof(struct target_signal_frame), 0);
1757 if (!sf)
1758 goto sigsegv;
1760 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1761 #if 0
1762 if (invalid_frame_pointer(sf, sigframe_size))
1763 goto sigill_and_return;
1764 #endif
1765 /* 2. Save the current process state */
1766 err = setup___siginfo(&sf->info, env, set->sig[0]);
1767 err |= __put_user(0, &sf->extra_size);
1769 //err |= save_fpu_state(regs, &sf->fpu_state);
1770 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1772 err |= __put_user(set->sig[0], &sf->info.si_mask);
1773 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1774 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1777 for (i = 0; i < 8; i++) {
1778 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1780 for (i = 0; i < 8; i++) {
1781 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1783 if (err)
1784 goto sigsegv;
1786 /* 3. signal handler back-trampoline and parameters */
1787 env->regwptr[UREG_FP] = sf_addr;
1788 env->regwptr[UREG_I0] = sig;
1789 env->regwptr[UREG_I1] = sf_addr +
1790 offsetof(struct target_signal_frame, info);
1791 env->regwptr[UREG_I2] = sf_addr +
1792 offsetof(struct target_signal_frame, info);
1794 /* 4. signal handler */
1795 env->pc = ka->_sa_handler;
1796 env->npc = (env->pc + 4);
1797 /* 5. return to kernel instructions */
1798 if (ka->sa_restorer)
1799 env->regwptr[UREG_I7] = ka->sa_restorer;
1800 else {
1801 uint32_t val32;
1803 env->regwptr[UREG_I7] = sf_addr +
1804 offsetof(struct target_signal_frame, insns) - 2 * 4;
1806 /* mov __NR_sigreturn, %g1 */
1807 val32 = 0x821020d8;
1808 err |= __put_user(val32, &sf->insns[0]);
1810 /* t 0x10 */
1811 val32 = 0x91d02010;
1812 err |= __put_user(val32, &sf->insns[1]);
1813 if (err)
1814 goto sigsegv;
1816 /* Flush instruction space. */
1817 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1818 // tb_flush(env);
1820 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1821 return;
1822 #if 0
1823 sigill_and_return:
1824 force_sig(TARGET_SIGILL);
1825 #endif
1826 sigsegv:
1827 //fprintf(stderr, "force_sig\n");
1828 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1829 force_sig(TARGET_SIGSEGV);
1831 static inline int
1832 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1834 int err;
1835 #if 0
1836 #ifdef CONFIG_SMP
1837 if (current->flags & PF_USEDFPU)
1838 regs->psr &= ~PSR_EF;
1839 #else
1840 if (current == last_task_used_math) {
1841 last_task_used_math = 0;
1842 regs->psr &= ~PSR_EF;
1844 #endif
1845 current->used_math = 1;
1846 current->flags &= ~PF_USEDFPU;
1847 #endif
1848 #if 0
1849 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1850 return -EFAULT;
1851 #endif
1853 #if 0
1854 /* XXX: incorrect */
1855 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1856 (sizeof(unsigned long) * 32));
1857 #endif
1858 err |= __get_user(env->fsr, &fpu->si_fsr);
1859 #if 0
1860 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1861 if (current->thread.fpqdepth != 0)
1862 err |= __copy_from_user(&current->thread.fpqueue[0],
1863 &fpu->si_fpqueue[0],
1864 ((sizeof(unsigned long) +
1865 (sizeof(unsigned long *)))*16));
1866 #endif
1867 return err;
1871 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1872 target_siginfo_t *info,
1873 target_sigset_t *set, CPUState *env)
1875 fprintf(stderr, "setup_rt_frame: not implemented\n");
1878 long do_sigreturn(CPUState *env)
1880 abi_ulong sf_addr;
1881 struct target_signal_frame *sf;
1882 uint32_t up_psr, pc, npc;
1883 target_sigset_t set;
1884 sigset_t host_set;
1885 abi_ulong fpu_save_addr;
1886 int err, i;
1888 sf_addr = env->regwptr[UREG_FP];
1889 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1890 goto segv_and_exit;
1891 #if 0
1892 fprintf(stderr, "sigreturn\n");
1893 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1894 #endif
1895 //cpu_dump_state(env, stderr, fprintf, 0);
1897 /* 1. Make sure we are not getting garbage from the user */
1899 if (sf_addr & 3)
1900 goto segv_and_exit;
1902 err = __get_user(pc, &sf->info.si_regs.pc);
1903 err |= __get_user(npc, &sf->info.si_regs.npc);
1905 if ((pc | npc) & 3)
1906 goto segv_and_exit;
1908 /* 2. Restore the state */
1909 err |= __get_user(up_psr, &sf->info.si_regs.psr);
1911 /* User can only change condition codes and FPU enabling in %psr. */
1912 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1913 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1915 env->pc = pc;
1916 env->npc = npc;
1917 err |= __get_user(env->y, &sf->info.si_regs.y);
1918 for (i=0; i < 8; i++) {
1919 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1921 for (i=0; i < 8; i++) {
1922 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1925 err |= __get_user(fpu_save_addr, &sf->fpu_save);
1927 //if (fpu_save)
1928 // err |= restore_fpu_state(env, fpu_save);
1930 /* This is pretty much atomic, no amount locking would prevent
1931 * the races which exist anyways.
1933 err |= __get_user(set.sig[0], &sf->info.si_mask);
1934 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1935 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1938 target_to_host_sigset_internal(&host_set, &set);
1939 sigprocmask(SIG_SETMASK, &host_set, NULL);
1941 if (err)
1942 goto segv_and_exit;
1943 unlock_user_struct(sf, sf_addr, 0);
1944 return env->regwptr[0];
1946 segv_and_exit:
1947 unlock_user_struct(sf, sf_addr, 0);
1948 force_sig(TARGET_SIGSEGV);
1951 long do_rt_sigreturn(CPUState *env)
1953 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1954 return -TARGET_ENOSYS;
1957 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1958 #define MC_TSTATE 0
1959 #define MC_PC 1
1960 #define MC_NPC 2
1961 #define MC_Y 3
1962 #define MC_G1 4
1963 #define MC_G2 5
1964 #define MC_G3 6
1965 #define MC_G4 7
1966 #define MC_G5 8
1967 #define MC_G6 9
1968 #define MC_G7 10
1969 #define MC_O0 11
1970 #define MC_O1 12
1971 #define MC_O2 13
1972 #define MC_O3 14
1973 #define MC_O4 15
1974 #define MC_O5 16
1975 #define MC_O6 17
1976 #define MC_O7 18
1977 #define MC_NGREG 19
1979 typedef abi_ulong target_mc_greg_t;
1980 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1982 struct target_mc_fq {
1983 abi_ulong *mcfq_addr;
1984 uint32_t mcfq_insn;
1987 struct target_mc_fpu {
1988 union {
1989 uint32_t sregs[32];
1990 uint64_t dregs[32];
1991 //uint128_t qregs[16];
1992 } mcfpu_fregs;
1993 abi_ulong mcfpu_fsr;
1994 abi_ulong mcfpu_fprs;
1995 abi_ulong mcfpu_gsr;
1996 struct target_mc_fq *mcfpu_fq;
1997 unsigned char mcfpu_qcnt;
1998 unsigned char mcfpu_qentsz;
1999 unsigned char mcfpu_enab;
2001 typedef struct target_mc_fpu target_mc_fpu_t;
2003 typedef struct {
2004 target_mc_gregset_t mc_gregs;
2005 target_mc_greg_t mc_fp;
2006 target_mc_greg_t mc_i7;
2007 target_mc_fpu_t mc_fpregs;
2008 } target_mcontext_t;
2010 struct target_ucontext {
2011 struct target_ucontext *uc_link;
2012 abi_ulong uc_flags;
2013 target_sigset_t uc_sigmask;
2014 target_mcontext_t uc_mcontext;
2017 /* A V9 register window */
2018 struct target_reg_window {
2019 abi_ulong locals[8];
2020 abi_ulong ins[8];
2023 #define TARGET_STACK_BIAS 2047
2025 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2026 void sparc64_set_context(CPUSPARCState *env)
2028 abi_ulong ucp_addr;
2029 struct target_ucontext *ucp;
2030 target_mc_gregset_t *grp;
2031 abi_ulong pc, npc, tstate;
2032 abi_ulong fp, i7, w_addr;
2033 unsigned char fenab;
2034 int err;
2035 unsigned int i;
2037 ucp_addr = env->regwptr[UREG_I0];
2038 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2039 goto do_sigsegv;
2040 grp = &ucp->uc_mcontext.mc_gregs;
2041 err = __get_user(pc, &((*grp)[MC_PC]));
2042 err |= __get_user(npc, &((*grp)[MC_NPC]));
2043 if (err || ((pc | npc) & 3))
2044 goto do_sigsegv;
2045 if (env->regwptr[UREG_I1]) {
2046 target_sigset_t target_set;
2047 sigset_t set;
2049 if (TARGET_NSIG_WORDS == 1) {
2050 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2051 goto do_sigsegv;
2052 } else {
2053 abi_ulong *src, *dst;
2054 src = ucp->uc_sigmask.sig;
2055 dst = target_set.sig;
2056 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2057 i++, dst++, src++)
2058 err |= __get_user(*dst, src);
2059 if (err)
2060 goto do_sigsegv;
2062 target_to_host_sigset_internal(&set, &target_set);
2063 sigprocmask(SIG_SETMASK, &set, NULL);
2065 env->pc = pc;
2066 env->npc = npc;
2067 err |= __get_user(env->y, &((*grp)[MC_Y]));
2068 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2069 env->asi = (tstate >> 24) & 0xff;
2070 PUT_CCR(env, tstate >> 32);
2071 PUT_CWP64(env, tstate & 0x1f);
2072 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2073 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2074 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2075 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2076 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2077 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2078 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2079 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2080 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2081 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2082 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2083 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2084 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2085 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2086 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2088 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2089 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2091 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2092 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2093 abi_ulong) != 0)
2094 goto do_sigsegv;
2095 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2096 abi_ulong) != 0)
2097 goto do_sigsegv;
2098 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2099 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2101 uint32_t *src, *dst;
2102 src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2103 dst = env->fpr;
2104 /* XXX: check that the CPU storage is the same as user context */
2105 for (i = 0; i < 64; i++, dst++, src++)
2106 err |= __get_user(*dst, src);
2108 err |= __get_user(env->fsr,
2109 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2110 err |= __get_user(env->gsr,
2111 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2112 if (err)
2113 goto do_sigsegv;
2114 unlock_user_struct(ucp, ucp_addr, 0);
2115 return;
2116 do_sigsegv:
2117 unlock_user_struct(ucp, ucp_addr, 0);
2118 force_sig(SIGSEGV);
2121 void sparc64_get_context(CPUSPARCState *env)
2123 abi_ulong ucp_addr;
2124 struct target_ucontext *ucp;
2125 target_mc_gregset_t *grp;
2126 target_mcontext_t *mcp;
2127 abi_ulong fp, i7, w_addr;
2128 int err;
2129 unsigned int i;
2130 target_sigset_t target_set;
2131 sigset_t set;
2133 ucp_addr = env->regwptr[UREG_I0];
2134 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2135 goto do_sigsegv;
2137 mcp = &ucp->uc_mcontext;
2138 grp = &mcp->mc_gregs;
2140 /* Skip over the trap instruction, first. */
2141 env->pc = env->npc;
2142 env->npc += 4;
2144 err = 0;
2146 sigprocmask(0, NULL, &set);
2147 host_to_target_sigset_internal(&target_set, &set);
2148 if (TARGET_NSIG_WORDS == 1) {
2149 err |= __put_user(target_set.sig[0],
2150 (abi_ulong *)&ucp->uc_sigmask);
2151 } else {
2152 abi_ulong *src, *dst;
2153 src = target_set.sig;
2154 dst = ucp->uc_sigmask.sig;
2155 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2156 i++, dst++, src++)
2157 err |= __put_user(*src, dst);
2158 if (err)
2159 goto do_sigsegv;
2162 /* XXX: tstate must be saved properly */
2163 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2164 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2165 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2166 err |= __put_user(env->y, &((*grp)[MC_Y]));
2167 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2168 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2169 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2170 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2171 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2172 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2173 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2174 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2175 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2176 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2177 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2178 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2179 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2180 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2181 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2183 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2184 fp = i7 = 0;
2185 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2186 abi_ulong) != 0)
2187 goto do_sigsegv;
2188 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2189 abi_ulong) != 0)
2190 goto do_sigsegv;
2191 err |= __put_user(fp, &(mcp->mc_fp));
2192 err |= __put_user(i7, &(mcp->mc_i7));
2195 uint32_t *src, *dst;
2196 src = env->fpr;
2197 dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2198 /* XXX: check that the CPU storage is the same as user context */
2199 for (i = 0; i < 64; i++, dst++, src++)
2200 err |= __put_user(*src, dst);
2202 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2203 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2204 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2206 if (err)
2207 goto do_sigsegv;
2208 unlock_user_struct(ucp, ucp_addr, 1);
2209 return;
2210 do_sigsegv:
2211 unlock_user_struct(ucp, ucp_addr, 1);
2212 force_sig(SIGSEGV);
2214 #endif
2215 #elif defined(TARGET_ABI_MIPSN64)
2217 # warning signal handling not implemented
2219 static void setup_frame(int sig, struct target_sigaction *ka,
2220 target_sigset_t *set, CPUState *env)
2222 fprintf(stderr, "setup_frame: not implemented\n");
2225 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2226 target_siginfo_t *info,
2227 target_sigset_t *set, CPUState *env)
2229 fprintf(stderr, "setup_rt_frame: not implemented\n");
2232 long do_sigreturn(CPUState *env)
2234 fprintf(stderr, "do_sigreturn: not implemented\n");
2235 return -TARGET_ENOSYS;
2238 long do_rt_sigreturn(CPUState *env)
2240 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2241 return -TARGET_ENOSYS;
2244 #elif defined(TARGET_ABI_MIPSN32)
2246 # warning signal handling not implemented
2248 static void setup_frame(int sig, struct target_sigaction *ka,
2249 target_sigset_t *set, CPUState *env)
2251 fprintf(stderr, "setup_frame: not implemented\n");
2254 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2255 target_siginfo_t *info,
2256 target_sigset_t *set, CPUState *env)
2258 fprintf(stderr, "setup_rt_frame: not implemented\n");
2261 long do_sigreturn(CPUState *env)
2263 fprintf(stderr, "do_sigreturn: not implemented\n");
2264 return -TARGET_ENOSYS;
2267 long do_rt_sigreturn(CPUState *env)
2269 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2270 return -TARGET_ENOSYS;
2273 #elif defined(TARGET_ABI_MIPSO32)
2275 struct target_sigcontext {
2276 uint32_t sc_regmask; /* Unused */
2277 uint32_t sc_status;
2278 uint64_t sc_pc;
2279 uint64_t sc_regs[32];
2280 uint64_t sc_fpregs[32];
2281 uint32_t sc_ownedfp; /* Unused */
2282 uint32_t sc_fpc_csr;
2283 uint32_t sc_fpc_eir; /* Unused */
2284 uint32_t sc_used_math;
2285 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2286 uint64_t sc_mdhi;
2287 uint64_t sc_mdlo;
2288 target_ulong sc_hi1; /* Was sc_cause */
2289 target_ulong sc_lo1; /* Was sc_badvaddr */
2290 target_ulong sc_hi2; /* Was sc_sigset[4] */
2291 target_ulong sc_lo2;
2292 target_ulong sc_hi3;
2293 target_ulong sc_lo3;
2296 struct sigframe {
2297 uint32_t sf_ass[4]; /* argument save space for o32 */
2298 uint32_t sf_code[2]; /* signal trampoline */
2299 struct target_sigcontext sf_sc;
2300 target_sigset_t sf_mask;
2303 /* Install trampoline to jump back from signal handler */
2304 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2306 int err;
2309 * Set up the return code ...
2311 * li v0, __NR__foo_sigreturn
2312 * syscall
2315 err = __put_user(0x24020000 + syscall, tramp + 0);
2316 err |= __put_user(0x0000000c , tramp + 1);
2317 /* flush_cache_sigtramp((unsigned long) tramp); */
2318 return err;
2321 static inline int
2322 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2324 int err = 0;
2326 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2328 #define save_gp_reg(i) do { \
2329 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2330 } while(0)
2331 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2332 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2333 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2334 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2335 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2336 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2337 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2338 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2339 save_gp_reg(31);
2340 #undef save_gp_reg
2342 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2343 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2345 /* Not used yet, but might be useful if we ever have DSP suppport */
2346 #if 0
2347 if (cpu_has_dsp) {
2348 err |= __put_user(mfhi1(), &sc->sc_hi1);
2349 err |= __put_user(mflo1(), &sc->sc_lo1);
2350 err |= __put_user(mfhi2(), &sc->sc_hi2);
2351 err |= __put_user(mflo2(), &sc->sc_lo2);
2352 err |= __put_user(mfhi3(), &sc->sc_hi3);
2353 err |= __put_user(mflo3(), &sc->sc_lo3);
2354 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2356 /* same with 64 bit */
2357 #ifdef CONFIG_64BIT
2358 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2359 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2360 if (cpu_has_dsp) {
2361 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2362 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2363 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2364 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2365 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2366 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2367 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2369 #endif
2370 #endif
2372 #if 0
2373 err |= __put_user(!!used_math(), &sc->sc_used_math);
2375 if (!used_math())
2376 goto out;
2379 * Save FPU state to signal context. Signal handler will "inherit"
2380 * current FPU state.
2382 preempt_disable();
2384 if (!is_fpu_owner()) {
2385 own_fpu();
2386 restore_fp(current);
2388 err |= save_fp_context(sc);
2390 preempt_enable();
2391 out:
2392 #endif
2393 return err;
2396 static inline int
2397 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2399 int err = 0;
2401 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2403 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2404 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2406 #define restore_gp_reg(i) do { \
2407 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2408 } while(0)
2409 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2410 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2411 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2412 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2413 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2414 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2415 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2416 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2417 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2418 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2419 restore_gp_reg(31);
2420 #undef restore_gp_reg
2422 #if 0
2423 if (cpu_has_dsp) {
2424 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2425 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2426 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2427 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2428 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2429 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2430 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2432 #ifdef CONFIG_64BIT
2433 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2434 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2435 if (cpu_has_dsp) {
2436 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2437 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2438 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2439 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2440 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2441 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2442 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2444 #endif
2446 err |= __get_user(used_math, &sc->sc_used_math);
2447 conditional_used_math(used_math);
2449 preempt_disable();
2451 if (used_math()) {
2452 /* restore fpu context if we have used it before */
2453 own_fpu();
2454 err |= restore_fp_context(sc);
2455 } else {
2456 /* signal handler may have used FPU. Give it up. */
2457 lose_fpu();
2460 preempt_enable();
2461 #endif
2462 return err;
2465 * Determine which stack to use..
2467 static inline abi_ulong
2468 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2470 unsigned long sp;
2472 /* Default to using normal stack */
2473 sp = regs->active_tc.gpr[29];
2476 * FPU emulator may have it's own trampoline active just
2477 * above the user stack, 16-bytes before the next lowest
2478 * 16 byte boundary. Try to avoid trashing it.
2480 sp -= 32;
2482 /* This is the X/Open sanctioned signal stack switching. */
2483 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2484 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2487 return (sp - frame_size) & ~7;
2490 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2491 static void setup_frame(int sig, struct target_sigaction * ka,
2492 target_sigset_t *set, CPUState *regs)
2494 struct sigframe *frame;
2495 abi_ulong frame_addr;
2496 int i;
2498 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2499 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2500 goto give_sigsegv;
2502 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2504 if(setup_sigcontext(regs, &frame->sf_sc))
2505 goto give_sigsegv;
2507 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2508 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2509 goto give_sigsegv;
2513 * Arguments to signal handler:
2515 * a0 = signal number
2516 * a1 = 0 (should be cause)
2517 * a2 = pointer to struct sigcontext
2519 * $25 and PC point to the signal handler, $29 points to the
2520 * struct sigframe.
2522 regs->active_tc.gpr[ 4] = sig;
2523 regs->active_tc.gpr[ 5] = 0;
2524 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2525 regs->active_tc.gpr[29] = frame_addr;
2526 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2527 /* The original kernel code sets CP0_EPC to the handler
2528 * since it returns to userland using eret
2529 * we cannot do this here, and we must set PC directly */
2530 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2531 unlock_user_struct(frame, frame_addr, 1);
2532 return;
2534 give_sigsegv:
2535 unlock_user_struct(frame, frame_addr, 1);
2536 force_sig(TARGET_SIGSEGV/*, current*/);
2537 return;
2540 long do_sigreturn(CPUState *regs)
2542 struct sigframe *frame;
2543 abi_ulong frame_addr;
2544 sigset_t blocked;
2545 target_sigset_t target_set;
2546 int i;
2548 #if defined(DEBUG_SIGNAL)
2549 fprintf(stderr, "do_sigreturn\n");
2550 #endif
2551 frame_addr = regs->active_tc.gpr[29];
2552 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2553 goto badframe;
2555 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2556 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2557 goto badframe;
2560 target_to_host_sigset_internal(&blocked, &target_set);
2561 sigprocmask(SIG_SETMASK, &blocked, NULL);
2563 if (restore_sigcontext(regs, &frame->sf_sc))
2564 goto badframe;
2566 #if 0
2568 * Don't let your children do this ...
2570 __asm__ __volatile__(
2571 "move\t$29, %0\n\t"
2572 "j\tsyscall_exit"
2573 :/* no outputs */
2574 :"r" (&regs));
2575 /* Unreached */
2576 #endif
2578 regs->active_tc.PC = regs->CP0_EPC;
2579 /* I am not sure this is right, but it seems to work
2580 * maybe a problem with nested signals ? */
2581 regs->CP0_EPC = 0;
2582 return 0;
2584 badframe:
2585 force_sig(TARGET_SIGSEGV/*, current*/);
2586 return 0;
2589 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2590 target_siginfo_t *info,
2591 target_sigset_t *set, CPUState *env)
2593 fprintf(stderr, "setup_rt_frame: not implemented\n");
2596 long do_rt_sigreturn(CPUState *env)
2598 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2599 return -TARGET_ENOSYS;
2602 #elif defined(TARGET_SH4)
2605 * code and data structures from linux kernel:
2606 * include/asm-sh/sigcontext.h
2607 * arch/sh/kernel/signal.c
2610 struct target_sigcontext {
2611 target_ulong oldmask;
2613 /* CPU registers */
2614 target_ulong sc_gregs[16];
2615 target_ulong sc_pc;
2616 target_ulong sc_pr;
2617 target_ulong sc_sr;
2618 target_ulong sc_gbr;
2619 target_ulong sc_mach;
2620 target_ulong sc_macl;
2622 /* FPU registers */
2623 target_ulong sc_fpregs[16];
2624 target_ulong sc_xfpregs[16];
2625 unsigned int sc_fpscr;
2626 unsigned int sc_fpul;
2627 unsigned int sc_ownedfp;
2630 struct target_sigframe
2632 struct target_sigcontext sc;
2633 target_ulong extramask[TARGET_NSIG_WORDS-1];
2634 uint16_t retcode[3];
2638 struct target_ucontext {
2639 target_ulong uc_flags;
2640 struct target_ucontext *uc_link;
2641 target_stack_t uc_stack;
2642 struct target_sigcontext uc_mcontext;
2643 target_sigset_t uc_sigmask; /* mask last for extensibility */
2646 struct target_rt_sigframe
2648 struct target_siginfo info;
2649 struct target_ucontext uc;
2650 uint16_t retcode[3];
2654 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2655 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2657 static abi_ulong get_sigframe(struct target_sigaction *ka,
2658 unsigned long sp, size_t frame_size)
2660 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2661 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2664 return (sp - frame_size) & -8ul;
2667 static int setup_sigcontext(struct target_sigcontext *sc,
2668 CPUState *regs, unsigned long mask)
2670 int err = 0;
2672 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2673 COPY(gregs[0]); COPY(gregs[1]);
2674 COPY(gregs[2]); COPY(gregs[3]);
2675 COPY(gregs[4]); COPY(gregs[5]);
2676 COPY(gregs[6]); COPY(gregs[7]);
2677 COPY(gregs[8]); COPY(gregs[9]);
2678 COPY(gregs[10]); COPY(gregs[11]);
2679 COPY(gregs[12]); COPY(gregs[13]);
2680 COPY(gregs[14]); COPY(gregs[15]);
2681 COPY(gbr); COPY(mach);
2682 COPY(macl); COPY(pr);
2683 COPY(sr); COPY(pc);
2684 #undef COPY
2686 /* todo: save FPU registers here */
2688 /* non-iBCS2 extensions.. */
2689 err |= __put_user(mask, &sc->oldmask);
2691 return err;
2694 static int restore_sigcontext(CPUState *regs,
2695 struct target_sigcontext *sc)
2697 unsigned int err = 0;
2699 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2700 COPY(gregs[1]);
2701 COPY(gregs[2]); COPY(gregs[3]);
2702 COPY(gregs[4]); COPY(gregs[5]);
2703 COPY(gregs[6]); COPY(gregs[7]);
2704 COPY(gregs[8]); COPY(gregs[9]);
2705 COPY(gregs[10]); COPY(gregs[11]);
2706 COPY(gregs[12]); COPY(gregs[13]);
2707 COPY(gregs[14]); COPY(gregs[15]);
2708 COPY(gbr); COPY(mach);
2709 COPY(macl); COPY(pr);
2710 COPY(sr); COPY(pc);
2711 #undef COPY
2713 /* todo: restore FPU registers here */
2715 regs->tra = -1; /* disable syscall checks */
2716 return err;
2719 static void setup_frame(int sig, struct target_sigaction *ka,
2720 target_sigset_t *set, CPUState *regs)
2722 struct target_sigframe *frame;
2723 abi_ulong frame_addr;
2724 int i;
2725 int err = 0;
2726 int signal;
2728 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2729 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2730 goto give_sigsegv;
2732 signal = current_exec_domain_sig(sig);
2734 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2736 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2737 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2740 /* Set up to return from userspace. If provided, use a stub
2741 already in userspace. */
2742 if (ka->sa_flags & TARGET_SA_RESTORER) {
2743 regs->pr = (unsigned long) ka->sa_restorer;
2744 } else {
2745 /* Generate return code (system call to sigreturn) */
2746 err |= __put_user(MOVW(2), &frame->retcode[0]);
2747 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2748 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2749 regs->pr = (unsigned long) frame->retcode;
2752 if (err)
2753 goto give_sigsegv;
2755 /* Set up registers for signal handler */
2756 regs->gregs[15] = (unsigned long) frame;
2757 regs->gregs[4] = signal; /* Arg for signal handler */
2758 regs->gregs[5] = 0;
2759 regs->gregs[6] = (unsigned long) &frame->sc;
2760 regs->pc = (unsigned long) ka->_sa_handler;
2762 unlock_user_struct(frame, frame_addr, 1);
2763 return;
2765 give_sigsegv:
2766 unlock_user_struct(frame, frame_addr, 1);
2767 force_sig(SIGSEGV);
2770 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2771 target_siginfo_t *info,
2772 target_sigset_t *set, CPUState *regs)
2774 struct target_rt_sigframe *frame;
2775 abi_ulong frame_addr;
2776 int i;
2777 int err = 0;
2778 int signal;
2780 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2781 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2782 goto give_sigsegv;
2784 signal = current_exec_domain_sig(sig);
2786 err |= copy_siginfo_to_user(&frame->info, info);
2788 /* Create the ucontext. */
2789 err |= __put_user(0, &frame->uc.uc_flags);
2790 err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2791 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2792 &frame->uc.uc_stack.ss_sp);
2793 err |= __put_user(sas_ss_flags(regs->gregs[15]),
2794 &frame->uc.uc_stack.ss_flags);
2795 err |= __put_user(target_sigaltstack_used.ss_size,
2796 &frame->uc.uc_stack.ss_size);
2797 err |= setup_sigcontext(&frame->uc.uc_mcontext,
2798 regs, set->sig[0]);
2799 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2800 err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2803 /* Set up to return from userspace. If provided, use a stub
2804 already in userspace. */
2805 if (ka->sa_flags & TARGET_SA_RESTORER) {
2806 regs->pr = (unsigned long) ka->sa_restorer;
2807 } else {
2808 /* Generate return code (system call to sigreturn) */
2809 err |= __put_user(MOVW(2), &frame->retcode[0]);
2810 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2811 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2812 regs->pr = (unsigned long) frame->retcode;
2815 if (err)
2816 goto give_sigsegv;
2818 /* Set up registers for signal handler */
2819 regs->gregs[15] = (unsigned long) frame;
2820 regs->gregs[4] = signal; /* Arg for signal handler */
2821 regs->gregs[5] = (unsigned long) &frame->info;
2822 regs->gregs[6] = (unsigned long) &frame->uc;
2823 regs->pc = (unsigned long) ka->_sa_handler;
2825 unlock_user_struct(frame, frame_addr, 1);
2826 return;
2828 give_sigsegv:
2829 unlock_user_struct(frame, frame_addr, 1);
2830 force_sig(SIGSEGV);
2833 long do_sigreturn(CPUState *regs)
2835 struct target_sigframe *frame;
2836 abi_ulong frame_addr;
2837 sigset_t blocked;
2838 target_sigset_t target_set;
2839 int i;
2840 int err = 0;
2842 #if defined(DEBUG_SIGNAL)
2843 fprintf(stderr, "do_sigreturn\n");
2844 #endif
2845 frame_addr = regs->gregs[15];
2846 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2847 goto badframe;
2849 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2850 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2851 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2854 if (err)
2855 goto badframe;
2857 target_to_host_sigset_internal(&blocked, &target_set);
2858 sigprocmask(SIG_SETMASK, &blocked, NULL);
2860 if (restore_sigcontext(regs, &frame->sc))
2861 goto badframe;
2863 unlock_user_struct(frame, frame_addr, 0);
2864 return regs->gregs[0];
2866 badframe:
2867 unlock_user_struct(frame, frame_addr, 0);
2868 force_sig(TARGET_SIGSEGV);
2869 return 0;
2872 long do_rt_sigreturn(CPUState *regs)
2874 struct target_rt_sigframe *frame;
2875 abi_ulong frame_addr;
2876 sigset_t blocked;
2878 #if defined(DEBUG_SIGNAL)
2879 fprintf(stderr, "do_rt_sigreturn\n");
2880 #endif
2881 frame_addr = regs->gregs[15];
2882 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2883 goto badframe;
2885 target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2886 sigprocmask(SIG_SETMASK, &blocked, NULL);
2888 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2889 goto badframe;
2891 if (do_sigaltstack(frame_addr +
2892 offsetof(struct target_rt_sigframe, uc.uc_stack),
2893 0, get_sp_from_cpustate(regs)) == -EFAULT)
2894 goto badframe;
2896 unlock_user_struct(frame, frame_addr, 0);
2897 return regs->gregs[0];
2899 badframe:
2900 unlock_user_struct(frame, frame_addr, 0);
2901 force_sig(TARGET_SIGSEGV);
2902 return 0;
2904 #elif defined(TARGET_CRIS)
2906 struct target_sigcontext {
2907 struct target_pt_regs regs; /* needs to be first */
2908 uint32_t oldmask;
2909 uint32_t usp; /* usp before stacking this gunk on it */
2912 /* Signal frames. */
2913 struct target_signal_frame {
2914 struct target_sigcontext sc;
2915 uint32_t extramask[TARGET_NSIG_WORDS - 1];
2916 uint8_t retcode[8]; /* Trampoline code. */
2919 struct rt_signal_frame {
2920 struct siginfo *pinfo;
2921 void *puc;
2922 struct siginfo info;
2923 struct ucontext uc;
2924 uint8_t retcode[8]; /* Trampoline code. */
2927 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2929 __put_user(env->regs[0], &sc->regs.r0);
2930 __put_user(env->regs[1], &sc->regs.r1);
2931 __put_user(env->regs[2], &sc->regs.r2);
2932 __put_user(env->regs[3], &sc->regs.r3);
2933 __put_user(env->regs[4], &sc->regs.r4);
2934 __put_user(env->regs[5], &sc->regs.r5);
2935 __put_user(env->regs[6], &sc->regs.r6);
2936 __put_user(env->regs[7], &sc->regs.r7);
2937 __put_user(env->regs[8], &sc->regs.r8);
2938 __put_user(env->regs[9], &sc->regs.r9);
2939 __put_user(env->regs[10], &sc->regs.r10);
2940 __put_user(env->regs[11], &sc->regs.r11);
2941 __put_user(env->regs[12], &sc->regs.r12);
2942 __put_user(env->regs[13], &sc->regs.r13);
2943 __put_user(env->regs[14], &sc->usp);
2944 __put_user(env->regs[15], &sc->regs.acr);
2945 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2946 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2947 __put_user(env->pc, &sc->regs.erp);
2950 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2952 __get_user(env->regs[0], &sc->regs.r0);
2953 __get_user(env->regs[1], &sc->regs.r1);
2954 __get_user(env->regs[2], &sc->regs.r2);
2955 __get_user(env->regs[3], &sc->regs.r3);
2956 __get_user(env->regs[4], &sc->regs.r4);
2957 __get_user(env->regs[5], &sc->regs.r5);
2958 __get_user(env->regs[6], &sc->regs.r6);
2959 __get_user(env->regs[7], &sc->regs.r7);
2960 __get_user(env->regs[8], &sc->regs.r8);
2961 __get_user(env->regs[9], &sc->regs.r9);
2962 __get_user(env->regs[10], &sc->regs.r10);
2963 __get_user(env->regs[11], &sc->regs.r11);
2964 __get_user(env->regs[12], &sc->regs.r12);
2965 __get_user(env->regs[13], &sc->regs.r13);
2966 __get_user(env->regs[14], &sc->usp);
2967 __get_user(env->regs[15], &sc->regs.acr);
2968 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2969 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2970 __get_user(env->pc, &sc->regs.erp);
2973 static abi_ulong get_sigframe(CPUState *env, int framesize)
2975 abi_ulong sp;
2976 /* Align the stack downwards to 4. */
2977 sp = (env->regs[R_SP] & ~3);
2978 return sp - framesize;
2981 static void setup_frame(int sig, struct target_sigaction *ka,
2982 target_sigset_t *set, CPUState *env)
2984 struct target_signal_frame *frame;
2985 abi_ulong frame_addr;
2986 int err = 0;
2987 int i;
2989 frame_addr = get_sigframe(env, sizeof *frame);
2990 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2991 goto badframe;
2994 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2995 * use this trampoline anymore but it sets it up for GDB.
2996 * In QEMU, using the trampoline simplifies things a bit so we use it.
2998 * This is movu.w __NR_sigreturn, r9; break 13;
3000 err |= __put_user(0x9c5f, frame->retcode+0);
3001 err |= __put_user(TARGET_NR_sigreturn,
3002 frame->retcode+2);
3003 err |= __put_user(0xe93d, frame->retcode+4);
3005 /* Save the mask. */
3006 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3007 if (err)
3008 goto badframe;
3010 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3011 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3012 goto badframe;
3015 setup_sigcontext(&frame->sc, env);
3017 /* Move the stack and setup the arguments for the handler. */
3018 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3019 env->regs[10] = sig;
3020 env->pc = (unsigned long) ka->_sa_handler;
3021 /* Link SRP so the guest returns through the trampoline. */
3022 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3024 unlock_user_struct(frame, frame_addr, 1);
3025 return;
3026 badframe:
3027 unlock_user_struct(frame, frame_addr, 1);
3028 force_sig(TARGET_SIGSEGV);
3031 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3032 target_siginfo_t *info,
3033 target_sigset_t *set, CPUState *env)
3035 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3038 long do_sigreturn(CPUState *env)
3040 struct target_signal_frame *frame;
3041 abi_ulong frame_addr;
3042 target_sigset_t target_set;
3043 sigset_t set;
3044 int i;
3046 frame_addr = env->regs[R_SP];
3047 /* Make sure the guest isn't playing games. */
3048 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3049 goto badframe;
3051 /* Restore blocked signals */
3052 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3053 goto badframe;
3054 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3055 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3056 goto badframe;
3058 target_to_host_sigset_internal(&set, &target_set);
3059 sigprocmask(SIG_SETMASK, &set, NULL);
3061 restore_sigcontext(&frame->sc, env);
3062 unlock_user_struct(frame, frame_addr, 0);
3063 return env->regs[10];
3064 badframe:
3065 unlock_user_struct(frame, frame_addr, 0);
3066 force_sig(TARGET_SIGSEGV);
3069 long do_rt_sigreturn(CPUState *env)
3071 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3072 return -TARGET_ENOSYS;
3075 #else
3077 static void setup_frame(int sig, struct target_sigaction *ka,
3078 target_sigset_t *set, CPUState *env)
3080 fprintf(stderr, "setup_frame: not implemented\n");
3083 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3084 target_siginfo_t *info,
3085 target_sigset_t *set, CPUState *env)
3087 fprintf(stderr, "setup_rt_frame: not implemented\n");
3090 long do_sigreturn(CPUState *env)
3092 fprintf(stderr, "do_sigreturn: not implemented\n");
3093 return -TARGET_ENOSYS;
3096 long do_rt_sigreturn(CPUState *env)
3098 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3099 return -TARGET_ENOSYS;
3102 #endif
3104 void process_pending_signals(CPUState *cpu_env)
3106 int sig;
3107 abi_ulong handler;
3108 sigset_t set, old_set;
3109 target_sigset_t target_old_set;
3110 struct emulated_sigtable *k;
3111 struct target_sigaction *sa;
3112 struct sigqueue *q;
3113 TaskState *ts = cpu_env->opaque;
3115 if (!ts->signal_pending)
3116 return;
3118 /* FIXME: This is not threadsafe. */
3119 k = ts->sigtab;
3120 for(sig = 1; sig <= TARGET_NSIG; sig++) {
3121 if (k->pending)
3122 goto handle_signal;
3123 k++;
3125 /* if no signal is pending, just return */
3126 ts->signal_pending = 0;
3127 return;
3129 handle_signal:
3130 #ifdef DEBUG_SIGNAL
3131 fprintf(stderr, "qemu: process signal %d\n", sig);
3132 #endif
3133 /* dequeue signal */
3134 q = k->first;
3135 k->first = q->next;
3136 if (!k->first)
3137 k->pending = 0;
3139 sig = gdb_handlesig (cpu_env, sig);
3140 if (!sig) {
3141 sa = NULL;
3142 handler = TARGET_SIG_IGN;
3143 } else {
3144 sa = &sigact_table[sig - 1];
3145 handler = sa->_sa_handler;
3148 if (handler == TARGET_SIG_DFL) {
3149 /* default handler : ignore some signal. The other are job control or fatal */
3150 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
3151 kill(getpid(),SIGSTOP);
3152 } else if (sig != TARGET_SIGCHLD &&
3153 sig != TARGET_SIGURG &&
3154 sig != TARGET_SIGWINCH &&
3155 sig != TARGET_SIGCONT) {
3156 force_sig(sig);
3158 } else if (handler == TARGET_SIG_IGN) {
3159 /* ignore sig */
3160 } else if (handler == TARGET_SIG_ERR) {
3161 force_sig(sig);
3162 } else {
3163 /* compute the blocked signals during the handler execution */
3164 target_to_host_sigset(&set, &sa->sa_mask);
3165 /* SA_NODEFER indicates that the current signal should not be
3166 blocked during the handler */
3167 if (!(sa->sa_flags & TARGET_SA_NODEFER))
3168 sigaddset(&set, target_to_host_signal(sig));
3170 /* block signals in the handler using Linux */
3171 sigprocmask(SIG_BLOCK, &set, &old_set);
3172 /* save the previous blocked signal state to restore it at the
3173 end of the signal execution (see do_sigreturn) */
3174 host_to_target_sigset_internal(&target_old_set, &old_set);
3176 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3177 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3179 CPUX86State *env = cpu_env;
3180 if (env->eflags & VM_MASK)
3181 save_v86_state(env);
3183 #endif
3184 /* prepare the stack frame of the virtual CPU */
3185 if (sa->sa_flags & TARGET_SA_SIGINFO)
3186 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3187 else
3188 setup_frame(sig, sa, &target_old_set, cpu_env);
3189 if (sa->sa_flags & TARGET_SA_RESETHAND)
3190 sa->_sa_handler = TARGET_SIG_DFL;
3192 if (q != &k->info)
3193 free_sigqueue(cpu_env, q);