User-mode GDB stub improvements - handle signals
[qemu/qemu-JZ.git] / linux-user / signal.c
blob5e30522091d9be3624b501591a71c0f93937125d
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <unistd.h>
25 #include <signal.h>
26 #include <errno.h>
27 #include <sys/ucontext.h>
29 #include "qemu.h"
30 #include "target_signal.h"
32 //#define DEBUG_SIGNAL
34 static struct target_sigaltstack target_sigaltstack_used = {
35 .ss_sp = 0,
36 .ss_size = 0,
37 .ss_flags = TARGET_SS_DISABLE,
40 static struct target_sigaction sigact_table[TARGET_NSIG];
42 static void host_signal_handler(int host_signum, siginfo_t *info,
43 void *puc);
45 static uint8_t host_to_target_signal_table[65] = {
46 [SIGHUP] = TARGET_SIGHUP,
47 [SIGINT] = TARGET_SIGINT,
48 [SIGQUIT] = TARGET_SIGQUIT,
49 [SIGILL] = TARGET_SIGILL,
50 [SIGTRAP] = TARGET_SIGTRAP,
51 [SIGABRT] = TARGET_SIGABRT,
52 /* [SIGIOT] = TARGET_SIGIOT,*/
53 [SIGBUS] = TARGET_SIGBUS,
54 [SIGFPE] = TARGET_SIGFPE,
55 [SIGKILL] = TARGET_SIGKILL,
56 [SIGUSR1] = TARGET_SIGUSR1,
57 [SIGSEGV] = TARGET_SIGSEGV,
58 [SIGUSR2] = TARGET_SIGUSR2,
59 [SIGPIPE] = TARGET_SIGPIPE,
60 [SIGALRM] = TARGET_SIGALRM,
61 [SIGTERM] = TARGET_SIGTERM,
62 #ifdef SIGSTKFLT
63 [SIGSTKFLT] = TARGET_SIGSTKFLT,
64 #endif
65 [SIGCHLD] = TARGET_SIGCHLD,
66 [SIGCONT] = TARGET_SIGCONT,
67 [SIGSTOP] = TARGET_SIGSTOP,
68 [SIGTSTP] = TARGET_SIGTSTP,
69 [SIGTTIN] = TARGET_SIGTTIN,
70 [SIGTTOU] = TARGET_SIGTTOU,
71 [SIGURG] = TARGET_SIGURG,
72 [SIGXCPU] = TARGET_SIGXCPU,
73 [SIGXFSZ] = TARGET_SIGXFSZ,
74 [SIGVTALRM] = TARGET_SIGVTALRM,
75 [SIGPROF] = TARGET_SIGPROF,
76 [SIGWINCH] = TARGET_SIGWINCH,
77 [SIGIO] = TARGET_SIGIO,
78 [SIGPWR] = TARGET_SIGPWR,
79 [SIGSYS] = TARGET_SIGSYS,
80 /* next signals stay the same */
81 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
82 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
83 To fix this properly we need to do manual signal delivery multiplexed
84 over a single host signal. */
85 [__SIGRTMIN] = __SIGRTMAX,
86 [__SIGRTMAX] = __SIGRTMIN,
88 static uint8_t target_to_host_signal_table[65];
90 static inline int on_sig_stack(unsigned long sp)
92 return (sp - target_sigaltstack_used.ss_sp
93 < target_sigaltstack_used.ss_size);
96 static inline int sas_ss_flags(unsigned long sp)
98 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
99 : on_sig_stack(sp) ? SS_ONSTACK : 0);
102 static inline int host_to_target_signal(int sig)
104 if (sig > 64)
105 return sig;
106 return host_to_target_signal_table[sig];
109 int target_to_host_signal(int sig)
111 if (sig > 64)
112 return sig;
113 return target_to_host_signal_table[sig];
116 static inline void target_sigemptyset(target_sigset_t *set)
118 memset(set, 0, sizeof(*set));
121 static inline void target_sigaddset(target_sigset_t *set, int signum)
123 signum--;
124 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
125 set->sig[signum / TARGET_NSIG_BPW] |= mask;
128 static inline int target_sigismember(const target_sigset_t *set, int signum)
130 signum--;
131 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
132 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
135 static void host_to_target_sigset_internal(target_sigset_t *d,
136 const sigset_t *s)
138 int i;
139 target_sigemptyset(d);
140 for (i = 1; i <= TARGET_NSIG; i++) {
141 if (sigismember(s, i)) {
142 target_sigaddset(d, host_to_target_signal(i));
147 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
149 target_sigset_t d1;
150 int i;
152 host_to_target_sigset_internal(&d1, s);
153 for(i = 0;i < TARGET_NSIG_WORDS; i++)
154 d->sig[i] = tswapl(d1.sig[i]);
157 static void target_to_host_sigset_internal(sigset_t *d,
158 const target_sigset_t *s)
160 int i;
161 sigemptyset(d);
162 for (i = 1; i <= TARGET_NSIG; i++) {
163 if (target_sigismember(s, i)) {
164 sigaddset(d, target_to_host_signal(i));
169 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
171 target_sigset_t s1;
172 int i;
174 for(i = 0;i < TARGET_NSIG_WORDS; i++)
175 s1.sig[i] = tswapl(s->sig[i]);
176 target_to_host_sigset_internal(d, &s1);
179 void host_to_target_old_sigset(abi_ulong *old_sigset,
180 const sigset_t *sigset)
182 target_sigset_t d;
183 host_to_target_sigset(&d, sigset);
184 *old_sigset = d.sig[0];
187 void target_to_host_old_sigset(sigset_t *sigset,
188 const abi_ulong *old_sigset)
190 target_sigset_t d;
191 int i;
193 d.sig[0] = *old_sigset;
194 for(i = 1;i < TARGET_NSIG_WORDS; i++)
195 d.sig[i] = 0;
196 target_to_host_sigset(sigset, &d);
199 /* siginfo conversion */
201 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
202 const siginfo_t *info)
204 int sig;
205 sig = host_to_target_signal(info->si_signo);
206 tinfo->si_signo = sig;
207 tinfo->si_errno = 0;
208 tinfo->si_code = info->si_code;
209 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
210 sig == SIGBUS || sig == SIGTRAP) {
211 /* should never come here, but who knows. The information for
212 the target is irrelevant */
213 tinfo->_sifields._sigfault._addr = 0;
214 } else if (sig == SIGIO) {
215 tinfo->_sifields._sigpoll._fd = info->si_fd;
216 } else if (sig >= TARGET_SIGRTMIN) {
217 tinfo->_sifields._rt._pid = info->si_pid;
218 tinfo->_sifields._rt._uid = info->si_uid;
219 /* XXX: potential problem if 64 bit */
220 tinfo->_sifields._rt._sigval.sival_ptr =
221 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
225 static void tswap_siginfo(target_siginfo_t *tinfo,
226 const target_siginfo_t *info)
228 int sig;
229 sig = info->si_signo;
230 tinfo->si_signo = tswap32(sig);
231 tinfo->si_errno = tswap32(info->si_errno);
232 tinfo->si_code = tswap32(info->si_code);
233 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
234 sig == SIGBUS || sig == SIGTRAP) {
235 tinfo->_sifields._sigfault._addr =
236 tswapl(info->_sifields._sigfault._addr);
237 } else if (sig == SIGIO) {
238 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
239 } else if (sig >= TARGET_SIGRTMIN) {
240 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
241 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
242 tinfo->_sifields._rt._sigval.sival_ptr =
243 tswapl(info->_sifields._rt._sigval.sival_ptr);
248 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
250 host_to_target_siginfo_noswap(tinfo, info);
251 tswap_siginfo(tinfo, tinfo);
254 /* XXX: we support only POSIX RT signals are used. */
255 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
256 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
258 info->si_signo = tswap32(tinfo->si_signo);
259 info->si_errno = tswap32(tinfo->si_errno);
260 info->si_code = tswap32(tinfo->si_code);
261 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
262 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
263 info->si_value.sival_ptr =
264 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
267 static int fatal_signal (int sig)
269 switch (sig) {
270 case TARGET_SIGCHLD:
271 case TARGET_SIGURG:
272 case TARGET_SIGWINCH:
273 /* Ignored by default. */
274 return 0;
275 case TARGET_SIGCONT:
276 case TARGET_SIGSTOP:
277 case TARGET_SIGTSTP:
278 case TARGET_SIGTTIN:
279 case TARGET_SIGTTOU:
280 /* Job control signals. */
281 return 0;
282 default:
283 return 1;
287 void signal_init(void)
289 struct sigaction act;
290 struct sigaction oact;
291 int i, j;
292 int host_sig;
294 /* generate signal conversion tables */
295 for(i = 1; i <= 64; i++) {
296 if (host_to_target_signal_table[i] == 0)
297 host_to_target_signal_table[i] = i;
299 for(i = 1; i <= 64; i++) {
300 j = host_to_target_signal_table[i];
301 target_to_host_signal_table[j] = i;
304 /* set all host signal handlers. ALL signals are blocked during
305 the handlers to serialize them. */
306 memset(sigact_table, 0, sizeof(sigact_table));
308 sigfillset(&act.sa_mask);
309 act.sa_flags = SA_SIGINFO;
310 act.sa_sigaction = host_signal_handler;
311 for(i = 1; i <= TARGET_NSIG; i++) {
312 host_sig = target_to_host_signal(i);
313 sigaction(host_sig, NULL, &oact);
314 if (oact.sa_sigaction == (void *)SIG_IGN) {
315 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
316 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
317 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
319 /* If there's already a handler installed then something has
320 gone horribly wrong, so don't even try to handle that case. */
321 /* Install some handlers for our own use. We need at least
322 SIGSEGV and SIGBUS, to detect exceptions. We can not just
323 trap all signals because it affects syscall interrupt
324 behavior. But do trap all default-fatal signals. */
325 if (fatal_signal (i))
326 sigaction(host_sig, &act, NULL);
330 /* signal queue handling */
332 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
334 TaskState *ts = env->opaque;
335 struct sigqueue *q = ts->first_free;
336 if (!q)
337 return NULL;
338 ts->first_free = q->next;
339 return q;
342 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
344 TaskState *ts = env->opaque;
345 q->next = ts->first_free;
346 ts->first_free = q;
349 /* abort execution with signal */
350 static void __attribute((noreturn)) force_sig(int sig)
352 int host_sig;
353 host_sig = target_to_host_signal(sig);
354 fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
355 sig, strsignal(host_sig));
356 #if 1
357 gdb_signalled(thread_env, sig);
358 _exit(-host_sig);
359 #else
361 struct sigaction act;
362 sigemptyset(&act.sa_mask);
363 act.sa_flags = SA_SIGINFO;
364 act.sa_sigaction = SIG_DFL;
365 sigaction(SIGABRT, &act, NULL);
366 abort();
368 #endif
371 /* queue a signal so that it will be send to the virtual CPU as soon
372 as possible */
373 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
375 TaskState *ts = env->opaque;
376 struct emulated_sigtable *k;
377 struct sigqueue *q, **pq;
378 abi_ulong handler;
379 int queue;
381 #if defined(DEBUG_SIGNAL)
382 fprintf(stderr, "queue_signal: sig=%d\n",
383 sig);
384 #endif
385 k = &ts->sigtab[sig - 1];
386 queue = gdb_queuesig ();
387 handler = sigact_table[sig - 1]._sa_handler;
388 if (!queue && handler == TARGET_SIG_DFL) {
389 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
390 kill(getpid(),SIGSTOP);
391 return 0;
392 } else
393 /* default handler : ignore some signal. The other are fatal */
394 if (sig != TARGET_SIGCHLD &&
395 sig != TARGET_SIGURG &&
396 sig != TARGET_SIGWINCH &&
397 sig != TARGET_SIGCONT) {
398 force_sig(sig);
399 } else {
400 return 0; /* indicate ignored */
402 } else if (!queue && handler == TARGET_SIG_IGN) {
403 /* ignore signal */
404 return 0;
405 } else if (!queue && handler == TARGET_SIG_ERR) {
406 force_sig(sig);
407 } else {
408 pq = &k->first;
409 if (sig < TARGET_SIGRTMIN) {
410 /* if non real time signal, we queue exactly one signal */
411 if (!k->pending)
412 q = &k->info;
413 else
414 return 0;
415 } else {
416 if (!k->pending) {
417 /* first signal */
418 q = &k->info;
419 } else {
420 q = alloc_sigqueue(env);
421 if (!q)
422 return -EAGAIN;
423 while (*pq != NULL)
424 pq = &(*pq)->next;
427 *pq = q;
428 q->info = *info;
429 q->next = NULL;
430 k->pending = 1;
431 /* signal that a new signal is pending */
432 ts->signal_pending = 1;
433 return 1; /* indicates that the signal was queued */
437 static void host_signal_handler(int host_signum, siginfo_t *info,
438 void *puc)
440 int sig;
441 target_siginfo_t tinfo;
443 /* the CPU emulator uses some host signals to detect exceptions,
444 we we forward to it some signals */
445 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
446 && info->si_code == SI_KERNEL) {
447 if (cpu_signal_handler(host_signum, info, puc))
448 return;
451 /* get target signal number */
452 sig = host_to_target_signal(host_signum);
453 if (sig < 1 || sig > TARGET_NSIG)
454 return;
455 #if defined(DEBUG_SIGNAL)
456 fprintf(stderr, "qemu: got signal %d\n", sig);
457 #endif
458 host_to_target_siginfo_noswap(&tinfo, info);
459 if (queue_signal(thread_env, sig, &tinfo) == 1) {
460 /* interrupt the virtual CPU as soon as possible */
461 cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
465 /* do_sigaltstack() returns target values and errnos. */
466 /* compare linux/kernel/signal.c:do_sigaltstack() */
467 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
469 int ret;
470 struct target_sigaltstack oss;
472 /* XXX: test errors */
473 if(uoss_addr)
475 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
476 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
477 __put_user(sas_ss_flags(sp), &oss.ss_flags);
480 if(uss_addr)
482 struct target_sigaltstack *uss;
483 struct target_sigaltstack ss;
485 ret = -TARGET_EFAULT;
486 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
487 || __get_user(ss.ss_sp, &uss->ss_sp)
488 || __get_user(ss.ss_size, &uss->ss_size)
489 || __get_user(ss.ss_flags, &uss->ss_flags))
490 goto out;
491 unlock_user_struct(uss, uss_addr, 0);
493 ret = -TARGET_EPERM;
494 if (on_sig_stack(sp))
495 goto out;
497 ret = -TARGET_EINVAL;
498 if (ss.ss_flags != TARGET_SS_DISABLE
499 && ss.ss_flags != TARGET_SS_ONSTACK
500 && ss.ss_flags != 0)
501 goto out;
503 if (ss.ss_flags == TARGET_SS_DISABLE) {
504 ss.ss_size = 0;
505 ss.ss_sp = 0;
506 } else {
507 ret = -TARGET_ENOMEM;
508 if (ss.ss_size < MINSIGSTKSZ)
509 goto out;
512 target_sigaltstack_used.ss_sp = ss.ss_sp;
513 target_sigaltstack_used.ss_size = ss.ss_size;
516 if (uoss_addr) {
517 ret = -TARGET_EFAULT;
518 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
519 goto out;
522 ret = 0;
523 out:
524 return ret;
527 /* do_sigaction() return host values and errnos */
528 int do_sigaction(int sig, const struct target_sigaction *act,
529 struct target_sigaction *oact)
531 struct target_sigaction *k;
532 struct sigaction act1;
533 int host_sig;
534 int ret = 0;
536 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
537 return -EINVAL;
538 k = &sigact_table[sig - 1];
539 #if defined(DEBUG_SIGNAL)
540 fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
541 sig, (int)act, (int)oact);
542 #endif
543 if (oact) {
544 oact->_sa_handler = tswapl(k->_sa_handler);
545 oact->sa_flags = tswapl(k->sa_flags);
546 #if !defined(TARGET_MIPS)
547 oact->sa_restorer = tswapl(k->sa_restorer);
548 #endif
549 oact->sa_mask = k->sa_mask;
551 if (act) {
552 /* FIXME: This is not threadsafe. */
553 k->_sa_handler = tswapl(act->_sa_handler);
554 k->sa_flags = tswapl(act->sa_flags);
555 #if !defined(TARGET_MIPS)
556 k->sa_restorer = tswapl(act->sa_restorer);
557 #endif
558 k->sa_mask = act->sa_mask;
560 /* we update the host linux signal state */
561 host_sig = target_to_host_signal(sig);
562 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
563 sigfillset(&act1.sa_mask);
564 act1.sa_flags = SA_SIGINFO;
565 if (k->sa_flags & TARGET_SA_RESTART)
566 act1.sa_flags |= SA_RESTART;
567 /* NOTE: it is important to update the host kernel signal
568 ignore state to avoid getting unexpected interrupted
569 syscalls */
570 if (k->_sa_handler == TARGET_SIG_IGN) {
571 act1.sa_sigaction = (void *)SIG_IGN;
572 } else if (k->_sa_handler == TARGET_SIG_DFL) {
573 if (fatal_signal (sig))
574 act1.sa_sigaction = host_signal_handler;
575 else
576 act1.sa_sigaction = (void *)SIG_DFL;
577 } else {
578 act1.sa_sigaction = host_signal_handler;
580 ret = sigaction(host_sig, &act1, NULL);
583 return ret;
586 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
587 const target_siginfo_t *info)
589 tswap_siginfo(tinfo, info);
590 return 0;
593 static inline int current_exec_domain_sig(int sig)
595 return /* current->exec_domain && current->exec_domain->signal_invmap
596 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
599 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
601 /* from the Linux kernel */
603 struct target_fpreg {
604 uint16_t significand[4];
605 uint16_t exponent;
608 struct target_fpxreg {
609 uint16_t significand[4];
610 uint16_t exponent;
611 uint16_t padding[3];
614 struct target_xmmreg {
615 abi_ulong element[4];
618 struct target_fpstate {
619 /* Regular FPU environment */
620 abi_ulong cw;
621 abi_ulong sw;
622 abi_ulong tag;
623 abi_ulong ipoff;
624 abi_ulong cssel;
625 abi_ulong dataoff;
626 abi_ulong datasel;
627 struct target_fpreg _st[8];
628 uint16_t status;
629 uint16_t magic; /* 0xffff = regular FPU data only */
631 /* FXSR FPU environment */
632 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
633 abi_ulong mxcsr;
634 abi_ulong reserved;
635 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
636 struct target_xmmreg _xmm[8];
637 abi_ulong padding[56];
640 #define X86_FXSR_MAGIC 0x0000
642 struct target_sigcontext {
643 uint16_t gs, __gsh;
644 uint16_t fs, __fsh;
645 uint16_t es, __esh;
646 uint16_t ds, __dsh;
647 abi_ulong edi;
648 abi_ulong esi;
649 abi_ulong ebp;
650 abi_ulong esp;
651 abi_ulong ebx;
652 abi_ulong edx;
653 abi_ulong ecx;
654 abi_ulong eax;
655 abi_ulong trapno;
656 abi_ulong err;
657 abi_ulong eip;
658 uint16_t cs, __csh;
659 abi_ulong eflags;
660 abi_ulong esp_at_signal;
661 uint16_t ss, __ssh;
662 abi_ulong fpstate; /* pointer */
663 abi_ulong oldmask;
664 abi_ulong cr2;
667 struct target_ucontext {
668 abi_ulong tuc_flags;
669 abi_ulong tuc_link;
670 target_stack_t tuc_stack;
671 struct target_sigcontext tuc_mcontext;
672 target_sigset_t tuc_sigmask; /* mask last for extensibility */
675 struct sigframe
677 abi_ulong pretcode;
678 int sig;
679 struct target_sigcontext sc;
680 struct target_fpstate fpstate;
681 abi_ulong extramask[TARGET_NSIG_WORDS-1];
682 char retcode[8];
685 struct rt_sigframe
687 abi_ulong pretcode;
688 int sig;
689 abi_ulong pinfo;
690 abi_ulong puc;
691 struct target_siginfo info;
692 struct target_ucontext uc;
693 struct target_fpstate fpstate;
694 char retcode[8];
698 * Set up a signal frame.
701 /* XXX: save x87 state */
702 static int
703 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
704 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
706 int err = 0;
707 uint16_t magic;
709 /* already locked in setup_frame() */
710 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
711 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
712 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
713 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
714 err |= __put_user(env->regs[R_EDI], &sc->edi);
715 err |= __put_user(env->regs[R_ESI], &sc->esi);
716 err |= __put_user(env->regs[R_EBP], &sc->ebp);
717 err |= __put_user(env->regs[R_ESP], &sc->esp);
718 err |= __put_user(env->regs[R_EBX], &sc->ebx);
719 err |= __put_user(env->regs[R_EDX], &sc->edx);
720 err |= __put_user(env->regs[R_ECX], &sc->ecx);
721 err |= __put_user(env->regs[R_EAX], &sc->eax);
722 err |= __put_user(env->exception_index, &sc->trapno);
723 err |= __put_user(env->error_code, &sc->err);
724 err |= __put_user(env->eip, &sc->eip);
725 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
726 err |= __put_user(env->eflags, &sc->eflags);
727 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
728 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
730 cpu_x86_fsave(env, fpstate_addr, 1);
731 fpstate->status = fpstate->sw;
732 magic = 0xffff;
733 err |= __put_user(magic, &fpstate->magic);
734 err |= __put_user(fpstate_addr, &sc->fpstate);
736 /* non-iBCS2 extensions.. */
737 err |= __put_user(mask, &sc->oldmask);
738 err |= __put_user(env->cr[2], &sc->cr2);
739 return err;
743 * Determine which stack to use..
746 static inline abi_ulong
747 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
749 unsigned long esp;
751 /* Default to using normal stack */
752 esp = env->regs[R_ESP];
753 /* This is the X/Open sanctioned signal stack switching. */
754 if (ka->sa_flags & TARGET_SA_ONSTACK) {
755 if (sas_ss_flags(esp) == 0)
756 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
759 /* This is the legacy signal stack switching. */
760 else
761 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
762 !(ka->sa_flags & TARGET_SA_RESTORER) &&
763 ka->sa_restorer) {
764 esp = (unsigned long) ka->sa_restorer;
766 return (esp - frame_size) & -8ul;
769 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
770 static void setup_frame(int sig, struct target_sigaction *ka,
771 target_sigset_t *set, CPUX86State *env)
773 abi_ulong frame_addr;
774 struct sigframe *frame;
775 int i, err = 0;
777 frame_addr = get_sigframe(ka, env, sizeof(*frame));
779 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
780 goto give_sigsegv;
782 err |= __put_user(current_exec_domain_sig(sig),
783 &frame->sig);
784 if (err)
785 goto give_sigsegv;
787 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
788 frame_addr + offsetof(struct sigframe, fpstate));
789 if (err)
790 goto give_sigsegv;
792 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
793 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
794 goto give_sigsegv;
797 /* Set up to return from userspace. If provided, use a stub
798 already in userspace. */
799 if (ka->sa_flags & TARGET_SA_RESTORER) {
800 err |= __put_user(ka->sa_restorer, &frame->pretcode);
801 } else {
802 uint16_t val16;
803 abi_ulong retcode_addr;
804 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
805 err |= __put_user(retcode_addr, &frame->pretcode);
806 /* This is popl %eax ; movl $,%eax ; int $0x80 */
807 val16 = 0xb858;
808 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
809 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
810 val16 = 0x80cd;
811 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
814 if (err)
815 goto give_sigsegv;
817 /* Set up registers for signal handler */
818 env->regs[R_ESP] = frame_addr;
819 env->eip = ka->_sa_handler;
821 cpu_x86_load_seg(env, R_DS, __USER_DS);
822 cpu_x86_load_seg(env, R_ES, __USER_DS);
823 cpu_x86_load_seg(env, R_SS, __USER_DS);
824 cpu_x86_load_seg(env, R_CS, __USER_CS);
825 env->eflags &= ~TF_MASK;
827 unlock_user_struct(frame, frame_addr, 1);
829 return;
831 give_sigsegv:
832 unlock_user_struct(frame, frame_addr, 1);
833 if (sig == TARGET_SIGSEGV)
834 ka->_sa_handler = TARGET_SIG_DFL;
835 force_sig(TARGET_SIGSEGV /* , current */);
838 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
839 static void setup_rt_frame(int sig, struct target_sigaction *ka,
840 target_siginfo_t *info,
841 target_sigset_t *set, CPUX86State *env)
843 abi_ulong frame_addr, addr;
844 struct rt_sigframe *frame;
845 int i, err = 0;
847 frame_addr = get_sigframe(ka, env, sizeof(*frame));
849 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
850 goto give_sigsegv;
852 err |= __put_user(current_exec_domain_sig(sig),
853 &frame->sig);
854 addr = frame_addr + offsetof(struct rt_sigframe, info);
855 err |= __put_user(addr, &frame->pinfo);
856 addr = frame_addr + offsetof(struct rt_sigframe, uc);
857 err |= __put_user(addr, &frame->puc);
858 err |= copy_siginfo_to_user(&frame->info, info);
859 if (err)
860 goto give_sigsegv;
862 /* Create the ucontext. */
863 err |= __put_user(0, &frame->uc.tuc_flags);
864 err |= __put_user(0, &frame->uc.tuc_link);
865 err |= __put_user(target_sigaltstack_used.ss_sp,
866 &frame->uc.tuc_stack.ss_sp);
867 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
868 &frame->uc.tuc_stack.ss_flags);
869 err |= __put_user(target_sigaltstack_used.ss_size,
870 &frame->uc.tuc_stack.ss_size);
871 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
872 env, set->sig[0],
873 frame_addr + offsetof(struct rt_sigframe, fpstate));
874 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
875 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
876 goto give_sigsegv;
879 /* Set up to return from userspace. If provided, use a stub
880 already in userspace. */
881 if (ka->sa_flags & TARGET_SA_RESTORER) {
882 err |= __put_user(ka->sa_restorer, &frame->pretcode);
883 } else {
884 uint16_t val16;
885 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
886 err |= __put_user(addr, &frame->pretcode);
887 /* This is movl $,%eax ; int $0x80 */
888 err |= __put_user(0xb8, (char *)(frame->retcode+0));
889 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
890 val16 = 0x80cd;
891 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
894 if (err)
895 goto give_sigsegv;
897 /* Set up registers for signal handler */
898 env->regs[R_ESP] = frame_addr;
899 env->eip = ka->_sa_handler;
901 cpu_x86_load_seg(env, R_DS, __USER_DS);
902 cpu_x86_load_seg(env, R_ES, __USER_DS);
903 cpu_x86_load_seg(env, R_SS, __USER_DS);
904 cpu_x86_load_seg(env, R_CS, __USER_CS);
905 env->eflags &= ~TF_MASK;
907 unlock_user_struct(frame, frame_addr, 1);
909 return;
911 give_sigsegv:
912 unlock_user_struct(frame, frame_addr, 1);
913 if (sig == TARGET_SIGSEGV)
914 ka->_sa_handler = TARGET_SIG_DFL;
915 force_sig(TARGET_SIGSEGV /* , current */);
918 static int
919 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
921 unsigned int err = 0;
922 abi_ulong fpstate_addr;
923 unsigned int tmpflags;
925 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
926 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
927 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
928 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
930 env->regs[R_EDI] = tswapl(sc->edi);
931 env->regs[R_ESI] = tswapl(sc->esi);
932 env->regs[R_EBP] = tswapl(sc->ebp);
933 env->regs[R_ESP] = tswapl(sc->esp);
934 env->regs[R_EBX] = tswapl(sc->ebx);
935 env->regs[R_EDX] = tswapl(sc->edx);
936 env->regs[R_ECX] = tswapl(sc->ecx);
937 env->eip = tswapl(sc->eip);
939 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
940 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
942 tmpflags = tswapl(sc->eflags);
943 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
944 // regs->orig_eax = -1; /* disable syscall checks */
946 fpstate_addr = tswapl(sc->fpstate);
947 if (fpstate_addr != 0) {
948 if (!access_ok(VERIFY_READ, fpstate_addr,
949 sizeof(struct target_fpstate)))
950 goto badframe;
951 cpu_x86_frstor(env, fpstate_addr, 1);
954 *peax = tswapl(sc->eax);
955 return err;
956 badframe:
957 return 1;
960 long do_sigreturn(CPUX86State *env)
962 struct sigframe *frame;
963 abi_ulong frame_addr = env->regs[R_ESP] - 8;
964 target_sigset_t target_set;
965 sigset_t set;
966 int eax, i;
968 #if defined(DEBUG_SIGNAL)
969 fprintf(stderr, "do_sigreturn\n");
970 #endif
971 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
972 goto badframe;
973 /* set blocked signals */
974 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
975 goto badframe;
976 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
977 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
978 goto badframe;
981 target_to_host_sigset_internal(&set, &target_set);
982 sigprocmask(SIG_SETMASK, &set, NULL);
984 /* restore registers */
985 if (restore_sigcontext(env, &frame->sc, &eax))
986 goto badframe;
987 unlock_user_struct(frame, frame_addr, 0);
988 return eax;
990 badframe:
991 unlock_user_struct(frame, frame_addr, 0);
992 force_sig(TARGET_SIGSEGV);
993 return 0;
996 long do_rt_sigreturn(CPUX86State *env)
998 abi_ulong frame_addr;
999 struct rt_sigframe *frame;
1000 sigset_t set;
1001 int eax;
1003 frame_addr = env->regs[R_ESP] - 4;
1004 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1005 goto badframe;
1006 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1007 sigprocmask(SIG_SETMASK, &set, NULL);
1009 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1010 goto badframe;
1012 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1013 get_sp_from_cpustate(env)) == -EFAULT)
1014 goto badframe;
1016 unlock_user_struct(frame, frame_addr, 0);
1017 return eax;
1019 badframe:
1020 unlock_user_struct(frame, frame_addr, 0);
1021 force_sig(TARGET_SIGSEGV);
1022 return 0;
1025 #elif defined(TARGET_ARM)
1027 struct target_sigcontext {
1028 abi_ulong trap_no;
1029 abi_ulong error_code;
1030 abi_ulong oldmask;
1031 abi_ulong arm_r0;
1032 abi_ulong arm_r1;
1033 abi_ulong arm_r2;
1034 abi_ulong arm_r3;
1035 abi_ulong arm_r4;
1036 abi_ulong arm_r5;
1037 abi_ulong arm_r6;
1038 abi_ulong arm_r7;
1039 abi_ulong arm_r8;
1040 abi_ulong arm_r9;
1041 abi_ulong arm_r10;
1042 abi_ulong arm_fp;
1043 abi_ulong arm_ip;
1044 abi_ulong arm_sp;
1045 abi_ulong arm_lr;
1046 abi_ulong arm_pc;
1047 abi_ulong arm_cpsr;
1048 abi_ulong fault_address;
1051 struct target_ucontext_v1 {
1052 abi_ulong tuc_flags;
1053 abi_ulong tuc_link;
1054 target_stack_t tuc_stack;
1055 struct target_sigcontext tuc_mcontext;
1056 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1059 struct target_ucontext_v2 {
1060 abi_ulong tuc_flags;
1061 abi_ulong tuc_link;
1062 target_stack_t tuc_stack;
1063 struct target_sigcontext tuc_mcontext;
1064 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1065 char __unused[128 - sizeof(sigset_t)];
1066 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1069 struct sigframe_v1
1071 struct target_sigcontext sc;
1072 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1073 abi_ulong retcode;
1076 struct sigframe_v2
1078 struct target_ucontext_v2 uc;
1079 abi_ulong retcode;
1082 struct rt_sigframe_v1
1084 abi_ulong pinfo;
1085 abi_ulong puc;
1086 struct target_siginfo info;
1087 struct target_ucontext_v1 uc;
1088 abi_ulong retcode;
1091 struct rt_sigframe_v2
1093 struct target_siginfo info;
1094 struct target_ucontext_v2 uc;
1095 abi_ulong retcode;
1098 #define TARGET_CONFIG_CPU_32 1
1101 * For ARM syscalls, we encode the syscall number into the instruction.
1103 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1104 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1107 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1108 * need two 16-bit instructions.
1110 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1111 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1113 static const abi_ulong retcodes[4] = {
1114 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1115 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1119 #define __get_user_error(x,p,e) __get_user(x, p)
1121 static inline int valid_user_regs(CPUState *regs)
1123 return 1;
1126 static void
1127 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1128 CPUState *env, abi_ulong mask)
1130 __put_user(env->regs[0], &sc->arm_r0);
1131 __put_user(env->regs[1], &sc->arm_r1);
1132 __put_user(env->regs[2], &sc->arm_r2);
1133 __put_user(env->regs[3], &sc->arm_r3);
1134 __put_user(env->regs[4], &sc->arm_r4);
1135 __put_user(env->regs[5], &sc->arm_r5);
1136 __put_user(env->regs[6], &sc->arm_r6);
1137 __put_user(env->regs[7], &sc->arm_r7);
1138 __put_user(env->regs[8], &sc->arm_r8);
1139 __put_user(env->regs[9], &sc->arm_r9);
1140 __put_user(env->regs[10], &sc->arm_r10);
1141 __put_user(env->regs[11], &sc->arm_fp);
1142 __put_user(env->regs[12], &sc->arm_ip);
1143 __put_user(env->regs[13], &sc->arm_sp);
1144 __put_user(env->regs[14], &sc->arm_lr);
1145 __put_user(env->regs[15], &sc->arm_pc);
1146 #ifdef TARGET_CONFIG_CPU_32
1147 __put_user(cpsr_read(env), &sc->arm_cpsr);
1148 #endif
1150 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1151 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1152 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1153 __put_user(mask, &sc->oldmask);
1156 static inline abi_ulong
1157 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1159 unsigned long sp = regs->regs[13];
1162 * This is the X/Open sanctioned signal stack switching.
1164 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1165 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1167 * ATPCS B01 mandates 8-byte alignment
1169 return (sp - framesize) & ~7;
1172 static int
1173 setup_return(CPUState *env, struct target_sigaction *ka,
1174 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1176 abi_ulong handler = ka->_sa_handler;
1177 abi_ulong retcode;
1178 int thumb = handler & 1;
1180 if (ka->sa_flags & TARGET_SA_RESTORER) {
1181 retcode = ka->sa_restorer;
1182 } else {
1183 unsigned int idx = thumb;
1185 if (ka->sa_flags & TARGET_SA_SIGINFO)
1186 idx += 2;
1188 if (__put_user(retcodes[idx], rc))
1189 return 1;
1190 #if 0
1191 flush_icache_range((abi_ulong)rc,
1192 (abi_ulong)(rc + 1));
1193 #endif
1194 retcode = rc_addr + thumb;
1197 env->regs[0] = usig;
1198 env->regs[13] = frame_addr;
1199 env->regs[14] = retcode;
1200 env->regs[15] = handler & (thumb ? ~1 : ~3);
1201 env->thumb = thumb;
1203 #if 0
1204 #ifdef TARGET_CONFIG_CPU_32
1205 env->cpsr = cpsr;
1206 #endif
1207 #endif
1209 return 0;
1212 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1213 target_sigset_t *set, CPUState *env)
1215 struct target_sigaltstack stack;
1216 int i;
1218 /* Clear all the bits of the ucontext we don't use. */
1219 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1221 memset(&stack, 0, sizeof(stack));
1222 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1223 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1224 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1225 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1227 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1228 /* FIXME: Save coprocessor signal frame. */
1229 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1230 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1234 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1235 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1236 target_sigset_t *set, CPUState *regs)
1238 struct sigframe_v1 *frame;
1239 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1240 int i;
1242 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1243 return;
1245 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1247 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1248 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1249 goto end;
1252 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1253 frame_addr + offsetof(struct sigframe_v1, retcode));
1255 end:
1256 unlock_user_struct(frame, frame_addr, 1);
1259 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1260 target_sigset_t *set, CPUState *regs)
1262 struct sigframe_v2 *frame;
1263 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1265 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1266 return;
1268 setup_sigframe_v2(&frame->uc, set, regs);
1270 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1271 frame_addr + offsetof(struct sigframe_v2, retcode));
1273 unlock_user_struct(frame, frame_addr, 1);
1276 static void setup_frame(int usig, struct target_sigaction *ka,
1277 target_sigset_t *set, CPUState *regs)
1279 if (get_osversion() >= 0x020612) {
1280 setup_frame_v2(usig, ka, set, regs);
1281 } else {
1282 setup_frame_v1(usig, ka, set, regs);
1286 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1287 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1288 target_siginfo_t *info,
1289 target_sigset_t *set, CPUState *env)
1291 struct rt_sigframe_v1 *frame;
1292 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1293 struct target_sigaltstack stack;
1294 int i;
1295 abi_ulong info_addr, uc_addr;
1297 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1298 return /* 1 */;
1300 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1301 __put_user(info_addr, &frame->pinfo);
1302 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1303 __put_user(uc_addr, &frame->puc);
1304 copy_siginfo_to_user(&frame->info, info);
1306 /* Clear all the bits of the ucontext we don't use. */
1307 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1309 memset(&stack, 0, sizeof(stack));
1310 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1311 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1312 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1313 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1315 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1316 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1317 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1318 goto end;
1321 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1322 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1324 env->regs[1] = info_addr;
1325 env->regs[2] = uc_addr;
1327 end:
1328 unlock_user_struct(frame, frame_addr, 1);
1331 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1332 target_siginfo_t *info,
1333 target_sigset_t *set, CPUState *env)
1335 struct rt_sigframe_v2 *frame;
1336 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1337 abi_ulong info_addr, uc_addr;
1339 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1340 return /* 1 */;
1342 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1343 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1344 copy_siginfo_to_user(&frame->info, info);
1346 setup_sigframe_v2(&frame->uc, set, env);
1348 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1349 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1351 env->regs[1] = info_addr;
1352 env->regs[2] = uc_addr;
1354 unlock_user_struct(frame, frame_addr, 1);
1357 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1358 target_siginfo_t *info,
1359 target_sigset_t *set, CPUState *env)
1361 if (get_osversion() >= 0x020612) {
1362 setup_rt_frame_v2(usig, ka, info, set, env);
1363 } else {
1364 setup_rt_frame_v1(usig, ka, info, set, env);
1368 static int
1369 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1371 int err = 0;
1372 uint32_t cpsr;
1374 __get_user_error(env->regs[0], &sc->arm_r0, err);
1375 __get_user_error(env->regs[1], &sc->arm_r1, err);
1376 __get_user_error(env->regs[2], &sc->arm_r2, err);
1377 __get_user_error(env->regs[3], &sc->arm_r3, err);
1378 __get_user_error(env->regs[4], &sc->arm_r4, err);
1379 __get_user_error(env->regs[5], &sc->arm_r5, err);
1380 __get_user_error(env->regs[6], &sc->arm_r6, err);
1381 __get_user_error(env->regs[7], &sc->arm_r7, err);
1382 __get_user_error(env->regs[8], &sc->arm_r8, err);
1383 __get_user_error(env->regs[9], &sc->arm_r9, err);
1384 __get_user_error(env->regs[10], &sc->arm_r10, err);
1385 __get_user_error(env->regs[11], &sc->arm_fp, err);
1386 __get_user_error(env->regs[12], &sc->arm_ip, err);
1387 __get_user_error(env->regs[13], &sc->arm_sp, err);
1388 __get_user_error(env->regs[14], &sc->arm_lr, err);
1389 __get_user_error(env->regs[15], &sc->arm_pc, err);
1390 #ifdef TARGET_CONFIG_CPU_32
1391 __get_user_error(cpsr, &sc->arm_cpsr, err);
1392 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1393 #endif
1395 err |= !valid_user_regs(env);
1397 return err;
1400 long do_sigreturn_v1(CPUState *env)
1402 abi_ulong frame_addr;
1403 struct sigframe_v1 *frame;
1404 target_sigset_t set;
1405 sigset_t host_set;
1406 int i;
1409 * Since we stacked the signal on a 64-bit boundary,
1410 * then 'sp' should be word aligned here. If it's
1411 * not, then the user is trying to mess with us.
1413 if (env->regs[13] & 7)
1414 goto badframe;
1416 frame_addr = env->regs[13];
1417 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1418 goto badframe;
1420 if (__get_user(set.sig[0], &frame->sc.oldmask))
1421 goto badframe;
1422 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1423 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1424 goto badframe;
1427 target_to_host_sigset_internal(&host_set, &set);
1428 sigprocmask(SIG_SETMASK, &host_set, NULL);
1430 if (restore_sigcontext(env, &frame->sc))
1431 goto badframe;
1433 #if 0
1434 /* Send SIGTRAP if we're single-stepping */
1435 if (ptrace_cancel_bpt(current))
1436 send_sig(SIGTRAP, current, 1);
1437 #endif
1438 unlock_user_struct(frame, frame_addr, 0);
1439 return env->regs[0];
1441 badframe:
1442 unlock_user_struct(frame, frame_addr, 0);
1443 force_sig(SIGSEGV /* , current */);
1444 return 0;
1447 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1448 struct target_ucontext_v2 *uc)
1450 sigset_t host_set;
1452 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1453 sigprocmask(SIG_SETMASK, &host_set, NULL);
1455 if (restore_sigcontext(env, &uc->tuc_mcontext))
1456 return 1;
1458 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1459 return 1;
1461 #if 0
1462 /* Send SIGTRAP if we're single-stepping */
1463 if (ptrace_cancel_bpt(current))
1464 send_sig(SIGTRAP, current, 1);
1465 #endif
1467 return 0;
1470 long do_sigreturn_v2(CPUState *env)
1472 abi_ulong frame_addr;
1473 struct sigframe_v2 *frame;
1476 * Since we stacked the signal on a 64-bit boundary,
1477 * then 'sp' should be word aligned here. If it's
1478 * not, then the user is trying to mess with us.
1480 if (env->regs[13] & 7)
1481 goto badframe;
1483 frame_addr = env->regs[13];
1484 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1485 goto badframe;
1487 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1488 goto badframe;
1490 unlock_user_struct(frame, frame_addr, 0);
1491 return env->regs[0];
1493 badframe:
1494 unlock_user_struct(frame, frame_addr, 0);
1495 force_sig(SIGSEGV /* , current */);
1496 return 0;
1499 long do_sigreturn(CPUState *env)
1501 if (get_osversion() >= 0x020612) {
1502 return do_sigreturn_v2(env);
1503 } else {
1504 return do_sigreturn_v1(env);
1508 long do_rt_sigreturn_v1(CPUState *env)
1510 abi_ulong frame_addr;
1511 struct rt_sigframe_v1 *frame;
1512 sigset_t host_set;
1515 * Since we stacked the signal on a 64-bit boundary,
1516 * then 'sp' should be word aligned here. If it's
1517 * not, then the user is trying to mess with us.
1519 if (env->regs[13] & 7)
1520 goto badframe;
1522 frame_addr = env->regs[13];
1523 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1524 goto badframe;
1526 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1527 sigprocmask(SIG_SETMASK, &host_set, NULL);
1529 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1530 goto badframe;
1532 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1533 goto badframe;
1535 #if 0
1536 /* Send SIGTRAP if we're single-stepping */
1537 if (ptrace_cancel_bpt(current))
1538 send_sig(SIGTRAP, current, 1);
1539 #endif
1540 unlock_user_struct(frame, frame_addr, 0);
1541 return env->regs[0];
1543 badframe:
1544 unlock_user_struct(frame, frame_addr, 0);
1545 force_sig(SIGSEGV /* , current */);
1546 return 0;
1549 long do_rt_sigreturn_v2(CPUState *env)
1551 abi_ulong frame_addr;
1552 struct rt_sigframe_v2 *frame;
1555 * Since we stacked the signal on a 64-bit boundary,
1556 * then 'sp' should be word aligned here. If it's
1557 * not, then the user is trying to mess with us.
1559 if (env->regs[13] & 7)
1560 goto badframe;
1562 frame_addr = env->regs[13];
1563 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1564 goto badframe;
1566 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1567 goto badframe;
1569 unlock_user_struct(frame, frame_addr, 0);
1570 return env->regs[0];
1572 badframe:
1573 unlock_user_struct(frame, frame_addr, 0);
1574 force_sig(SIGSEGV /* , current */);
1575 return 0;
1578 long do_rt_sigreturn(CPUState *env)
1580 if (get_osversion() >= 0x020612) {
1581 return do_rt_sigreturn_v2(env);
1582 } else {
1583 return do_rt_sigreturn_v1(env);
1587 #elif defined(TARGET_SPARC)
1589 #define __SUNOS_MAXWIN 31
1591 /* This is what SunOS does, so shall I. */
1592 struct target_sigcontext {
1593 abi_ulong sigc_onstack; /* state to restore */
1595 abi_ulong sigc_mask; /* sigmask to restore */
1596 abi_ulong sigc_sp; /* stack pointer */
1597 abi_ulong sigc_pc; /* program counter */
1598 abi_ulong sigc_npc; /* next program counter */
1599 abi_ulong sigc_psr; /* for condition codes etc */
1600 abi_ulong sigc_g1; /* User uses these two registers */
1601 abi_ulong sigc_o0; /* within the trampoline code. */
1603 /* Now comes information regarding the users window set
1604 * at the time of the signal.
1606 abi_ulong sigc_oswins; /* outstanding windows */
1608 /* stack ptrs for each regwin buf */
1609 char *sigc_spbuf[__SUNOS_MAXWIN];
1611 /* Windows to restore after signal */
1612 struct {
1613 abi_ulong locals[8];
1614 abi_ulong ins[8];
1615 } sigc_wbuf[__SUNOS_MAXWIN];
1617 /* A Sparc stack frame */
1618 struct sparc_stackf {
1619 abi_ulong locals[8];
1620 abi_ulong ins[6];
1621 struct sparc_stackf *fp;
1622 abi_ulong callers_pc;
1623 char *structptr;
1624 abi_ulong xargs[6];
1625 abi_ulong xxargs[1];
1628 typedef struct {
1629 struct {
1630 abi_ulong psr;
1631 abi_ulong pc;
1632 abi_ulong npc;
1633 abi_ulong y;
1634 abi_ulong u_regs[16]; /* globals and ins */
1635 } si_regs;
1636 int si_mask;
1637 } __siginfo_t;
1639 typedef struct {
1640 unsigned long si_float_regs [32];
1641 unsigned long si_fsr;
1642 unsigned long si_fpqdepth;
1643 struct {
1644 unsigned long *insn_addr;
1645 unsigned long insn;
1646 } si_fpqueue [16];
1647 } qemu_siginfo_fpu_t;
1650 struct target_signal_frame {
1651 struct sparc_stackf ss;
1652 __siginfo_t info;
1653 abi_ulong fpu_save;
1654 abi_ulong insns[2] __attribute__ ((aligned (8)));
1655 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1656 abi_ulong extra_size; /* Should be 0 */
1657 qemu_siginfo_fpu_t fpu_state;
1659 struct target_rt_signal_frame {
1660 struct sparc_stackf ss;
1661 siginfo_t info;
1662 abi_ulong regs[20];
1663 sigset_t mask;
1664 abi_ulong fpu_save;
1665 unsigned int insns[2];
1666 stack_t stack;
1667 unsigned int extra_size; /* Should be 0 */
1668 qemu_siginfo_fpu_t fpu_state;
1671 #define UREG_O0 16
1672 #define UREG_O6 22
1673 #define UREG_I0 0
1674 #define UREG_I1 1
1675 #define UREG_I2 2
1676 #define UREG_I3 3
1677 #define UREG_I4 4
1678 #define UREG_I5 5
1679 #define UREG_I6 6
1680 #define UREG_I7 7
1681 #define UREG_L0 8
1682 #define UREG_FP UREG_I6
1683 #define UREG_SP UREG_O6
1685 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1686 CPUState *env, unsigned long framesize)
1688 abi_ulong sp;
1690 sp = env->regwptr[UREG_FP];
1692 /* This is the X/Open sanctioned signal stack switching. */
1693 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1694 if (!on_sig_stack(sp)
1695 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1696 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1698 return sp - framesize;
1701 static int
1702 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1704 int err = 0, i;
1706 err |= __put_user(env->psr, &si->si_regs.psr);
1707 err |= __put_user(env->pc, &si->si_regs.pc);
1708 err |= __put_user(env->npc, &si->si_regs.npc);
1709 err |= __put_user(env->y, &si->si_regs.y);
1710 for (i=0; i < 8; i++) {
1711 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1713 for (i=0; i < 8; i++) {
1714 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1716 err |= __put_user(mask, &si->si_mask);
1717 return err;
1720 #if 0
1721 static int
1722 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1723 CPUState *env, unsigned long mask)
1725 int err = 0;
1727 err |= __put_user(mask, &sc->sigc_mask);
1728 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1729 err |= __put_user(env->pc, &sc->sigc_pc);
1730 err |= __put_user(env->npc, &sc->sigc_npc);
1731 err |= __put_user(env->psr, &sc->sigc_psr);
1732 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1733 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1735 return err;
1737 #endif
1738 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1740 static void setup_frame(int sig, struct target_sigaction *ka,
1741 target_sigset_t *set, CPUState *env)
1743 abi_ulong sf_addr;
1744 struct target_signal_frame *sf;
1745 int sigframe_size, err, i;
1747 /* 1. Make sure everything is clean */
1748 //synchronize_user_stack();
1750 sigframe_size = NF_ALIGNEDSZ;
1751 sf_addr = get_sigframe(ka, env, sigframe_size);
1753 sf = lock_user(VERIFY_WRITE, sf_addr,
1754 sizeof(struct target_signal_frame), 0);
1755 if (!sf)
1756 goto sigsegv;
1758 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1759 #if 0
1760 if (invalid_frame_pointer(sf, sigframe_size))
1761 goto sigill_and_return;
1762 #endif
1763 /* 2. Save the current process state */
1764 err = setup___siginfo(&sf->info, env, set->sig[0]);
1765 err |= __put_user(0, &sf->extra_size);
1767 //err |= save_fpu_state(regs, &sf->fpu_state);
1768 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1770 err |= __put_user(set->sig[0], &sf->info.si_mask);
1771 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1772 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1775 for (i = 0; i < 8; i++) {
1776 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1778 for (i = 0; i < 8; i++) {
1779 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1781 if (err)
1782 goto sigsegv;
1784 /* 3. signal handler back-trampoline and parameters */
1785 env->regwptr[UREG_FP] = sf_addr;
1786 env->regwptr[UREG_I0] = sig;
1787 env->regwptr[UREG_I1] = sf_addr +
1788 offsetof(struct target_signal_frame, info);
1789 env->regwptr[UREG_I2] = sf_addr +
1790 offsetof(struct target_signal_frame, info);
1792 /* 4. signal handler */
1793 env->pc = ka->_sa_handler;
1794 env->npc = (env->pc + 4);
1795 /* 5. return to kernel instructions */
1796 if (ka->sa_restorer)
1797 env->regwptr[UREG_I7] = ka->sa_restorer;
1798 else {
1799 uint32_t val32;
1801 env->regwptr[UREG_I7] = sf_addr +
1802 offsetof(struct target_signal_frame, insns) - 2 * 4;
1804 /* mov __NR_sigreturn, %g1 */
1805 val32 = 0x821020d8;
1806 err |= __put_user(val32, &sf->insns[0]);
1808 /* t 0x10 */
1809 val32 = 0x91d02010;
1810 err |= __put_user(val32, &sf->insns[1]);
1811 if (err)
1812 goto sigsegv;
1814 /* Flush instruction space. */
1815 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1816 // tb_flush(env);
1818 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1819 return;
1820 #if 0
1821 sigill_and_return:
1822 force_sig(TARGET_SIGILL);
1823 #endif
1824 sigsegv:
1825 //fprintf(stderr, "force_sig\n");
1826 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1827 force_sig(TARGET_SIGSEGV);
1829 static inline int
1830 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1832 int err;
1833 #if 0
1834 #ifdef CONFIG_SMP
1835 if (current->flags & PF_USEDFPU)
1836 regs->psr &= ~PSR_EF;
1837 #else
1838 if (current == last_task_used_math) {
1839 last_task_used_math = 0;
1840 regs->psr &= ~PSR_EF;
1842 #endif
1843 current->used_math = 1;
1844 current->flags &= ~PF_USEDFPU;
1845 #endif
1846 #if 0
1847 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1848 return -EFAULT;
1849 #endif
1851 #if 0
1852 /* XXX: incorrect */
1853 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1854 (sizeof(unsigned long) * 32));
1855 #endif
1856 err |= __get_user(env->fsr, &fpu->si_fsr);
1857 #if 0
1858 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1859 if (current->thread.fpqdepth != 0)
1860 err |= __copy_from_user(&current->thread.fpqueue[0],
1861 &fpu->si_fpqueue[0],
1862 ((sizeof(unsigned long) +
1863 (sizeof(unsigned long *)))*16));
1864 #endif
1865 return err;
1869 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1870 target_siginfo_t *info,
1871 target_sigset_t *set, CPUState *env)
1873 fprintf(stderr, "setup_rt_frame: not implemented\n");
1876 long do_sigreturn(CPUState *env)
1878 abi_ulong sf_addr;
1879 struct target_signal_frame *sf;
1880 uint32_t up_psr, pc, npc;
1881 target_sigset_t set;
1882 sigset_t host_set;
1883 abi_ulong fpu_save_addr;
1884 int err, i;
1886 sf_addr = env->regwptr[UREG_FP];
1887 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1888 goto segv_and_exit;
1889 #if 0
1890 fprintf(stderr, "sigreturn\n");
1891 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1892 #endif
1893 //cpu_dump_state(env, stderr, fprintf, 0);
1895 /* 1. Make sure we are not getting garbage from the user */
1897 if (sf_addr & 3)
1898 goto segv_and_exit;
1900 err = __get_user(pc, &sf->info.si_regs.pc);
1901 err |= __get_user(npc, &sf->info.si_regs.npc);
1903 if ((pc | npc) & 3)
1904 goto segv_and_exit;
1906 /* 2. Restore the state */
1907 err |= __get_user(up_psr, &sf->info.si_regs.psr);
1909 /* User can only change condition codes and FPU enabling in %psr. */
1910 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1911 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1913 env->pc = pc;
1914 env->npc = npc;
1915 err |= __get_user(env->y, &sf->info.si_regs.y);
1916 for (i=0; i < 8; i++) {
1917 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1919 for (i=0; i < 8; i++) {
1920 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1923 err |= __get_user(fpu_save_addr, &sf->fpu_save);
1925 //if (fpu_save)
1926 // err |= restore_fpu_state(env, fpu_save);
1928 /* This is pretty much atomic, no amount locking would prevent
1929 * the races which exist anyways.
1931 err |= __get_user(set.sig[0], &sf->info.si_mask);
1932 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1933 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1936 target_to_host_sigset_internal(&host_set, &set);
1937 sigprocmask(SIG_SETMASK, &host_set, NULL);
1939 if (err)
1940 goto segv_and_exit;
1941 unlock_user_struct(sf, sf_addr, 0);
1942 return env->regwptr[0];
1944 segv_and_exit:
1945 unlock_user_struct(sf, sf_addr, 0);
1946 force_sig(TARGET_SIGSEGV);
1949 long do_rt_sigreturn(CPUState *env)
1951 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1952 return -TARGET_ENOSYS;
1955 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1956 #define MC_TSTATE 0
1957 #define MC_PC 1
1958 #define MC_NPC 2
1959 #define MC_Y 3
1960 #define MC_G1 4
1961 #define MC_G2 5
1962 #define MC_G3 6
1963 #define MC_G4 7
1964 #define MC_G5 8
1965 #define MC_G6 9
1966 #define MC_G7 10
1967 #define MC_O0 11
1968 #define MC_O1 12
1969 #define MC_O2 13
1970 #define MC_O3 14
1971 #define MC_O4 15
1972 #define MC_O5 16
1973 #define MC_O6 17
1974 #define MC_O7 18
1975 #define MC_NGREG 19
1977 typedef abi_ulong target_mc_greg_t;
1978 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1980 struct target_mc_fq {
1981 abi_ulong *mcfq_addr;
1982 uint32_t mcfq_insn;
1985 struct target_mc_fpu {
1986 union {
1987 uint32_t sregs[32];
1988 uint64_t dregs[32];
1989 //uint128_t qregs[16];
1990 } mcfpu_fregs;
1991 abi_ulong mcfpu_fsr;
1992 abi_ulong mcfpu_fprs;
1993 abi_ulong mcfpu_gsr;
1994 struct target_mc_fq *mcfpu_fq;
1995 unsigned char mcfpu_qcnt;
1996 unsigned char mcfpu_qentsz;
1997 unsigned char mcfpu_enab;
1999 typedef struct target_mc_fpu target_mc_fpu_t;
2001 typedef struct {
2002 target_mc_gregset_t mc_gregs;
2003 target_mc_greg_t mc_fp;
2004 target_mc_greg_t mc_i7;
2005 target_mc_fpu_t mc_fpregs;
2006 } target_mcontext_t;
2008 struct target_ucontext {
2009 struct target_ucontext *uc_link;
2010 abi_ulong uc_flags;
2011 target_sigset_t uc_sigmask;
2012 target_mcontext_t uc_mcontext;
2015 /* A V9 register window */
2016 struct target_reg_window {
2017 abi_ulong locals[8];
2018 abi_ulong ins[8];
2021 #define TARGET_STACK_BIAS 2047
2023 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2024 void sparc64_set_context(CPUSPARCState *env)
2026 abi_ulong ucp_addr;
2027 struct target_ucontext *ucp;
2028 target_mc_gregset_t *grp;
2029 abi_ulong pc, npc, tstate;
2030 abi_ulong fp, i7, w_addr;
2031 unsigned char fenab;
2032 int err;
2033 unsigned int i;
2035 ucp_addr = env->regwptr[UREG_I0];
2036 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2037 goto do_sigsegv;
2038 grp = &ucp->uc_mcontext.mc_gregs;
2039 err = __get_user(pc, &((*grp)[MC_PC]));
2040 err |= __get_user(npc, &((*grp)[MC_NPC]));
2041 if (err || ((pc | npc) & 3))
2042 goto do_sigsegv;
2043 if (env->regwptr[UREG_I1]) {
2044 target_sigset_t target_set;
2045 sigset_t set;
2047 if (TARGET_NSIG_WORDS == 1) {
2048 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2049 goto do_sigsegv;
2050 } else {
2051 abi_ulong *src, *dst;
2052 src = ucp->uc_sigmask.sig;
2053 dst = target_set.sig;
2054 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2055 i++, dst++, src++)
2056 err |= __get_user(*dst, src);
2057 if (err)
2058 goto do_sigsegv;
2060 target_to_host_sigset_internal(&set, &target_set);
2061 sigprocmask(SIG_SETMASK, &set, NULL);
2063 env->pc = pc;
2064 env->npc = npc;
2065 err |= __get_user(env->y, &((*grp)[MC_Y]));
2066 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2067 env->asi = (tstate >> 24) & 0xff;
2068 PUT_CCR(env, tstate >> 32);
2069 PUT_CWP64(env, tstate & 0x1f);
2070 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2071 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2072 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2073 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2074 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2075 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2076 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2077 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2078 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2079 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2080 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2081 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2082 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2083 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2084 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2086 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2087 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2089 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2090 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2091 abi_ulong) != 0)
2092 goto do_sigsegv;
2093 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2094 abi_ulong) != 0)
2095 goto do_sigsegv;
2096 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2097 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2099 uint32_t *src, *dst;
2100 src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2101 dst = env->fpr;
2102 /* XXX: check that the CPU storage is the same as user context */
2103 for (i = 0; i < 64; i++, dst++, src++)
2104 err |= __get_user(*dst, src);
2106 err |= __get_user(env->fsr,
2107 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2108 err |= __get_user(env->gsr,
2109 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2110 if (err)
2111 goto do_sigsegv;
2112 unlock_user_struct(ucp, ucp_addr, 0);
2113 return;
2114 do_sigsegv:
2115 unlock_user_struct(ucp, ucp_addr, 0);
2116 force_sig(SIGSEGV);
2119 void sparc64_get_context(CPUSPARCState *env)
2121 abi_ulong ucp_addr;
2122 struct target_ucontext *ucp;
2123 target_mc_gregset_t *grp;
2124 target_mcontext_t *mcp;
2125 abi_ulong fp, i7, w_addr;
2126 int err;
2127 unsigned int i;
2128 target_sigset_t target_set;
2129 sigset_t set;
2131 ucp_addr = env->regwptr[UREG_I0];
2132 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2133 goto do_sigsegv;
2135 mcp = &ucp->uc_mcontext;
2136 grp = &mcp->mc_gregs;
2138 /* Skip over the trap instruction, first. */
2139 env->pc = env->npc;
2140 env->npc += 4;
2142 err = 0;
2144 sigprocmask(0, NULL, &set);
2145 host_to_target_sigset_internal(&target_set, &set);
2146 if (TARGET_NSIG_WORDS == 1) {
2147 err |= __put_user(target_set.sig[0],
2148 (abi_ulong *)&ucp->uc_sigmask);
2149 } else {
2150 abi_ulong *src, *dst;
2151 src = target_set.sig;
2152 dst = ucp->uc_sigmask.sig;
2153 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2154 i++, dst++, src++)
2155 err |= __put_user(*src, dst);
2156 if (err)
2157 goto do_sigsegv;
2160 /* XXX: tstate must be saved properly */
2161 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2162 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2163 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2164 err |= __put_user(env->y, &((*grp)[MC_Y]));
2165 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2166 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2167 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2168 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2169 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2170 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2171 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2172 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2173 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2174 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2175 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2176 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2177 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2178 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2179 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2181 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2182 fp = i7 = 0;
2183 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2184 abi_ulong) != 0)
2185 goto do_sigsegv;
2186 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2187 abi_ulong) != 0)
2188 goto do_sigsegv;
2189 err |= __put_user(fp, &(mcp->mc_fp));
2190 err |= __put_user(i7, &(mcp->mc_i7));
2193 uint32_t *src, *dst;
2194 src = env->fpr;
2195 dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2196 /* XXX: check that the CPU storage is the same as user context */
2197 for (i = 0; i < 64; i++, dst++, src++)
2198 err |= __put_user(*src, dst);
2200 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2201 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2202 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2204 if (err)
2205 goto do_sigsegv;
2206 unlock_user_struct(ucp, ucp_addr, 1);
2207 return;
2208 do_sigsegv:
2209 unlock_user_struct(ucp, ucp_addr, 1);
2210 force_sig(SIGSEGV);
2212 #endif
2213 #elif defined(TARGET_ABI_MIPSN64)
2215 # warning signal handling not implemented
2217 static void setup_frame(int sig, struct target_sigaction *ka,
2218 target_sigset_t *set, CPUState *env)
2220 fprintf(stderr, "setup_frame: not implemented\n");
2223 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2224 target_siginfo_t *info,
2225 target_sigset_t *set, CPUState *env)
2227 fprintf(stderr, "setup_rt_frame: not implemented\n");
2230 long do_sigreturn(CPUState *env)
2232 fprintf(stderr, "do_sigreturn: not implemented\n");
2233 return -TARGET_ENOSYS;
2236 long do_rt_sigreturn(CPUState *env)
2238 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2239 return -TARGET_ENOSYS;
2242 #elif defined(TARGET_ABI_MIPSN32)
2244 # warning signal handling not implemented
2246 static void setup_frame(int sig, struct target_sigaction *ka,
2247 target_sigset_t *set, CPUState *env)
2249 fprintf(stderr, "setup_frame: not implemented\n");
2252 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2253 target_siginfo_t *info,
2254 target_sigset_t *set, CPUState *env)
2256 fprintf(stderr, "setup_rt_frame: not implemented\n");
2259 long do_sigreturn(CPUState *env)
2261 fprintf(stderr, "do_sigreturn: not implemented\n");
2262 return -TARGET_ENOSYS;
2265 long do_rt_sigreturn(CPUState *env)
2267 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2268 return -TARGET_ENOSYS;
2271 #elif defined(TARGET_ABI_MIPSO32)
2273 struct target_sigcontext {
2274 uint32_t sc_regmask; /* Unused */
2275 uint32_t sc_status;
2276 uint64_t sc_pc;
2277 uint64_t sc_regs[32];
2278 uint64_t sc_fpregs[32];
2279 uint32_t sc_ownedfp; /* Unused */
2280 uint32_t sc_fpc_csr;
2281 uint32_t sc_fpc_eir; /* Unused */
2282 uint32_t sc_used_math;
2283 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2284 uint64_t sc_mdhi;
2285 uint64_t sc_mdlo;
2286 target_ulong sc_hi1; /* Was sc_cause */
2287 target_ulong sc_lo1; /* Was sc_badvaddr */
2288 target_ulong sc_hi2; /* Was sc_sigset[4] */
2289 target_ulong sc_lo2;
2290 target_ulong sc_hi3;
2291 target_ulong sc_lo3;
2294 struct sigframe {
2295 uint32_t sf_ass[4]; /* argument save space for o32 */
2296 uint32_t sf_code[2]; /* signal trampoline */
2297 struct target_sigcontext sf_sc;
2298 target_sigset_t sf_mask;
2301 /* Install trampoline to jump back from signal handler */
2302 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2304 int err;
2307 * Set up the return code ...
2309 * li v0, __NR__foo_sigreturn
2310 * syscall
2313 err = __put_user(0x24020000 + syscall, tramp + 0);
2314 err |= __put_user(0x0000000c , tramp + 1);
2315 /* flush_cache_sigtramp((unsigned long) tramp); */
2316 return err;
2319 static inline int
2320 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2322 int err = 0;
2324 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2326 #define save_gp_reg(i) do { \
2327 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2328 } while(0)
2329 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2330 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2331 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2332 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2333 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2334 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2335 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2336 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2337 save_gp_reg(31);
2338 #undef save_gp_reg
2340 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2341 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2343 /* Not used yet, but might be useful if we ever have DSP suppport */
2344 #if 0
2345 if (cpu_has_dsp) {
2346 err |= __put_user(mfhi1(), &sc->sc_hi1);
2347 err |= __put_user(mflo1(), &sc->sc_lo1);
2348 err |= __put_user(mfhi2(), &sc->sc_hi2);
2349 err |= __put_user(mflo2(), &sc->sc_lo2);
2350 err |= __put_user(mfhi3(), &sc->sc_hi3);
2351 err |= __put_user(mflo3(), &sc->sc_lo3);
2352 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2354 /* same with 64 bit */
2355 #ifdef CONFIG_64BIT
2356 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2357 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2358 if (cpu_has_dsp) {
2359 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2360 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2361 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2362 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2363 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2364 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2365 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2367 #endif
2368 #endif
2370 #if 0
2371 err |= __put_user(!!used_math(), &sc->sc_used_math);
2373 if (!used_math())
2374 goto out;
2377 * Save FPU state to signal context. Signal handler will "inherit"
2378 * current FPU state.
2380 preempt_disable();
2382 if (!is_fpu_owner()) {
2383 own_fpu();
2384 restore_fp(current);
2386 err |= save_fp_context(sc);
2388 preempt_enable();
2389 out:
2390 #endif
2391 return err;
2394 static inline int
2395 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2397 int err = 0;
2399 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2401 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2402 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2404 #define restore_gp_reg(i) do { \
2405 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2406 } while(0)
2407 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2408 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2409 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2410 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2411 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2412 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2413 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2414 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2415 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2416 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2417 restore_gp_reg(31);
2418 #undef restore_gp_reg
2420 #if 0
2421 if (cpu_has_dsp) {
2422 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2423 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2424 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2425 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2426 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2427 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2428 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2430 #ifdef CONFIG_64BIT
2431 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2432 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2433 if (cpu_has_dsp) {
2434 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2435 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2436 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2437 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2438 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2439 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2440 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2442 #endif
2444 err |= __get_user(used_math, &sc->sc_used_math);
2445 conditional_used_math(used_math);
2447 preempt_disable();
2449 if (used_math()) {
2450 /* restore fpu context if we have used it before */
2451 own_fpu();
2452 err |= restore_fp_context(sc);
2453 } else {
2454 /* signal handler may have used FPU. Give it up. */
2455 lose_fpu();
2458 preempt_enable();
2459 #endif
2460 return err;
2463 * Determine which stack to use..
2465 static inline abi_ulong
2466 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2468 unsigned long sp;
2470 /* Default to using normal stack */
2471 sp = regs->active_tc.gpr[29];
2474 * FPU emulator may have it's own trampoline active just
2475 * above the user stack, 16-bytes before the next lowest
2476 * 16 byte boundary. Try to avoid trashing it.
2478 sp -= 32;
2480 /* This is the X/Open sanctioned signal stack switching. */
2481 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2482 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2485 return (sp - frame_size) & ~7;
2488 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2489 static void setup_frame(int sig, struct target_sigaction * ka,
2490 target_sigset_t *set, CPUState *regs)
2492 struct sigframe *frame;
2493 abi_ulong frame_addr;
2494 int i;
2496 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2497 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2498 goto give_sigsegv;
2500 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2502 if(setup_sigcontext(regs, &frame->sf_sc))
2503 goto give_sigsegv;
2505 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2506 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2507 goto give_sigsegv;
2511 * Arguments to signal handler:
2513 * a0 = signal number
2514 * a1 = 0 (should be cause)
2515 * a2 = pointer to struct sigcontext
2517 * $25 and PC point to the signal handler, $29 points to the
2518 * struct sigframe.
2520 regs->active_tc.gpr[ 4] = sig;
2521 regs->active_tc.gpr[ 5] = 0;
2522 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2523 regs->active_tc.gpr[29] = frame_addr;
2524 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2525 /* The original kernel code sets CP0_EPC to the handler
2526 * since it returns to userland using eret
2527 * we cannot do this here, and we must set PC directly */
2528 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2529 unlock_user_struct(frame, frame_addr, 1);
2530 return;
2532 give_sigsegv:
2533 unlock_user_struct(frame, frame_addr, 1);
2534 force_sig(TARGET_SIGSEGV/*, current*/);
2535 return;
2538 long do_sigreturn(CPUState *regs)
2540 struct sigframe *frame;
2541 abi_ulong frame_addr;
2542 sigset_t blocked;
2543 target_sigset_t target_set;
2544 int i;
2546 #if defined(DEBUG_SIGNAL)
2547 fprintf(stderr, "do_sigreturn\n");
2548 #endif
2549 frame_addr = regs->active_tc.gpr[29];
2550 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2551 goto badframe;
2553 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2554 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2555 goto badframe;
2558 target_to_host_sigset_internal(&blocked, &target_set);
2559 sigprocmask(SIG_SETMASK, &blocked, NULL);
2561 if (restore_sigcontext(regs, &frame->sf_sc))
2562 goto badframe;
2564 #if 0
2566 * Don't let your children do this ...
2568 __asm__ __volatile__(
2569 "move\t$29, %0\n\t"
2570 "j\tsyscall_exit"
2571 :/* no outputs */
2572 :"r" (&regs));
2573 /* Unreached */
2574 #endif
2576 regs->active_tc.PC = regs->CP0_EPC;
2577 /* I am not sure this is right, but it seems to work
2578 * maybe a problem with nested signals ? */
2579 regs->CP0_EPC = 0;
2580 return 0;
2582 badframe:
2583 force_sig(TARGET_SIGSEGV/*, current*/);
2584 return 0;
2587 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2588 target_siginfo_t *info,
2589 target_sigset_t *set, CPUState *env)
2591 fprintf(stderr, "setup_rt_frame: not implemented\n");
2594 long do_rt_sigreturn(CPUState *env)
2596 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2597 return -TARGET_ENOSYS;
2600 #elif defined(TARGET_SH4)
2603 * code and data structures from linux kernel:
2604 * include/asm-sh/sigcontext.h
2605 * arch/sh/kernel/signal.c
2608 struct target_sigcontext {
2609 target_ulong oldmask;
2611 /* CPU registers */
2612 target_ulong sc_gregs[16];
2613 target_ulong sc_pc;
2614 target_ulong sc_pr;
2615 target_ulong sc_sr;
2616 target_ulong sc_gbr;
2617 target_ulong sc_mach;
2618 target_ulong sc_macl;
2620 /* FPU registers */
2621 target_ulong sc_fpregs[16];
2622 target_ulong sc_xfpregs[16];
2623 unsigned int sc_fpscr;
2624 unsigned int sc_fpul;
2625 unsigned int sc_ownedfp;
2628 struct target_sigframe
2630 struct target_sigcontext sc;
2631 target_ulong extramask[TARGET_NSIG_WORDS-1];
2632 uint16_t retcode[3];
2636 struct target_ucontext {
2637 target_ulong uc_flags;
2638 struct target_ucontext *uc_link;
2639 target_stack_t uc_stack;
2640 struct target_sigcontext uc_mcontext;
2641 target_sigset_t uc_sigmask; /* mask last for extensibility */
2644 struct target_rt_sigframe
2646 struct target_siginfo info;
2647 struct target_ucontext uc;
2648 uint16_t retcode[3];
2652 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2653 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2655 static abi_ulong get_sigframe(struct target_sigaction *ka,
2656 unsigned long sp, size_t frame_size)
2658 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2659 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2662 return (sp - frame_size) & -8ul;
2665 static int setup_sigcontext(struct target_sigcontext *sc,
2666 CPUState *regs, unsigned long mask)
2668 int err = 0;
2670 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2671 COPY(gregs[0]); COPY(gregs[1]);
2672 COPY(gregs[2]); COPY(gregs[3]);
2673 COPY(gregs[4]); COPY(gregs[5]);
2674 COPY(gregs[6]); COPY(gregs[7]);
2675 COPY(gregs[8]); COPY(gregs[9]);
2676 COPY(gregs[10]); COPY(gregs[11]);
2677 COPY(gregs[12]); COPY(gregs[13]);
2678 COPY(gregs[14]); COPY(gregs[15]);
2679 COPY(gbr); COPY(mach);
2680 COPY(macl); COPY(pr);
2681 COPY(sr); COPY(pc);
2682 #undef COPY
2684 /* todo: save FPU registers here */
2686 /* non-iBCS2 extensions.. */
2687 err |= __put_user(mask, &sc->oldmask);
2689 return err;
2692 static int restore_sigcontext(struct CPUState *regs,
2693 struct target_sigcontext *sc)
2695 unsigned int err = 0;
2697 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2698 COPY(gregs[1]);
2699 COPY(gregs[2]); COPY(gregs[3]);
2700 COPY(gregs[4]); COPY(gregs[5]);
2701 COPY(gregs[6]); COPY(gregs[7]);
2702 COPY(gregs[8]); COPY(gregs[9]);
2703 COPY(gregs[10]); COPY(gregs[11]);
2704 COPY(gregs[12]); COPY(gregs[13]);
2705 COPY(gregs[14]); COPY(gregs[15]);
2706 COPY(gbr); COPY(mach);
2707 COPY(macl); COPY(pr);
2708 COPY(sr); COPY(pc);
2709 #undef COPY
2711 /* todo: restore FPU registers here */
2713 regs->tra = -1; /* disable syscall checks */
2714 return err;
2717 static void setup_frame(int sig, struct target_sigaction *ka,
2718 target_sigset_t *set, CPUState *regs)
2720 struct target_sigframe *frame;
2721 abi_ulong frame_addr;
2722 int i;
2723 int err = 0;
2724 int signal;
2726 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2727 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2728 goto give_sigsegv;
2730 signal = current_exec_domain_sig(sig);
2732 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2734 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2735 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2738 /* Set up to return from userspace. If provided, use a stub
2739 already in userspace. */
2740 if (ka->sa_flags & TARGET_SA_RESTORER) {
2741 regs->pr = (unsigned long) ka->sa_restorer;
2742 } else {
2743 /* Generate return code (system call to sigreturn) */
2744 err |= __put_user(MOVW(2), &frame->retcode[0]);
2745 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2746 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2747 regs->pr = (unsigned long) frame->retcode;
2750 if (err)
2751 goto give_sigsegv;
2753 /* Set up registers for signal handler */
2754 regs->gregs[15] = (unsigned long) frame;
2755 regs->gregs[4] = signal; /* Arg for signal handler */
2756 regs->gregs[5] = 0;
2757 regs->gregs[6] = (unsigned long) &frame->sc;
2758 regs->pc = (unsigned long) ka->_sa_handler;
2760 unlock_user_struct(frame, frame_addr, 1);
2761 return;
2763 give_sigsegv:
2764 unlock_user_struct(frame, frame_addr, 1);
2765 force_sig(SIGSEGV);
2768 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2769 target_siginfo_t *info,
2770 target_sigset_t *set, CPUState *regs)
2772 struct target_rt_sigframe *frame;
2773 abi_ulong frame_addr;
2774 int i;
2775 int err = 0;
2776 int signal;
2778 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2779 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2780 goto give_sigsegv;
2782 signal = current_exec_domain_sig(sig);
2784 err |= copy_siginfo_to_user(&frame->info, info);
2786 /* Create the ucontext. */
2787 err |= __put_user(0, &frame->uc.uc_flags);
2788 err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2789 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2790 &frame->uc.uc_stack.ss_sp);
2791 err |= __put_user(sas_ss_flags(regs->gregs[15]),
2792 &frame->uc.uc_stack.ss_flags);
2793 err |= __put_user(target_sigaltstack_used.ss_size,
2794 &frame->uc.uc_stack.ss_size);
2795 err |= setup_sigcontext(&frame->uc.uc_mcontext,
2796 regs, set->sig[0]);
2797 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2798 err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2801 /* Set up to return from userspace. If provided, use a stub
2802 already in userspace. */
2803 if (ka->sa_flags & TARGET_SA_RESTORER) {
2804 regs->pr = (unsigned long) ka->sa_restorer;
2805 } else {
2806 /* Generate return code (system call to sigreturn) */
2807 err |= __put_user(MOVW(2), &frame->retcode[0]);
2808 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2809 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2810 regs->pr = (unsigned long) frame->retcode;
2813 if (err)
2814 goto give_sigsegv;
2816 /* Set up registers for signal handler */
2817 regs->gregs[15] = (unsigned long) frame;
2818 regs->gregs[4] = signal; /* Arg for signal handler */
2819 regs->gregs[5] = (unsigned long) &frame->info;
2820 regs->gregs[6] = (unsigned long) &frame->uc;
2821 regs->pc = (unsigned long) ka->_sa_handler;
2823 unlock_user_struct(frame, frame_addr, 1);
2824 return;
2826 give_sigsegv:
2827 unlock_user_struct(frame, frame_addr, 1);
2828 force_sig(SIGSEGV);
2831 long do_sigreturn(CPUState *regs)
2833 struct target_sigframe *frame;
2834 abi_ulong frame_addr;
2835 sigset_t blocked;
2836 target_sigset_t target_set;
2837 int i;
2838 int err = 0;
2840 #if defined(DEBUG_SIGNAL)
2841 fprintf(stderr, "do_sigreturn\n");
2842 #endif
2843 frame_addr = regs->gregs[15];
2844 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2845 goto badframe;
2847 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2848 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2849 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2852 if (err)
2853 goto badframe;
2855 target_to_host_sigset_internal(&blocked, &target_set);
2856 sigprocmask(SIG_SETMASK, &blocked, NULL);
2858 if (restore_sigcontext(regs, &frame->sc))
2859 goto badframe;
2861 unlock_user_struct(frame, frame_addr, 0);
2862 return regs->gregs[0];
2864 badframe:
2865 unlock_user_struct(frame, frame_addr, 0);
2866 force_sig(TARGET_SIGSEGV);
2867 return 0;
2870 long do_rt_sigreturn(CPUState *regs)
2872 struct target_rt_sigframe *frame;
2873 abi_ulong frame_addr;
2874 sigset_t blocked;
2876 #if defined(DEBUG_SIGNAL)
2877 fprintf(stderr, "do_rt_sigreturn\n");
2878 #endif
2879 frame_addr = regs->gregs[15];
2880 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2881 goto badframe;
2883 target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2884 sigprocmask(SIG_SETMASK, &blocked, NULL);
2886 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2887 goto badframe;
2889 if (do_sigaltstack(frame_addr +
2890 offsetof(struct target_rt_sigframe, uc.uc_stack),
2891 0, get_sp_from_cpustate(regs)) == -EFAULT)
2892 goto badframe;
2894 unlock_user_struct(frame, frame_addr, 0);
2895 return regs->gregs[0];
2897 badframe:
2898 unlock_user_struct(frame, frame_addr, 0);
2899 force_sig(TARGET_SIGSEGV);
2900 return 0;
2902 #elif defined(TARGET_CRIS)
2904 struct target_sigcontext {
2905 struct target_pt_regs regs; /* needs to be first */
2906 uint32_t oldmask;
2907 uint32_t usp; /* usp before stacking this gunk on it */
2910 /* Signal frames. */
2911 struct target_signal_frame {
2912 struct target_sigcontext sc;
2913 uint32_t extramask[TARGET_NSIG_WORDS - 1];
2914 uint8_t retcode[8]; /* Trampoline code. */
2917 struct rt_signal_frame {
2918 struct siginfo *pinfo;
2919 void *puc;
2920 struct siginfo info;
2921 struct ucontext uc;
2922 uint8_t retcode[8]; /* Trampoline code. */
2925 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2927 __put_user(env->regs[0], &sc->regs.r0);
2928 __put_user(env->regs[1], &sc->regs.r1);
2929 __put_user(env->regs[2], &sc->regs.r2);
2930 __put_user(env->regs[3], &sc->regs.r3);
2931 __put_user(env->regs[4], &sc->regs.r4);
2932 __put_user(env->regs[5], &sc->regs.r5);
2933 __put_user(env->regs[6], &sc->regs.r6);
2934 __put_user(env->regs[7], &sc->regs.r7);
2935 __put_user(env->regs[8], &sc->regs.r8);
2936 __put_user(env->regs[9], &sc->regs.r9);
2937 __put_user(env->regs[10], &sc->regs.r10);
2938 __put_user(env->regs[11], &sc->regs.r11);
2939 __put_user(env->regs[12], &sc->regs.r12);
2940 __put_user(env->regs[13], &sc->regs.r13);
2941 __put_user(env->regs[14], &sc->usp);
2942 __put_user(env->regs[15], &sc->regs.acr);
2943 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2944 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2945 __put_user(env->pc, &sc->regs.erp);
2948 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2950 __get_user(env->regs[0], &sc->regs.r0);
2951 __get_user(env->regs[1], &sc->regs.r1);
2952 __get_user(env->regs[2], &sc->regs.r2);
2953 __get_user(env->regs[3], &sc->regs.r3);
2954 __get_user(env->regs[4], &sc->regs.r4);
2955 __get_user(env->regs[5], &sc->regs.r5);
2956 __get_user(env->regs[6], &sc->regs.r6);
2957 __get_user(env->regs[7], &sc->regs.r7);
2958 __get_user(env->regs[8], &sc->regs.r8);
2959 __get_user(env->regs[9], &sc->regs.r9);
2960 __get_user(env->regs[10], &sc->regs.r10);
2961 __get_user(env->regs[11], &sc->regs.r11);
2962 __get_user(env->regs[12], &sc->regs.r12);
2963 __get_user(env->regs[13], &sc->regs.r13);
2964 __get_user(env->regs[14], &sc->usp);
2965 __get_user(env->regs[15], &sc->regs.acr);
2966 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2967 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2968 __get_user(env->pc, &sc->regs.erp);
2971 static abi_ulong get_sigframe(CPUState *env, int framesize)
2973 abi_ulong sp;
2974 /* Align the stack downwards to 4. */
2975 sp = (env->regs[R_SP] & ~3);
2976 return sp - framesize;
2979 static void setup_frame(int sig, struct target_sigaction *ka,
2980 target_sigset_t *set, CPUState *env)
2982 struct target_signal_frame *frame;
2983 abi_ulong frame_addr;
2984 int err = 0;
2985 int i;
2987 frame_addr = get_sigframe(env, sizeof *frame);
2988 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2989 goto badframe;
2992 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2993 * use this trampoline anymore but it sets it up for GDB.
2994 * In QEMU, using the trampoline simplifies things a bit so we use it.
2996 * This is movu.w __NR_sigreturn, r9; break 13;
2998 err |= __put_user(0x9c5f, frame->retcode+0);
2999 err |= __put_user(TARGET_NR_sigreturn,
3000 frame->retcode+2);
3001 err |= __put_user(0xe93d, frame->retcode+4);
3003 /* Save the mask. */
3004 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3005 if (err)
3006 goto badframe;
3008 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3009 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3010 goto badframe;
3013 setup_sigcontext(&frame->sc, env);
3015 /* Move the stack and setup the arguments for the handler. */
3016 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3017 env->regs[10] = sig;
3018 env->pc = (unsigned long) ka->_sa_handler;
3019 /* Link SRP so the guest returns through the trampoline. */
3020 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3022 unlock_user_struct(frame, frame_addr, 1);
3023 return;
3024 badframe:
3025 unlock_user_struct(frame, frame_addr, 1);
3026 force_sig(TARGET_SIGSEGV);
3029 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3030 target_siginfo_t *info,
3031 target_sigset_t *set, CPUState *env)
3033 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3036 long do_sigreturn(CPUState *env)
3038 struct target_signal_frame *frame;
3039 abi_ulong frame_addr;
3040 target_sigset_t target_set;
3041 sigset_t set;
3042 int i;
3044 frame_addr = env->regs[R_SP];
3045 /* Make sure the guest isn't playing games. */
3046 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3047 goto badframe;
3049 /* Restore blocked signals */
3050 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3051 goto badframe;
3052 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3053 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3054 goto badframe;
3056 target_to_host_sigset_internal(&set, &target_set);
3057 sigprocmask(SIG_SETMASK, &set, NULL);
3059 restore_sigcontext(&frame->sc, env);
3060 unlock_user_struct(frame, frame_addr, 0);
3061 return env->regs[10];
3062 badframe:
3063 unlock_user_struct(frame, frame_addr, 0);
3064 force_sig(TARGET_SIGSEGV);
3067 long do_rt_sigreturn(CPUState *env)
3069 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3070 return -TARGET_ENOSYS;
3073 #else
3075 static void setup_frame(int sig, struct target_sigaction *ka,
3076 target_sigset_t *set, CPUState *env)
3078 fprintf(stderr, "setup_frame: not implemented\n");
3081 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3082 target_siginfo_t *info,
3083 target_sigset_t *set, CPUState *env)
3085 fprintf(stderr, "setup_rt_frame: not implemented\n");
3088 long do_sigreturn(CPUState *env)
3090 fprintf(stderr, "do_sigreturn: not implemented\n");
3091 return -TARGET_ENOSYS;
3094 long do_rt_sigreturn(CPUState *env)
3096 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3097 return -TARGET_ENOSYS;
3100 #endif
3102 void process_pending_signals(CPUState *cpu_env)
3104 int sig;
3105 abi_ulong handler;
3106 sigset_t set, old_set;
3107 target_sigset_t target_old_set;
3108 struct emulated_sigtable *k;
3109 struct target_sigaction *sa;
3110 struct sigqueue *q;
3111 TaskState *ts = cpu_env->opaque;
3113 if (!ts->signal_pending)
3114 return;
3116 /* FIXME: This is not threadsafe. */
3117 k = ts->sigtab;
3118 for(sig = 1; sig <= TARGET_NSIG; sig++) {
3119 if (k->pending)
3120 goto handle_signal;
3121 k++;
3123 /* if no signal is pending, just return */
3124 ts->signal_pending = 0;
3125 return;
3127 handle_signal:
3128 #ifdef DEBUG_SIGNAL
3129 fprintf(stderr, "qemu: process signal %d\n", sig);
3130 #endif
3131 /* dequeue signal */
3132 q = k->first;
3133 k->first = q->next;
3134 if (!k->first)
3135 k->pending = 0;
3137 sig = gdb_handlesig (cpu_env, sig);
3138 if (!sig) {
3139 sa = NULL;
3140 handler = TARGET_SIG_IGN;
3141 } else {
3142 sa = &sigact_table[sig - 1];
3143 handler = sa->_sa_handler;
3146 if (handler == TARGET_SIG_DFL) {
3147 /* default handler : ignore some signal. The other are job control or fatal */
3148 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
3149 kill(getpid(),SIGSTOP);
3150 } else if (sig != TARGET_SIGCHLD &&
3151 sig != TARGET_SIGURG &&
3152 sig != TARGET_SIGWINCH &&
3153 sig != TARGET_SIGCONT) {
3154 force_sig(sig);
3156 } else if (handler == TARGET_SIG_IGN) {
3157 /* ignore sig */
3158 } else if (handler == TARGET_SIG_ERR) {
3159 force_sig(sig);
3160 } else {
3161 /* compute the blocked signals during the handler execution */
3162 target_to_host_sigset(&set, &sa->sa_mask);
3163 /* SA_NODEFER indicates that the current signal should not be
3164 blocked during the handler */
3165 if (!(sa->sa_flags & TARGET_SA_NODEFER))
3166 sigaddset(&set, target_to_host_signal(sig));
3168 /* block signals in the handler using Linux */
3169 sigprocmask(SIG_BLOCK, &set, &old_set);
3170 /* save the previous blocked signal state to restore it at the
3171 end of the signal execution (see do_sigreturn) */
3172 host_to_target_sigset_internal(&target_old_set, &old_set);
3174 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3175 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3177 CPUX86State *env = cpu_env;
3178 if (env->eflags & VM_MASK)
3179 save_v86_state(env);
3181 #endif
3182 /* prepare the stack frame of the virtual CPU */
3183 if (sa->sa_flags & TARGET_SA_SIGINFO)
3184 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3185 else
3186 setup_frame(sig, sa, &target_old_set, cpu_env);
3187 if (sa->sa_flags & TARGET_SA_RESETHAND)
3188 sa->_sa_handler = TARGET_SIG_DFL;
3190 if (q != &k->info)
3191 free_sigqueue(cpu_env, q);