target-ppc: revert part of commit r6254 committed accidentally
[qemu/mini2440.git] / linux-user / signal.c
blobc3f73812897f4c5cd3c38f413a75d8221e991faf
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 "target_signal.h"
33 //#define DEBUG_SIGNAL
35 static struct target_sigaltstack target_sigaltstack_used = {
36 .ss_sp = 0,
37 .ss_size = 0,
38 .ss_flags = TARGET_SS_DISABLE,
41 static struct target_sigaction sigact_table[TARGET_NSIG];
43 static void host_signal_handler(int host_signum, siginfo_t *info,
44 void *puc);
46 static uint8_t host_to_target_signal_table[65] = {
47 [SIGHUP] = TARGET_SIGHUP,
48 [SIGINT] = TARGET_SIGINT,
49 [SIGQUIT] = TARGET_SIGQUIT,
50 [SIGILL] = TARGET_SIGILL,
51 [SIGTRAP] = TARGET_SIGTRAP,
52 [SIGABRT] = TARGET_SIGABRT,
53 /* [SIGIOT] = TARGET_SIGIOT,*/
54 [SIGBUS] = TARGET_SIGBUS,
55 [SIGFPE] = TARGET_SIGFPE,
56 [SIGKILL] = TARGET_SIGKILL,
57 [SIGUSR1] = TARGET_SIGUSR1,
58 [SIGSEGV] = TARGET_SIGSEGV,
59 [SIGUSR2] = TARGET_SIGUSR2,
60 [SIGPIPE] = TARGET_SIGPIPE,
61 [SIGALRM] = TARGET_SIGALRM,
62 [SIGTERM] = TARGET_SIGTERM,
63 #ifdef SIGSTKFLT
64 [SIGSTKFLT] = TARGET_SIGSTKFLT,
65 #endif
66 [SIGCHLD] = TARGET_SIGCHLD,
67 [SIGCONT] = TARGET_SIGCONT,
68 [SIGSTOP] = TARGET_SIGSTOP,
69 [SIGTSTP] = TARGET_SIGTSTP,
70 [SIGTTIN] = TARGET_SIGTTIN,
71 [SIGTTOU] = TARGET_SIGTTOU,
72 [SIGURG] = TARGET_SIGURG,
73 [SIGXCPU] = TARGET_SIGXCPU,
74 [SIGXFSZ] = TARGET_SIGXFSZ,
75 [SIGVTALRM] = TARGET_SIGVTALRM,
76 [SIGPROF] = TARGET_SIGPROF,
77 [SIGWINCH] = TARGET_SIGWINCH,
78 [SIGIO] = TARGET_SIGIO,
79 [SIGPWR] = TARGET_SIGPWR,
80 [SIGSYS] = TARGET_SIGSYS,
81 /* next signals stay the same */
82 /* Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with
83 host libpthread signals. This assumes noone actually uses SIGRTMAX :-/
84 To fix this properly we need to do manual signal delivery multiplexed
85 over a single host signal. */
86 [__SIGRTMIN] = __SIGRTMAX,
87 [__SIGRTMAX] = __SIGRTMIN,
89 static uint8_t target_to_host_signal_table[65];
91 static inline int on_sig_stack(unsigned long sp)
93 return (sp - target_sigaltstack_used.ss_sp
94 < target_sigaltstack_used.ss_size);
97 static inline int sas_ss_flags(unsigned long sp)
99 return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
100 : on_sig_stack(sp) ? SS_ONSTACK : 0);
103 static inline int host_to_target_signal(int sig)
105 if (sig > 64)
106 return sig;
107 return host_to_target_signal_table[sig];
110 int target_to_host_signal(int sig)
112 if (sig > 64)
113 return sig;
114 return target_to_host_signal_table[sig];
117 static inline void target_sigemptyset(target_sigset_t *set)
119 memset(set, 0, sizeof(*set));
122 static inline void target_sigaddset(target_sigset_t *set, int signum)
124 signum--;
125 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
126 set->sig[signum / TARGET_NSIG_BPW] |= mask;
129 static inline int target_sigismember(const target_sigset_t *set, int signum)
131 signum--;
132 abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
133 return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
136 static void host_to_target_sigset_internal(target_sigset_t *d,
137 const sigset_t *s)
139 int i;
140 target_sigemptyset(d);
141 for (i = 1; i <= TARGET_NSIG; i++) {
142 if (sigismember(s, i)) {
143 target_sigaddset(d, host_to_target_signal(i));
148 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
150 target_sigset_t d1;
151 int i;
153 host_to_target_sigset_internal(&d1, s);
154 for(i = 0;i < TARGET_NSIG_WORDS; i++)
155 d->sig[i] = tswapl(d1.sig[i]);
158 static void target_to_host_sigset_internal(sigset_t *d,
159 const target_sigset_t *s)
161 int i;
162 sigemptyset(d);
163 for (i = 1; i <= TARGET_NSIG; i++) {
164 if (target_sigismember(s, i)) {
165 sigaddset(d, target_to_host_signal(i));
170 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
172 target_sigset_t s1;
173 int i;
175 for(i = 0;i < TARGET_NSIG_WORDS; i++)
176 s1.sig[i] = tswapl(s->sig[i]);
177 target_to_host_sigset_internal(d, &s1);
180 void host_to_target_old_sigset(abi_ulong *old_sigset,
181 const sigset_t *sigset)
183 target_sigset_t d;
184 host_to_target_sigset(&d, sigset);
185 *old_sigset = d.sig[0];
188 void target_to_host_old_sigset(sigset_t *sigset,
189 const abi_ulong *old_sigset)
191 target_sigset_t d;
192 int i;
194 d.sig[0] = *old_sigset;
195 for(i = 1;i < TARGET_NSIG_WORDS; i++)
196 d.sig[i] = 0;
197 target_to_host_sigset(sigset, &d);
200 /* siginfo conversion */
202 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
203 const siginfo_t *info)
205 int sig;
206 sig = host_to_target_signal(info->si_signo);
207 tinfo->si_signo = sig;
208 tinfo->si_errno = 0;
209 tinfo->si_code = info->si_code;
210 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
211 sig == SIGBUS || sig == SIGTRAP) {
212 /* should never come here, but who knows. The information for
213 the target is irrelevant */
214 tinfo->_sifields._sigfault._addr = 0;
215 } else if (sig == SIGIO) {
216 tinfo->_sifields._sigpoll._fd = info->si_fd;
217 } else if (sig >= TARGET_SIGRTMIN) {
218 tinfo->_sifields._rt._pid = info->si_pid;
219 tinfo->_sifields._rt._uid = info->si_uid;
220 /* XXX: potential problem if 64 bit */
221 tinfo->_sifields._rt._sigval.sival_ptr =
222 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
226 static void tswap_siginfo(target_siginfo_t *tinfo,
227 const target_siginfo_t *info)
229 int sig;
230 sig = info->si_signo;
231 tinfo->si_signo = tswap32(sig);
232 tinfo->si_errno = tswap32(info->si_errno);
233 tinfo->si_code = tswap32(info->si_code);
234 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
235 sig == SIGBUS || sig == SIGTRAP) {
236 tinfo->_sifields._sigfault._addr =
237 tswapl(info->_sifields._sigfault._addr);
238 } else if (sig == SIGIO) {
239 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
240 } else if (sig >= TARGET_SIGRTMIN) {
241 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
242 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
243 tinfo->_sifields._rt._sigval.sival_ptr =
244 tswapl(info->_sifields._rt._sigval.sival_ptr);
249 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
251 host_to_target_siginfo_noswap(tinfo, info);
252 tswap_siginfo(tinfo, tinfo);
255 /* XXX: we support only POSIX RT signals are used. */
256 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
257 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
259 info->si_signo = tswap32(tinfo->si_signo);
260 info->si_errno = tswap32(tinfo->si_errno);
261 info->si_code = tswap32(tinfo->si_code);
262 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
263 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
264 info->si_value.sival_ptr =
265 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
268 static int fatal_signal (int sig)
270 switch (sig) {
271 case TARGET_SIGCHLD:
272 case TARGET_SIGURG:
273 case TARGET_SIGWINCH:
274 /* Ignored by default. */
275 return 0;
276 case TARGET_SIGCONT:
277 case TARGET_SIGSTOP:
278 case TARGET_SIGTSTP:
279 case TARGET_SIGTTIN:
280 case TARGET_SIGTTOU:
281 /* Job control signals. */
282 return 0;
283 default:
284 return 1;
288 void signal_init(void)
290 struct sigaction act;
291 struct sigaction oact;
292 int i, j;
293 int host_sig;
295 /* generate signal conversion tables */
296 for(i = 1; i <= 64; i++) {
297 if (host_to_target_signal_table[i] == 0)
298 host_to_target_signal_table[i] = i;
300 for(i = 1; i <= 64; i++) {
301 j = host_to_target_signal_table[i];
302 target_to_host_signal_table[j] = i;
305 /* set all host signal handlers. ALL signals are blocked during
306 the handlers to serialize them. */
307 memset(sigact_table, 0, sizeof(sigact_table));
309 sigfillset(&act.sa_mask);
310 act.sa_flags = SA_SIGINFO;
311 act.sa_sigaction = host_signal_handler;
312 for(i = 1; i <= TARGET_NSIG; i++) {
313 host_sig = target_to_host_signal(i);
314 sigaction(host_sig, NULL, &oact);
315 if (oact.sa_sigaction == (void *)SIG_IGN) {
316 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
317 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
318 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
320 /* If there's already a handler installed then something has
321 gone horribly wrong, so don't even try to handle that case. */
322 /* Install some handlers for our own use. We need at least
323 SIGSEGV and SIGBUS, to detect exceptions. We can not just
324 trap all signals because it affects syscall interrupt
325 behavior. But do trap all default-fatal signals. */
326 if (fatal_signal (i))
327 sigaction(host_sig, &act, NULL);
331 /* signal queue handling */
333 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
335 TaskState *ts = env->opaque;
336 struct sigqueue *q = ts->first_free;
337 if (!q)
338 return NULL;
339 ts->first_free = q->next;
340 return q;
343 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
345 TaskState *ts = env->opaque;
346 q->next = ts->first_free;
347 ts->first_free = q;
350 /* abort execution with signal */
351 static void __attribute((noreturn)) force_sig(int sig)
353 int host_sig;
354 host_sig = target_to_host_signal(sig);
355 fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
356 sig, strsignal(host_sig));
357 #if 1
358 gdb_signalled(thread_env, sig);
359 _exit(-host_sig);
360 #else
362 struct sigaction act;
363 sigemptyset(&act.sa_mask);
364 act.sa_flags = SA_SIGINFO;
365 act.sa_sigaction = SIG_DFL;
366 sigaction(SIGABRT, &act, NULL);
367 abort();
369 #endif
372 /* queue a signal so that it will be send to the virtual CPU as soon
373 as possible */
374 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
376 TaskState *ts = env->opaque;
377 struct emulated_sigtable *k;
378 struct sigqueue *q, **pq;
379 abi_ulong handler;
380 int queue;
382 #if defined(DEBUG_SIGNAL)
383 fprintf(stderr, "queue_signal: sig=%d\n",
384 sig);
385 #endif
386 k = &ts->sigtab[sig - 1];
387 queue = gdb_queuesig ();
388 handler = sigact_table[sig - 1]._sa_handler;
389 if (!queue && handler == TARGET_SIG_DFL) {
390 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
391 kill(getpid(),SIGSTOP);
392 return 0;
393 } else
394 /* default handler : ignore some signal. The other are fatal */
395 if (sig != TARGET_SIGCHLD &&
396 sig != TARGET_SIGURG &&
397 sig != TARGET_SIGWINCH &&
398 sig != TARGET_SIGCONT) {
399 force_sig(sig);
400 } else {
401 return 0; /* indicate ignored */
403 } else if (!queue && handler == TARGET_SIG_IGN) {
404 /* ignore signal */
405 return 0;
406 } else if (!queue && handler == TARGET_SIG_ERR) {
407 force_sig(sig);
408 } else {
409 pq = &k->first;
410 if (sig < TARGET_SIGRTMIN) {
411 /* if non real time signal, we queue exactly one signal */
412 if (!k->pending)
413 q = &k->info;
414 else
415 return 0;
416 } else {
417 if (!k->pending) {
418 /* first signal */
419 q = &k->info;
420 } else {
421 q = alloc_sigqueue(env);
422 if (!q)
423 return -EAGAIN;
424 while (*pq != NULL)
425 pq = &(*pq)->next;
428 *pq = q;
429 q->info = *info;
430 q->next = NULL;
431 k->pending = 1;
432 /* signal that a new signal is pending */
433 ts->signal_pending = 1;
434 return 1; /* indicates that the signal was queued */
438 static void host_signal_handler(int host_signum, siginfo_t *info,
439 void *puc)
441 int sig;
442 target_siginfo_t tinfo;
444 /* the CPU emulator uses some host signals to detect exceptions,
445 we forward to it some signals */
446 if ((host_signum == SIGSEGV || host_signum == SIGBUS)
447 && info->si_code > 0) {
448 if (cpu_signal_handler(host_signum, info, puc))
449 return;
452 /* get target signal number */
453 sig = host_to_target_signal(host_signum);
454 if (sig < 1 || sig > TARGET_NSIG)
455 return;
456 #if defined(DEBUG_SIGNAL)
457 fprintf(stderr, "qemu: got signal %d\n", sig);
458 #endif
459 host_to_target_siginfo_noswap(&tinfo, info);
460 if (queue_signal(thread_env, sig, &tinfo) == 1) {
461 /* interrupt the virtual CPU as soon as possible */
462 cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
466 /* do_sigaltstack() returns target values and errnos. */
467 /* compare linux/kernel/signal.c:do_sigaltstack() */
468 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
470 int ret;
471 struct target_sigaltstack oss;
473 /* XXX: test errors */
474 if(uoss_addr)
476 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
477 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
478 __put_user(sas_ss_flags(sp), &oss.ss_flags);
481 if(uss_addr)
483 struct target_sigaltstack *uss;
484 struct target_sigaltstack ss;
486 ret = -TARGET_EFAULT;
487 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
488 || __get_user(ss.ss_sp, &uss->ss_sp)
489 || __get_user(ss.ss_size, &uss->ss_size)
490 || __get_user(ss.ss_flags, &uss->ss_flags))
491 goto out;
492 unlock_user_struct(uss, uss_addr, 0);
494 ret = -TARGET_EPERM;
495 if (on_sig_stack(sp))
496 goto out;
498 ret = -TARGET_EINVAL;
499 if (ss.ss_flags != TARGET_SS_DISABLE
500 && ss.ss_flags != TARGET_SS_ONSTACK
501 && ss.ss_flags != 0)
502 goto out;
504 if (ss.ss_flags == TARGET_SS_DISABLE) {
505 ss.ss_size = 0;
506 ss.ss_sp = 0;
507 } else {
508 ret = -TARGET_ENOMEM;
509 if (ss.ss_size < MINSIGSTKSZ)
510 goto out;
513 target_sigaltstack_used.ss_sp = ss.ss_sp;
514 target_sigaltstack_used.ss_size = ss.ss_size;
517 if (uoss_addr) {
518 ret = -TARGET_EFAULT;
519 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
520 goto out;
523 ret = 0;
524 out:
525 return ret;
528 /* do_sigaction() return host values and errnos */
529 int do_sigaction(int sig, const struct target_sigaction *act,
530 struct target_sigaction *oact)
532 struct target_sigaction *k;
533 struct sigaction act1;
534 int host_sig;
535 int ret = 0;
537 if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
538 return -EINVAL;
539 k = &sigact_table[sig - 1];
540 #if defined(DEBUG_SIGNAL)
541 fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
542 sig, (int)act, (int)oact);
543 #endif
544 if (oact) {
545 oact->_sa_handler = tswapl(k->_sa_handler);
546 oact->sa_flags = tswapl(k->sa_flags);
547 #if !defined(TARGET_MIPS)
548 oact->sa_restorer = tswapl(k->sa_restorer);
549 #endif
550 oact->sa_mask = k->sa_mask;
552 if (act) {
553 /* FIXME: This is not threadsafe. */
554 k->_sa_handler = tswapl(act->_sa_handler);
555 k->sa_flags = tswapl(act->sa_flags);
556 #if !defined(TARGET_MIPS)
557 k->sa_restorer = tswapl(act->sa_restorer);
558 #endif
559 k->sa_mask = act->sa_mask;
561 /* we update the host linux signal state */
562 host_sig = target_to_host_signal(sig);
563 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
564 sigfillset(&act1.sa_mask);
565 act1.sa_flags = SA_SIGINFO;
566 if (k->sa_flags & TARGET_SA_RESTART)
567 act1.sa_flags |= SA_RESTART;
568 /* NOTE: it is important to update the host kernel signal
569 ignore state to avoid getting unexpected interrupted
570 syscalls */
571 if (k->_sa_handler == TARGET_SIG_IGN) {
572 act1.sa_sigaction = (void *)SIG_IGN;
573 } else if (k->_sa_handler == TARGET_SIG_DFL) {
574 if (fatal_signal (sig))
575 act1.sa_sigaction = host_signal_handler;
576 else
577 act1.sa_sigaction = (void *)SIG_DFL;
578 } else {
579 act1.sa_sigaction = host_signal_handler;
581 ret = sigaction(host_sig, &act1, NULL);
584 return ret;
587 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
588 const target_siginfo_t *info)
590 tswap_siginfo(tinfo, info);
591 return 0;
594 static inline int current_exec_domain_sig(int sig)
596 return /* current->exec_domain && current->exec_domain->signal_invmap
597 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
600 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
602 /* from the Linux kernel */
604 struct target_fpreg {
605 uint16_t significand[4];
606 uint16_t exponent;
609 struct target_fpxreg {
610 uint16_t significand[4];
611 uint16_t exponent;
612 uint16_t padding[3];
615 struct target_xmmreg {
616 abi_ulong element[4];
619 struct target_fpstate {
620 /* Regular FPU environment */
621 abi_ulong cw;
622 abi_ulong sw;
623 abi_ulong tag;
624 abi_ulong ipoff;
625 abi_ulong cssel;
626 abi_ulong dataoff;
627 abi_ulong datasel;
628 struct target_fpreg _st[8];
629 uint16_t status;
630 uint16_t magic; /* 0xffff = regular FPU data only */
632 /* FXSR FPU environment */
633 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
634 abi_ulong mxcsr;
635 abi_ulong reserved;
636 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
637 struct target_xmmreg _xmm[8];
638 abi_ulong padding[56];
641 #define X86_FXSR_MAGIC 0x0000
643 struct target_sigcontext {
644 uint16_t gs, __gsh;
645 uint16_t fs, __fsh;
646 uint16_t es, __esh;
647 uint16_t ds, __dsh;
648 abi_ulong edi;
649 abi_ulong esi;
650 abi_ulong ebp;
651 abi_ulong esp;
652 abi_ulong ebx;
653 abi_ulong edx;
654 abi_ulong ecx;
655 abi_ulong eax;
656 abi_ulong trapno;
657 abi_ulong err;
658 abi_ulong eip;
659 uint16_t cs, __csh;
660 abi_ulong eflags;
661 abi_ulong esp_at_signal;
662 uint16_t ss, __ssh;
663 abi_ulong fpstate; /* pointer */
664 abi_ulong oldmask;
665 abi_ulong cr2;
668 struct target_ucontext {
669 abi_ulong tuc_flags;
670 abi_ulong tuc_link;
671 target_stack_t tuc_stack;
672 struct target_sigcontext tuc_mcontext;
673 target_sigset_t tuc_sigmask; /* mask last for extensibility */
676 struct sigframe
678 abi_ulong pretcode;
679 int sig;
680 struct target_sigcontext sc;
681 struct target_fpstate fpstate;
682 abi_ulong extramask[TARGET_NSIG_WORDS-1];
683 char retcode[8];
686 struct rt_sigframe
688 abi_ulong pretcode;
689 int sig;
690 abi_ulong pinfo;
691 abi_ulong puc;
692 struct target_siginfo info;
693 struct target_ucontext uc;
694 struct target_fpstate fpstate;
695 char retcode[8];
699 * Set up a signal frame.
702 /* XXX: save x87 state */
703 static int
704 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
705 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
707 int err = 0;
708 uint16_t magic;
710 /* already locked in setup_frame() */
711 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
712 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
713 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
714 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
715 err |= __put_user(env->regs[R_EDI], &sc->edi);
716 err |= __put_user(env->regs[R_ESI], &sc->esi);
717 err |= __put_user(env->regs[R_EBP], &sc->ebp);
718 err |= __put_user(env->regs[R_ESP], &sc->esp);
719 err |= __put_user(env->regs[R_EBX], &sc->ebx);
720 err |= __put_user(env->regs[R_EDX], &sc->edx);
721 err |= __put_user(env->regs[R_ECX], &sc->ecx);
722 err |= __put_user(env->regs[R_EAX], &sc->eax);
723 err |= __put_user(env->exception_index, &sc->trapno);
724 err |= __put_user(env->error_code, &sc->err);
725 err |= __put_user(env->eip, &sc->eip);
726 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
727 err |= __put_user(env->eflags, &sc->eflags);
728 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
729 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
731 cpu_x86_fsave(env, fpstate_addr, 1);
732 fpstate->status = fpstate->sw;
733 magic = 0xffff;
734 err |= __put_user(magic, &fpstate->magic);
735 err |= __put_user(fpstate_addr, &sc->fpstate);
737 /* non-iBCS2 extensions.. */
738 err |= __put_user(mask, &sc->oldmask);
739 err |= __put_user(env->cr[2], &sc->cr2);
740 return err;
744 * Determine which stack to use..
747 static inline abi_ulong
748 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
750 unsigned long esp;
752 /* Default to using normal stack */
753 esp = env->regs[R_ESP];
754 /* This is the X/Open sanctioned signal stack switching. */
755 if (ka->sa_flags & TARGET_SA_ONSTACK) {
756 if (sas_ss_flags(esp) == 0)
757 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
760 /* This is the legacy signal stack switching. */
761 else
762 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
763 !(ka->sa_flags & TARGET_SA_RESTORER) &&
764 ka->sa_restorer) {
765 esp = (unsigned long) ka->sa_restorer;
767 return (esp - frame_size) & -8ul;
770 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
771 static void setup_frame(int sig, struct target_sigaction *ka,
772 target_sigset_t *set, CPUX86State *env)
774 abi_ulong frame_addr;
775 struct sigframe *frame;
776 int i, err = 0;
778 frame_addr = get_sigframe(ka, env, sizeof(*frame));
780 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
781 goto give_sigsegv;
783 err |= __put_user(current_exec_domain_sig(sig),
784 &frame->sig);
785 if (err)
786 goto give_sigsegv;
788 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
789 frame_addr + offsetof(struct sigframe, fpstate));
790 if (err)
791 goto give_sigsegv;
793 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
794 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
795 goto give_sigsegv;
798 /* Set up to return from userspace. If provided, use a stub
799 already in userspace. */
800 if (ka->sa_flags & TARGET_SA_RESTORER) {
801 err |= __put_user(ka->sa_restorer, &frame->pretcode);
802 } else {
803 uint16_t val16;
804 abi_ulong retcode_addr;
805 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
806 err |= __put_user(retcode_addr, &frame->pretcode);
807 /* This is popl %eax ; movl $,%eax ; int $0x80 */
808 val16 = 0xb858;
809 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
810 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
811 val16 = 0x80cd;
812 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
815 if (err)
816 goto give_sigsegv;
818 /* Set up registers for signal handler */
819 env->regs[R_ESP] = frame_addr;
820 env->eip = ka->_sa_handler;
822 cpu_x86_load_seg(env, R_DS, __USER_DS);
823 cpu_x86_load_seg(env, R_ES, __USER_DS);
824 cpu_x86_load_seg(env, R_SS, __USER_DS);
825 cpu_x86_load_seg(env, R_CS, __USER_CS);
826 env->eflags &= ~TF_MASK;
828 unlock_user_struct(frame, frame_addr, 1);
830 return;
832 give_sigsegv:
833 unlock_user_struct(frame, frame_addr, 1);
834 if (sig == TARGET_SIGSEGV)
835 ka->_sa_handler = TARGET_SIG_DFL;
836 force_sig(TARGET_SIGSEGV /* , current */);
839 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
840 static void setup_rt_frame(int sig, struct target_sigaction *ka,
841 target_siginfo_t *info,
842 target_sigset_t *set, CPUX86State *env)
844 abi_ulong frame_addr, addr;
845 struct rt_sigframe *frame;
846 int i, err = 0;
848 frame_addr = get_sigframe(ka, env, sizeof(*frame));
850 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
851 goto give_sigsegv;
853 err |= __put_user(current_exec_domain_sig(sig),
854 &frame->sig);
855 addr = frame_addr + offsetof(struct rt_sigframe, info);
856 err |= __put_user(addr, &frame->pinfo);
857 addr = frame_addr + offsetof(struct rt_sigframe, uc);
858 err |= __put_user(addr, &frame->puc);
859 err |= copy_siginfo_to_user(&frame->info, info);
860 if (err)
861 goto give_sigsegv;
863 /* Create the ucontext. */
864 err |= __put_user(0, &frame->uc.tuc_flags);
865 err |= __put_user(0, &frame->uc.tuc_link);
866 err |= __put_user(target_sigaltstack_used.ss_sp,
867 &frame->uc.tuc_stack.ss_sp);
868 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
869 &frame->uc.tuc_stack.ss_flags);
870 err |= __put_user(target_sigaltstack_used.ss_size,
871 &frame->uc.tuc_stack.ss_size);
872 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
873 env, set->sig[0],
874 frame_addr + offsetof(struct rt_sigframe, fpstate));
875 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
876 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
877 goto give_sigsegv;
880 /* Set up to return from userspace. If provided, use a stub
881 already in userspace. */
882 if (ka->sa_flags & TARGET_SA_RESTORER) {
883 err |= __put_user(ka->sa_restorer, &frame->pretcode);
884 } else {
885 uint16_t val16;
886 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
887 err |= __put_user(addr, &frame->pretcode);
888 /* This is movl $,%eax ; int $0x80 */
889 err |= __put_user(0xb8, (char *)(frame->retcode+0));
890 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
891 val16 = 0x80cd;
892 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
895 if (err)
896 goto give_sigsegv;
898 /* Set up registers for signal handler */
899 env->regs[R_ESP] = frame_addr;
900 env->eip = ka->_sa_handler;
902 cpu_x86_load_seg(env, R_DS, __USER_DS);
903 cpu_x86_load_seg(env, R_ES, __USER_DS);
904 cpu_x86_load_seg(env, R_SS, __USER_DS);
905 cpu_x86_load_seg(env, R_CS, __USER_CS);
906 env->eflags &= ~TF_MASK;
908 unlock_user_struct(frame, frame_addr, 1);
910 return;
912 give_sigsegv:
913 unlock_user_struct(frame, frame_addr, 1);
914 if (sig == TARGET_SIGSEGV)
915 ka->_sa_handler = TARGET_SIG_DFL;
916 force_sig(TARGET_SIGSEGV /* , current */);
919 static int
920 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
922 unsigned int err = 0;
923 abi_ulong fpstate_addr;
924 unsigned int tmpflags;
926 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
927 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
928 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
929 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
931 env->regs[R_EDI] = tswapl(sc->edi);
932 env->regs[R_ESI] = tswapl(sc->esi);
933 env->regs[R_EBP] = tswapl(sc->ebp);
934 env->regs[R_ESP] = tswapl(sc->esp);
935 env->regs[R_EBX] = tswapl(sc->ebx);
936 env->regs[R_EDX] = tswapl(sc->edx);
937 env->regs[R_ECX] = tswapl(sc->ecx);
938 env->eip = tswapl(sc->eip);
940 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
941 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
943 tmpflags = tswapl(sc->eflags);
944 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
945 // regs->orig_eax = -1; /* disable syscall checks */
947 fpstate_addr = tswapl(sc->fpstate);
948 if (fpstate_addr != 0) {
949 if (!access_ok(VERIFY_READ, fpstate_addr,
950 sizeof(struct target_fpstate)))
951 goto badframe;
952 cpu_x86_frstor(env, fpstate_addr, 1);
955 *peax = tswapl(sc->eax);
956 return err;
957 badframe:
958 return 1;
961 long do_sigreturn(CPUX86State *env)
963 struct sigframe *frame;
964 abi_ulong frame_addr = env->regs[R_ESP] - 8;
965 target_sigset_t target_set;
966 sigset_t set;
967 int eax, i;
969 #if defined(DEBUG_SIGNAL)
970 fprintf(stderr, "do_sigreturn\n");
971 #endif
972 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
973 goto badframe;
974 /* set blocked signals */
975 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
976 goto badframe;
977 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
978 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
979 goto badframe;
982 target_to_host_sigset_internal(&set, &target_set);
983 sigprocmask(SIG_SETMASK, &set, NULL);
985 /* restore registers */
986 if (restore_sigcontext(env, &frame->sc, &eax))
987 goto badframe;
988 unlock_user_struct(frame, frame_addr, 0);
989 return eax;
991 badframe:
992 unlock_user_struct(frame, frame_addr, 0);
993 force_sig(TARGET_SIGSEGV);
994 return 0;
997 long do_rt_sigreturn(CPUX86State *env)
999 abi_ulong frame_addr;
1000 struct rt_sigframe *frame;
1001 sigset_t set;
1002 int eax;
1004 frame_addr = env->regs[R_ESP] - 4;
1005 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1006 goto badframe;
1007 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1008 sigprocmask(SIG_SETMASK, &set, NULL);
1010 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1011 goto badframe;
1013 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
1014 get_sp_from_cpustate(env)) == -EFAULT)
1015 goto badframe;
1017 unlock_user_struct(frame, frame_addr, 0);
1018 return eax;
1020 badframe:
1021 unlock_user_struct(frame, frame_addr, 0);
1022 force_sig(TARGET_SIGSEGV);
1023 return 0;
1026 #elif defined(TARGET_ARM)
1028 struct target_sigcontext {
1029 abi_ulong trap_no;
1030 abi_ulong error_code;
1031 abi_ulong oldmask;
1032 abi_ulong arm_r0;
1033 abi_ulong arm_r1;
1034 abi_ulong arm_r2;
1035 abi_ulong arm_r3;
1036 abi_ulong arm_r4;
1037 abi_ulong arm_r5;
1038 abi_ulong arm_r6;
1039 abi_ulong arm_r7;
1040 abi_ulong arm_r8;
1041 abi_ulong arm_r9;
1042 abi_ulong arm_r10;
1043 abi_ulong arm_fp;
1044 abi_ulong arm_ip;
1045 abi_ulong arm_sp;
1046 abi_ulong arm_lr;
1047 abi_ulong arm_pc;
1048 abi_ulong arm_cpsr;
1049 abi_ulong fault_address;
1052 struct target_ucontext_v1 {
1053 abi_ulong tuc_flags;
1054 abi_ulong tuc_link;
1055 target_stack_t tuc_stack;
1056 struct target_sigcontext tuc_mcontext;
1057 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1060 struct target_ucontext_v2 {
1061 abi_ulong tuc_flags;
1062 abi_ulong tuc_link;
1063 target_stack_t tuc_stack;
1064 struct target_sigcontext tuc_mcontext;
1065 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1066 char __unused[128 - sizeof(sigset_t)];
1067 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1070 struct sigframe_v1
1072 struct target_sigcontext sc;
1073 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1074 abi_ulong retcode;
1077 struct sigframe_v2
1079 struct target_ucontext_v2 uc;
1080 abi_ulong retcode;
1083 struct rt_sigframe_v1
1085 abi_ulong pinfo;
1086 abi_ulong puc;
1087 struct target_siginfo info;
1088 struct target_ucontext_v1 uc;
1089 abi_ulong retcode;
1092 struct rt_sigframe_v2
1094 struct target_siginfo info;
1095 struct target_ucontext_v2 uc;
1096 abi_ulong retcode;
1099 #define TARGET_CONFIG_CPU_32 1
1102 * For ARM syscalls, we encode the syscall number into the instruction.
1104 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1105 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1108 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1109 * need two 16-bit instructions.
1111 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1112 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1114 static const abi_ulong retcodes[4] = {
1115 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1116 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1120 #define __get_user_error(x,p,e) __get_user(x, p)
1122 static inline int valid_user_regs(CPUState *regs)
1124 return 1;
1127 static void
1128 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1129 CPUState *env, abi_ulong mask)
1131 __put_user(env->regs[0], &sc->arm_r0);
1132 __put_user(env->regs[1], &sc->arm_r1);
1133 __put_user(env->regs[2], &sc->arm_r2);
1134 __put_user(env->regs[3], &sc->arm_r3);
1135 __put_user(env->regs[4], &sc->arm_r4);
1136 __put_user(env->regs[5], &sc->arm_r5);
1137 __put_user(env->regs[6], &sc->arm_r6);
1138 __put_user(env->regs[7], &sc->arm_r7);
1139 __put_user(env->regs[8], &sc->arm_r8);
1140 __put_user(env->regs[9], &sc->arm_r9);
1141 __put_user(env->regs[10], &sc->arm_r10);
1142 __put_user(env->regs[11], &sc->arm_fp);
1143 __put_user(env->regs[12], &sc->arm_ip);
1144 __put_user(env->regs[13], &sc->arm_sp);
1145 __put_user(env->regs[14], &sc->arm_lr);
1146 __put_user(env->regs[15], &sc->arm_pc);
1147 #ifdef TARGET_CONFIG_CPU_32
1148 __put_user(cpsr_read(env), &sc->arm_cpsr);
1149 #endif
1151 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1152 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1153 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1154 __put_user(mask, &sc->oldmask);
1157 static inline abi_ulong
1158 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1160 unsigned long sp = regs->regs[13];
1163 * This is the X/Open sanctioned signal stack switching.
1165 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1166 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1168 * ATPCS B01 mandates 8-byte alignment
1170 return (sp - framesize) & ~7;
1173 static int
1174 setup_return(CPUState *env, struct target_sigaction *ka,
1175 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1177 abi_ulong handler = ka->_sa_handler;
1178 abi_ulong retcode;
1179 int thumb = handler & 1;
1181 if (ka->sa_flags & TARGET_SA_RESTORER) {
1182 retcode = ka->sa_restorer;
1183 } else {
1184 unsigned int idx = thumb;
1186 if (ka->sa_flags & TARGET_SA_SIGINFO)
1187 idx += 2;
1189 if (__put_user(retcodes[idx], rc))
1190 return 1;
1191 #if 0
1192 flush_icache_range((abi_ulong)rc,
1193 (abi_ulong)(rc + 1));
1194 #endif
1195 retcode = rc_addr + thumb;
1198 env->regs[0] = usig;
1199 env->regs[13] = frame_addr;
1200 env->regs[14] = retcode;
1201 env->regs[15] = handler & (thumb ? ~1 : ~3);
1202 env->thumb = thumb;
1204 #if 0
1205 #ifdef TARGET_CONFIG_CPU_32
1206 env->cpsr = cpsr;
1207 #endif
1208 #endif
1210 return 0;
1213 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1214 target_sigset_t *set, CPUState *env)
1216 struct target_sigaltstack stack;
1217 int i;
1219 /* Clear all the bits of the ucontext we don't use. */
1220 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1222 memset(&stack, 0, sizeof(stack));
1223 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1224 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1225 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1226 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1228 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1229 /* FIXME: Save coprocessor signal frame. */
1230 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1231 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1235 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1236 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1237 target_sigset_t *set, CPUState *regs)
1239 struct sigframe_v1 *frame;
1240 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1241 int i;
1243 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1244 return;
1246 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1248 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1249 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1250 goto end;
1253 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1254 frame_addr + offsetof(struct sigframe_v1, retcode));
1256 end:
1257 unlock_user_struct(frame, frame_addr, 1);
1260 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1261 target_sigset_t *set, CPUState *regs)
1263 struct sigframe_v2 *frame;
1264 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1266 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1267 return;
1269 setup_sigframe_v2(&frame->uc, set, regs);
1271 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1272 frame_addr + offsetof(struct sigframe_v2, retcode));
1274 unlock_user_struct(frame, frame_addr, 1);
1277 static void setup_frame(int usig, struct target_sigaction *ka,
1278 target_sigset_t *set, CPUState *regs)
1280 if (get_osversion() >= 0x020612) {
1281 setup_frame_v2(usig, ka, set, regs);
1282 } else {
1283 setup_frame_v1(usig, ka, set, regs);
1287 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1288 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1289 target_siginfo_t *info,
1290 target_sigset_t *set, CPUState *env)
1292 struct rt_sigframe_v1 *frame;
1293 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1294 struct target_sigaltstack stack;
1295 int i;
1296 abi_ulong info_addr, uc_addr;
1298 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1299 return /* 1 */;
1301 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1302 __put_user(info_addr, &frame->pinfo);
1303 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1304 __put_user(uc_addr, &frame->puc);
1305 copy_siginfo_to_user(&frame->info, info);
1307 /* Clear all the bits of the ucontext we don't use. */
1308 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1310 memset(&stack, 0, sizeof(stack));
1311 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1312 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1313 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1314 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1316 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1317 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1318 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1319 goto end;
1322 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1323 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1325 env->regs[1] = info_addr;
1326 env->regs[2] = uc_addr;
1328 end:
1329 unlock_user_struct(frame, frame_addr, 1);
1332 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1333 target_siginfo_t *info,
1334 target_sigset_t *set, CPUState *env)
1336 struct rt_sigframe_v2 *frame;
1337 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1338 abi_ulong info_addr, uc_addr;
1340 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1341 return /* 1 */;
1343 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1344 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1345 copy_siginfo_to_user(&frame->info, info);
1347 setup_sigframe_v2(&frame->uc, set, env);
1349 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1350 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1352 env->regs[1] = info_addr;
1353 env->regs[2] = uc_addr;
1355 unlock_user_struct(frame, frame_addr, 1);
1358 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1359 target_siginfo_t *info,
1360 target_sigset_t *set, CPUState *env)
1362 if (get_osversion() >= 0x020612) {
1363 setup_rt_frame_v2(usig, ka, info, set, env);
1364 } else {
1365 setup_rt_frame_v1(usig, ka, info, set, env);
1369 static int
1370 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1372 int err = 0;
1373 uint32_t cpsr;
1375 __get_user_error(env->regs[0], &sc->arm_r0, err);
1376 __get_user_error(env->regs[1], &sc->arm_r1, err);
1377 __get_user_error(env->regs[2], &sc->arm_r2, err);
1378 __get_user_error(env->regs[3], &sc->arm_r3, err);
1379 __get_user_error(env->regs[4], &sc->arm_r4, err);
1380 __get_user_error(env->regs[5], &sc->arm_r5, err);
1381 __get_user_error(env->regs[6], &sc->arm_r6, err);
1382 __get_user_error(env->regs[7], &sc->arm_r7, err);
1383 __get_user_error(env->regs[8], &sc->arm_r8, err);
1384 __get_user_error(env->regs[9], &sc->arm_r9, err);
1385 __get_user_error(env->regs[10], &sc->arm_r10, err);
1386 __get_user_error(env->regs[11], &sc->arm_fp, err);
1387 __get_user_error(env->regs[12], &sc->arm_ip, err);
1388 __get_user_error(env->regs[13], &sc->arm_sp, err);
1389 __get_user_error(env->regs[14], &sc->arm_lr, err);
1390 __get_user_error(env->regs[15], &sc->arm_pc, err);
1391 #ifdef TARGET_CONFIG_CPU_32
1392 __get_user_error(cpsr, &sc->arm_cpsr, err);
1393 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1394 #endif
1396 err |= !valid_user_regs(env);
1398 return err;
1401 long do_sigreturn_v1(CPUState *env)
1403 abi_ulong frame_addr;
1404 struct sigframe_v1 *frame;
1405 target_sigset_t set;
1406 sigset_t host_set;
1407 int i;
1410 * Since we stacked the signal on a 64-bit boundary,
1411 * then 'sp' should be word aligned here. If it's
1412 * not, then the user is trying to mess with us.
1414 if (env->regs[13] & 7)
1415 goto badframe;
1417 frame_addr = env->regs[13];
1418 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1419 goto badframe;
1421 if (__get_user(set.sig[0], &frame->sc.oldmask))
1422 goto badframe;
1423 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1424 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1425 goto badframe;
1428 target_to_host_sigset_internal(&host_set, &set);
1429 sigprocmask(SIG_SETMASK, &host_set, NULL);
1431 if (restore_sigcontext(env, &frame->sc))
1432 goto badframe;
1434 #if 0
1435 /* Send SIGTRAP if we're single-stepping */
1436 if (ptrace_cancel_bpt(current))
1437 send_sig(SIGTRAP, current, 1);
1438 #endif
1439 unlock_user_struct(frame, frame_addr, 0);
1440 return env->regs[0];
1442 badframe:
1443 unlock_user_struct(frame, frame_addr, 0);
1444 force_sig(SIGSEGV /* , current */);
1445 return 0;
1448 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1449 struct target_ucontext_v2 *uc)
1451 sigset_t host_set;
1453 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1454 sigprocmask(SIG_SETMASK, &host_set, NULL);
1456 if (restore_sigcontext(env, &uc->tuc_mcontext))
1457 return 1;
1459 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1460 return 1;
1462 #if 0
1463 /* Send SIGTRAP if we're single-stepping */
1464 if (ptrace_cancel_bpt(current))
1465 send_sig(SIGTRAP, current, 1);
1466 #endif
1468 return 0;
1471 long do_sigreturn_v2(CPUState *env)
1473 abi_ulong frame_addr;
1474 struct sigframe_v2 *frame;
1477 * Since we stacked the signal on a 64-bit boundary,
1478 * then 'sp' should be word aligned here. If it's
1479 * not, then the user is trying to mess with us.
1481 if (env->regs[13] & 7)
1482 goto badframe;
1484 frame_addr = env->regs[13];
1485 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1486 goto badframe;
1488 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1489 goto badframe;
1491 unlock_user_struct(frame, frame_addr, 0);
1492 return env->regs[0];
1494 badframe:
1495 unlock_user_struct(frame, frame_addr, 0);
1496 force_sig(SIGSEGV /* , current */);
1497 return 0;
1500 long do_sigreturn(CPUState *env)
1502 if (get_osversion() >= 0x020612) {
1503 return do_sigreturn_v2(env);
1504 } else {
1505 return do_sigreturn_v1(env);
1509 long do_rt_sigreturn_v1(CPUState *env)
1511 abi_ulong frame_addr;
1512 struct rt_sigframe_v1 *frame;
1513 sigset_t host_set;
1516 * Since we stacked the signal on a 64-bit boundary,
1517 * then 'sp' should be word aligned here. If it's
1518 * not, then the user is trying to mess with us.
1520 if (env->regs[13] & 7)
1521 goto badframe;
1523 frame_addr = env->regs[13];
1524 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1525 goto badframe;
1527 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1528 sigprocmask(SIG_SETMASK, &host_set, NULL);
1530 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1531 goto badframe;
1533 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1534 goto badframe;
1536 #if 0
1537 /* Send SIGTRAP if we're single-stepping */
1538 if (ptrace_cancel_bpt(current))
1539 send_sig(SIGTRAP, current, 1);
1540 #endif
1541 unlock_user_struct(frame, frame_addr, 0);
1542 return env->regs[0];
1544 badframe:
1545 unlock_user_struct(frame, frame_addr, 0);
1546 force_sig(SIGSEGV /* , current */);
1547 return 0;
1550 long do_rt_sigreturn_v2(CPUState *env)
1552 abi_ulong frame_addr;
1553 struct rt_sigframe_v2 *frame;
1556 * Since we stacked the signal on a 64-bit boundary,
1557 * then 'sp' should be word aligned here. If it's
1558 * not, then the user is trying to mess with us.
1560 if (env->regs[13] & 7)
1561 goto badframe;
1563 frame_addr = env->regs[13];
1564 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1565 goto badframe;
1567 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1568 goto badframe;
1570 unlock_user_struct(frame, frame_addr, 0);
1571 return env->regs[0];
1573 badframe:
1574 unlock_user_struct(frame, frame_addr, 0);
1575 force_sig(SIGSEGV /* , current */);
1576 return 0;
1579 long do_rt_sigreturn(CPUState *env)
1581 if (get_osversion() >= 0x020612) {
1582 return do_rt_sigreturn_v2(env);
1583 } else {
1584 return do_rt_sigreturn_v1(env);
1588 #elif defined(TARGET_SPARC)
1590 #define __SUNOS_MAXWIN 31
1592 /* This is what SunOS does, so shall I. */
1593 struct target_sigcontext {
1594 abi_ulong sigc_onstack; /* state to restore */
1596 abi_ulong sigc_mask; /* sigmask to restore */
1597 abi_ulong sigc_sp; /* stack pointer */
1598 abi_ulong sigc_pc; /* program counter */
1599 abi_ulong sigc_npc; /* next program counter */
1600 abi_ulong sigc_psr; /* for condition codes etc */
1601 abi_ulong sigc_g1; /* User uses these two registers */
1602 abi_ulong sigc_o0; /* within the trampoline code. */
1604 /* Now comes information regarding the users window set
1605 * at the time of the signal.
1607 abi_ulong sigc_oswins; /* outstanding windows */
1609 /* stack ptrs for each regwin buf */
1610 char *sigc_spbuf[__SUNOS_MAXWIN];
1612 /* Windows to restore after signal */
1613 struct {
1614 abi_ulong locals[8];
1615 abi_ulong ins[8];
1616 } sigc_wbuf[__SUNOS_MAXWIN];
1618 /* A Sparc stack frame */
1619 struct sparc_stackf {
1620 abi_ulong locals[8];
1621 abi_ulong ins[6];
1622 struct sparc_stackf *fp;
1623 abi_ulong callers_pc;
1624 char *structptr;
1625 abi_ulong xargs[6];
1626 abi_ulong xxargs[1];
1629 typedef struct {
1630 struct {
1631 abi_ulong psr;
1632 abi_ulong pc;
1633 abi_ulong npc;
1634 abi_ulong y;
1635 abi_ulong u_regs[16]; /* globals and ins */
1636 } si_regs;
1637 int si_mask;
1638 } __siginfo_t;
1640 typedef struct {
1641 unsigned long si_float_regs [32];
1642 unsigned long si_fsr;
1643 unsigned long si_fpqdepth;
1644 struct {
1645 unsigned long *insn_addr;
1646 unsigned long insn;
1647 } si_fpqueue [16];
1648 } qemu_siginfo_fpu_t;
1651 struct target_signal_frame {
1652 struct sparc_stackf ss;
1653 __siginfo_t info;
1654 abi_ulong fpu_save;
1655 abi_ulong insns[2] __attribute__ ((aligned (8)));
1656 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1657 abi_ulong extra_size; /* Should be 0 */
1658 qemu_siginfo_fpu_t fpu_state;
1660 struct target_rt_signal_frame {
1661 struct sparc_stackf ss;
1662 siginfo_t info;
1663 abi_ulong regs[20];
1664 sigset_t mask;
1665 abi_ulong fpu_save;
1666 unsigned int insns[2];
1667 stack_t stack;
1668 unsigned int extra_size; /* Should be 0 */
1669 qemu_siginfo_fpu_t fpu_state;
1672 #define UREG_O0 16
1673 #define UREG_O6 22
1674 #define UREG_I0 0
1675 #define UREG_I1 1
1676 #define UREG_I2 2
1677 #define UREG_I3 3
1678 #define UREG_I4 4
1679 #define UREG_I5 5
1680 #define UREG_I6 6
1681 #define UREG_I7 7
1682 #define UREG_L0 8
1683 #define UREG_FP UREG_I6
1684 #define UREG_SP UREG_O6
1686 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1687 CPUState *env, unsigned long framesize)
1689 abi_ulong sp;
1691 sp = env->regwptr[UREG_FP];
1693 /* This is the X/Open sanctioned signal stack switching. */
1694 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1695 if (!on_sig_stack(sp)
1696 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1697 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1699 return sp - framesize;
1702 static int
1703 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1705 int err = 0, i;
1707 err |= __put_user(env->psr, &si->si_regs.psr);
1708 err |= __put_user(env->pc, &si->si_regs.pc);
1709 err |= __put_user(env->npc, &si->si_regs.npc);
1710 err |= __put_user(env->y, &si->si_regs.y);
1711 for (i=0; i < 8; i++) {
1712 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1714 for (i=0; i < 8; i++) {
1715 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1717 err |= __put_user(mask, &si->si_mask);
1718 return err;
1721 #if 0
1722 static int
1723 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1724 CPUState *env, unsigned long mask)
1726 int err = 0;
1728 err |= __put_user(mask, &sc->sigc_mask);
1729 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1730 err |= __put_user(env->pc, &sc->sigc_pc);
1731 err |= __put_user(env->npc, &sc->sigc_npc);
1732 err |= __put_user(env->psr, &sc->sigc_psr);
1733 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1734 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1736 return err;
1738 #endif
1739 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1741 static void setup_frame(int sig, struct target_sigaction *ka,
1742 target_sigset_t *set, CPUState *env)
1744 abi_ulong sf_addr;
1745 struct target_signal_frame *sf;
1746 int sigframe_size, err, i;
1748 /* 1. Make sure everything is clean */
1749 //synchronize_user_stack();
1751 sigframe_size = NF_ALIGNEDSZ;
1752 sf_addr = get_sigframe(ka, env, sigframe_size);
1754 sf = lock_user(VERIFY_WRITE, sf_addr,
1755 sizeof(struct target_signal_frame), 0);
1756 if (!sf)
1757 goto sigsegv;
1759 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1760 #if 0
1761 if (invalid_frame_pointer(sf, sigframe_size))
1762 goto sigill_and_return;
1763 #endif
1764 /* 2. Save the current process state */
1765 err = setup___siginfo(&sf->info, env, set->sig[0]);
1766 err |= __put_user(0, &sf->extra_size);
1768 //err |= save_fpu_state(regs, &sf->fpu_state);
1769 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1771 err |= __put_user(set->sig[0], &sf->info.si_mask);
1772 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1773 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1776 for (i = 0; i < 8; i++) {
1777 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1779 for (i = 0; i < 8; i++) {
1780 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1782 if (err)
1783 goto sigsegv;
1785 /* 3. signal handler back-trampoline and parameters */
1786 env->regwptr[UREG_FP] = sf_addr;
1787 env->regwptr[UREG_I0] = sig;
1788 env->regwptr[UREG_I1] = sf_addr +
1789 offsetof(struct target_signal_frame, info);
1790 env->regwptr[UREG_I2] = sf_addr +
1791 offsetof(struct target_signal_frame, info);
1793 /* 4. signal handler */
1794 env->pc = ka->_sa_handler;
1795 env->npc = (env->pc + 4);
1796 /* 5. return to kernel instructions */
1797 if (ka->sa_restorer)
1798 env->regwptr[UREG_I7] = ka->sa_restorer;
1799 else {
1800 uint32_t val32;
1802 env->regwptr[UREG_I7] = sf_addr +
1803 offsetof(struct target_signal_frame, insns) - 2 * 4;
1805 /* mov __NR_sigreturn, %g1 */
1806 val32 = 0x821020d8;
1807 err |= __put_user(val32, &sf->insns[0]);
1809 /* t 0x10 */
1810 val32 = 0x91d02010;
1811 err |= __put_user(val32, &sf->insns[1]);
1812 if (err)
1813 goto sigsegv;
1815 /* Flush instruction space. */
1816 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1817 // tb_flush(env);
1819 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1820 return;
1821 #if 0
1822 sigill_and_return:
1823 force_sig(TARGET_SIGILL);
1824 #endif
1825 sigsegv:
1826 //fprintf(stderr, "force_sig\n");
1827 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1828 force_sig(TARGET_SIGSEGV);
1830 static inline int
1831 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1833 int err;
1834 #if 0
1835 #ifdef CONFIG_SMP
1836 if (current->flags & PF_USEDFPU)
1837 regs->psr &= ~PSR_EF;
1838 #else
1839 if (current == last_task_used_math) {
1840 last_task_used_math = 0;
1841 regs->psr &= ~PSR_EF;
1843 #endif
1844 current->used_math = 1;
1845 current->flags &= ~PF_USEDFPU;
1846 #endif
1847 #if 0
1848 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1849 return -EFAULT;
1850 #endif
1852 #if 0
1853 /* XXX: incorrect */
1854 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1855 (sizeof(unsigned long) * 32));
1856 #endif
1857 err |= __get_user(env->fsr, &fpu->si_fsr);
1858 #if 0
1859 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1860 if (current->thread.fpqdepth != 0)
1861 err |= __copy_from_user(&current->thread.fpqueue[0],
1862 &fpu->si_fpqueue[0],
1863 ((sizeof(unsigned long) +
1864 (sizeof(unsigned long *)))*16));
1865 #endif
1866 return err;
1870 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1871 target_siginfo_t *info,
1872 target_sigset_t *set, CPUState *env)
1874 fprintf(stderr, "setup_rt_frame: not implemented\n");
1877 long do_sigreturn(CPUState *env)
1879 abi_ulong sf_addr;
1880 struct target_signal_frame *sf;
1881 uint32_t up_psr, pc, npc;
1882 target_sigset_t set;
1883 sigset_t host_set;
1884 abi_ulong fpu_save_addr;
1885 int err, i;
1887 sf_addr = env->regwptr[UREG_FP];
1888 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1889 goto segv_and_exit;
1890 #if 0
1891 fprintf(stderr, "sigreturn\n");
1892 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1893 #endif
1894 //cpu_dump_state(env, stderr, fprintf, 0);
1896 /* 1. Make sure we are not getting garbage from the user */
1898 if (sf_addr & 3)
1899 goto segv_and_exit;
1901 err = __get_user(pc, &sf->info.si_regs.pc);
1902 err |= __get_user(npc, &sf->info.si_regs.npc);
1904 if ((pc | npc) & 3)
1905 goto segv_and_exit;
1907 /* 2. Restore the state */
1908 err |= __get_user(up_psr, &sf->info.si_regs.psr);
1910 /* User can only change condition codes and FPU enabling in %psr. */
1911 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1912 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1914 env->pc = pc;
1915 env->npc = npc;
1916 err |= __get_user(env->y, &sf->info.si_regs.y);
1917 for (i=0; i < 8; i++) {
1918 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1920 for (i=0; i < 8; i++) {
1921 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1924 err |= __get_user(fpu_save_addr, &sf->fpu_save);
1926 //if (fpu_save)
1927 // err |= restore_fpu_state(env, fpu_save);
1929 /* This is pretty much atomic, no amount locking would prevent
1930 * the races which exist anyways.
1932 err |= __get_user(set.sig[0], &sf->info.si_mask);
1933 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1934 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1937 target_to_host_sigset_internal(&host_set, &set);
1938 sigprocmask(SIG_SETMASK, &host_set, NULL);
1940 if (err)
1941 goto segv_and_exit;
1942 unlock_user_struct(sf, sf_addr, 0);
1943 return env->regwptr[0];
1945 segv_and_exit:
1946 unlock_user_struct(sf, sf_addr, 0);
1947 force_sig(TARGET_SIGSEGV);
1950 long do_rt_sigreturn(CPUState *env)
1952 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1953 return -TARGET_ENOSYS;
1956 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1957 #define MC_TSTATE 0
1958 #define MC_PC 1
1959 #define MC_NPC 2
1960 #define MC_Y 3
1961 #define MC_G1 4
1962 #define MC_G2 5
1963 #define MC_G3 6
1964 #define MC_G4 7
1965 #define MC_G5 8
1966 #define MC_G6 9
1967 #define MC_G7 10
1968 #define MC_O0 11
1969 #define MC_O1 12
1970 #define MC_O2 13
1971 #define MC_O3 14
1972 #define MC_O4 15
1973 #define MC_O5 16
1974 #define MC_O6 17
1975 #define MC_O7 18
1976 #define MC_NGREG 19
1978 typedef abi_ulong target_mc_greg_t;
1979 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1981 struct target_mc_fq {
1982 abi_ulong *mcfq_addr;
1983 uint32_t mcfq_insn;
1986 struct target_mc_fpu {
1987 union {
1988 uint32_t sregs[32];
1989 uint64_t dregs[32];
1990 //uint128_t qregs[16];
1991 } mcfpu_fregs;
1992 abi_ulong mcfpu_fsr;
1993 abi_ulong mcfpu_fprs;
1994 abi_ulong mcfpu_gsr;
1995 struct target_mc_fq *mcfpu_fq;
1996 unsigned char mcfpu_qcnt;
1997 unsigned char mcfpu_qentsz;
1998 unsigned char mcfpu_enab;
2000 typedef struct target_mc_fpu target_mc_fpu_t;
2002 typedef struct {
2003 target_mc_gregset_t mc_gregs;
2004 target_mc_greg_t mc_fp;
2005 target_mc_greg_t mc_i7;
2006 target_mc_fpu_t mc_fpregs;
2007 } target_mcontext_t;
2009 struct target_ucontext {
2010 struct target_ucontext *uc_link;
2011 abi_ulong uc_flags;
2012 target_sigset_t uc_sigmask;
2013 target_mcontext_t uc_mcontext;
2016 /* A V9 register window */
2017 struct target_reg_window {
2018 abi_ulong locals[8];
2019 abi_ulong ins[8];
2022 #define TARGET_STACK_BIAS 2047
2024 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2025 void sparc64_set_context(CPUSPARCState *env)
2027 abi_ulong ucp_addr;
2028 struct target_ucontext *ucp;
2029 target_mc_gregset_t *grp;
2030 abi_ulong pc, npc, tstate;
2031 abi_ulong fp, i7, w_addr;
2032 unsigned char fenab;
2033 int err;
2034 unsigned int i;
2036 ucp_addr = env->regwptr[UREG_I0];
2037 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2038 goto do_sigsegv;
2039 grp = &ucp->uc_mcontext.mc_gregs;
2040 err = __get_user(pc, &((*grp)[MC_PC]));
2041 err |= __get_user(npc, &((*grp)[MC_NPC]));
2042 if (err || ((pc | npc) & 3))
2043 goto do_sigsegv;
2044 if (env->regwptr[UREG_I1]) {
2045 target_sigset_t target_set;
2046 sigset_t set;
2048 if (TARGET_NSIG_WORDS == 1) {
2049 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2050 goto do_sigsegv;
2051 } else {
2052 abi_ulong *src, *dst;
2053 src = ucp->uc_sigmask.sig;
2054 dst = target_set.sig;
2055 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2056 i++, dst++, src++)
2057 err |= __get_user(*dst, src);
2058 if (err)
2059 goto do_sigsegv;
2061 target_to_host_sigset_internal(&set, &target_set);
2062 sigprocmask(SIG_SETMASK, &set, NULL);
2064 env->pc = pc;
2065 env->npc = npc;
2066 err |= __get_user(env->y, &((*grp)[MC_Y]));
2067 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2068 env->asi = (tstate >> 24) & 0xff;
2069 PUT_CCR(env, tstate >> 32);
2070 PUT_CWP64(env, tstate & 0x1f);
2071 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2072 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2073 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2074 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2075 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2076 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2077 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2078 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2079 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2080 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2081 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2082 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2083 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2084 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2085 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2087 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2088 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2090 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2091 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2092 abi_ulong) != 0)
2093 goto do_sigsegv;
2094 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2095 abi_ulong) != 0)
2096 goto do_sigsegv;
2097 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2098 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2100 uint32_t *src, *dst;
2101 src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2102 dst = env->fpr;
2103 /* XXX: check that the CPU storage is the same as user context */
2104 for (i = 0; i < 64; i++, dst++, src++)
2105 err |= __get_user(*dst, src);
2107 err |= __get_user(env->fsr,
2108 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2109 err |= __get_user(env->gsr,
2110 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2111 if (err)
2112 goto do_sigsegv;
2113 unlock_user_struct(ucp, ucp_addr, 0);
2114 return;
2115 do_sigsegv:
2116 unlock_user_struct(ucp, ucp_addr, 0);
2117 force_sig(SIGSEGV);
2120 void sparc64_get_context(CPUSPARCState *env)
2122 abi_ulong ucp_addr;
2123 struct target_ucontext *ucp;
2124 target_mc_gregset_t *grp;
2125 target_mcontext_t *mcp;
2126 abi_ulong fp, i7, w_addr;
2127 int err;
2128 unsigned int i;
2129 target_sigset_t target_set;
2130 sigset_t set;
2132 ucp_addr = env->regwptr[UREG_I0];
2133 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2134 goto do_sigsegv;
2136 mcp = &ucp->uc_mcontext;
2137 grp = &mcp->mc_gregs;
2139 /* Skip over the trap instruction, first. */
2140 env->pc = env->npc;
2141 env->npc += 4;
2143 err = 0;
2145 sigprocmask(0, NULL, &set);
2146 host_to_target_sigset_internal(&target_set, &set);
2147 if (TARGET_NSIG_WORDS == 1) {
2148 err |= __put_user(target_set.sig[0],
2149 (abi_ulong *)&ucp->uc_sigmask);
2150 } else {
2151 abi_ulong *src, *dst;
2152 src = target_set.sig;
2153 dst = ucp->uc_sigmask.sig;
2154 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2155 i++, dst++, src++)
2156 err |= __put_user(*src, dst);
2157 if (err)
2158 goto do_sigsegv;
2161 /* XXX: tstate must be saved properly */
2162 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2163 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2164 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2165 err |= __put_user(env->y, &((*grp)[MC_Y]));
2166 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2167 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2168 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2169 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2170 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2171 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2172 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2173 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2174 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2175 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2176 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2177 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2178 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2179 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2180 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2182 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2183 fp = i7 = 0;
2184 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2185 abi_ulong) != 0)
2186 goto do_sigsegv;
2187 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2188 abi_ulong) != 0)
2189 goto do_sigsegv;
2190 err |= __put_user(fp, &(mcp->mc_fp));
2191 err |= __put_user(i7, &(mcp->mc_i7));
2194 uint32_t *src, *dst;
2195 src = env->fpr;
2196 dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2197 /* XXX: check that the CPU storage is the same as user context */
2198 for (i = 0; i < 64; i++, dst++, src++)
2199 err |= __put_user(*src, dst);
2201 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2202 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2203 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2205 if (err)
2206 goto do_sigsegv;
2207 unlock_user_struct(ucp, ucp_addr, 1);
2208 return;
2209 do_sigsegv:
2210 unlock_user_struct(ucp, ucp_addr, 1);
2211 force_sig(SIGSEGV);
2213 #endif
2214 #elif defined(TARGET_ABI_MIPSN64)
2216 # warning signal handling not implemented
2218 static void setup_frame(int sig, struct target_sigaction *ka,
2219 target_sigset_t *set, CPUState *env)
2221 fprintf(stderr, "setup_frame: not implemented\n");
2224 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2225 target_siginfo_t *info,
2226 target_sigset_t *set, CPUState *env)
2228 fprintf(stderr, "setup_rt_frame: not implemented\n");
2231 long do_sigreturn(CPUState *env)
2233 fprintf(stderr, "do_sigreturn: not implemented\n");
2234 return -TARGET_ENOSYS;
2237 long do_rt_sigreturn(CPUState *env)
2239 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2240 return -TARGET_ENOSYS;
2243 #elif defined(TARGET_ABI_MIPSN32)
2245 # warning signal handling not implemented
2247 static void setup_frame(int sig, struct target_sigaction *ka,
2248 target_sigset_t *set, CPUState *env)
2250 fprintf(stderr, "setup_frame: not implemented\n");
2253 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2254 target_siginfo_t *info,
2255 target_sigset_t *set, CPUState *env)
2257 fprintf(stderr, "setup_rt_frame: not implemented\n");
2260 long do_sigreturn(CPUState *env)
2262 fprintf(stderr, "do_sigreturn: not implemented\n");
2263 return -TARGET_ENOSYS;
2266 long do_rt_sigreturn(CPUState *env)
2268 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2269 return -TARGET_ENOSYS;
2272 #elif defined(TARGET_ABI_MIPSO32)
2274 struct target_sigcontext {
2275 uint32_t sc_regmask; /* Unused */
2276 uint32_t sc_status;
2277 uint64_t sc_pc;
2278 uint64_t sc_regs[32];
2279 uint64_t sc_fpregs[32];
2280 uint32_t sc_ownedfp; /* Unused */
2281 uint32_t sc_fpc_csr;
2282 uint32_t sc_fpc_eir; /* Unused */
2283 uint32_t sc_used_math;
2284 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2285 uint64_t sc_mdhi;
2286 uint64_t sc_mdlo;
2287 target_ulong sc_hi1; /* Was sc_cause */
2288 target_ulong sc_lo1; /* Was sc_badvaddr */
2289 target_ulong sc_hi2; /* Was sc_sigset[4] */
2290 target_ulong sc_lo2;
2291 target_ulong sc_hi3;
2292 target_ulong sc_lo3;
2295 struct sigframe {
2296 uint32_t sf_ass[4]; /* argument save space for o32 */
2297 uint32_t sf_code[2]; /* signal trampoline */
2298 struct target_sigcontext sf_sc;
2299 target_sigset_t sf_mask;
2302 /* Install trampoline to jump back from signal handler */
2303 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2305 int err;
2308 * Set up the return code ...
2310 * li v0, __NR__foo_sigreturn
2311 * syscall
2314 err = __put_user(0x24020000 + syscall, tramp + 0);
2315 err |= __put_user(0x0000000c , tramp + 1);
2316 /* flush_cache_sigtramp((unsigned long) tramp); */
2317 return err;
2320 static inline int
2321 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2323 int err = 0;
2325 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2327 #define save_gp_reg(i) do { \
2328 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2329 } while(0)
2330 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2331 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2332 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2333 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2334 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2335 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2336 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2337 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2338 save_gp_reg(31);
2339 #undef save_gp_reg
2341 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2342 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2344 /* Not used yet, but might be useful if we ever have DSP suppport */
2345 #if 0
2346 if (cpu_has_dsp) {
2347 err |= __put_user(mfhi1(), &sc->sc_hi1);
2348 err |= __put_user(mflo1(), &sc->sc_lo1);
2349 err |= __put_user(mfhi2(), &sc->sc_hi2);
2350 err |= __put_user(mflo2(), &sc->sc_lo2);
2351 err |= __put_user(mfhi3(), &sc->sc_hi3);
2352 err |= __put_user(mflo3(), &sc->sc_lo3);
2353 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2355 /* same with 64 bit */
2356 #ifdef CONFIG_64BIT
2357 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2358 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2359 if (cpu_has_dsp) {
2360 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2361 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2362 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2363 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2364 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2365 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2366 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2368 #endif
2369 #endif
2371 #if 0
2372 err |= __put_user(!!used_math(), &sc->sc_used_math);
2374 if (!used_math())
2375 goto out;
2378 * Save FPU state to signal context. Signal handler will "inherit"
2379 * current FPU state.
2381 preempt_disable();
2383 if (!is_fpu_owner()) {
2384 own_fpu();
2385 restore_fp(current);
2387 err |= save_fp_context(sc);
2389 preempt_enable();
2390 out:
2391 #endif
2392 return err;
2395 static inline int
2396 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2398 int err = 0;
2400 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2402 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2403 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2405 #define restore_gp_reg(i) do { \
2406 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2407 } while(0)
2408 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2409 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2410 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2411 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2412 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2413 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2414 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2415 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2416 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2417 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2418 restore_gp_reg(31);
2419 #undef restore_gp_reg
2421 #if 0
2422 if (cpu_has_dsp) {
2423 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2424 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2425 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2426 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2427 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2428 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2429 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2431 #ifdef CONFIG_64BIT
2432 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2433 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2434 if (cpu_has_dsp) {
2435 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2436 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2437 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2438 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2439 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2440 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2441 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2443 #endif
2445 err |= __get_user(used_math, &sc->sc_used_math);
2446 conditional_used_math(used_math);
2448 preempt_disable();
2450 if (used_math()) {
2451 /* restore fpu context if we have used it before */
2452 own_fpu();
2453 err |= restore_fp_context(sc);
2454 } else {
2455 /* signal handler may have used FPU. Give it up. */
2456 lose_fpu();
2459 preempt_enable();
2460 #endif
2461 return err;
2464 * Determine which stack to use..
2466 static inline abi_ulong
2467 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2469 unsigned long sp;
2471 /* Default to using normal stack */
2472 sp = regs->active_tc.gpr[29];
2475 * FPU emulator may have it's own trampoline active just
2476 * above the user stack, 16-bytes before the next lowest
2477 * 16 byte boundary. Try to avoid trashing it.
2479 sp -= 32;
2481 /* This is the X/Open sanctioned signal stack switching. */
2482 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2483 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2486 return (sp - frame_size) & ~7;
2489 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2490 static void setup_frame(int sig, struct target_sigaction * ka,
2491 target_sigset_t *set, CPUState *regs)
2493 struct sigframe *frame;
2494 abi_ulong frame_addr;
2495 int i;
2497 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2498 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2499 goto give_sigsegv;
2501 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2503 if(setup_sigcontext(regs, &frame->sf_sc))
2504 goto give_sigsegv;
2506 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2507 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2508 goto give_sigsegv;
2512 * Arguments to signal handler:
2514 * a0 = signal number
2515 * a1 = 0 (should be cause)
2516 * a2 = pointer to struct sigcontext
2518 * $25 and PC point to the signal handler, $29 points to the
2519 * struct sigframe.
2521 regs->active_tc.gpr[ 4] = sig;
2522 regs->active_tc.gpr[ 5] = 0;
2523 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2524 regs->active_tc.gpr[29] = frame_addr;
2525 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2526 /* The original kernel code sets CP0_EPC to the handler
2527 * since it returns to userland using eret
2528 * we cannot do this here, and we must set PC directly */
2529 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2530 unlock_user_struct(frame, frame_addr, 1);
2531 return;
2533 give_sigsegv:
2534 unlock_user_struct(frame, frame_addr, 1);
2535 force_sig(TARGET_SIGSEGV/*, current*/);
2536 return;
2539 long do_sigreturn(CPUState *regs)
2541 struct sigframe *frame;
2542 abi_ulong frame_addr;
2543 sigset_t blocked;
2544 target_sigset_t target_set;
2545 int i;
2547 #if defined(DEBUG_SIGNAL)
2548 fprintf(stderr, "do_sigreturn\n");
2549 #endif
2550 frame_addr = regs->active_tc.gpr[29];
2551 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2552 goto badframe;
2554 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2555 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2556 goto badframe;
2559 target_to_host_sigset_internal(&blocked, &target_set);
2560 sigprocmask(SIG_SETMASK, &blocked, NULL);
2562 if (restore_sigcontext(regs, &frame->sf_sc))
2563 goto badframe;
2565 #if 0
2567 * Don't let your children do this ...
2569 __asm__ __volatile__(
2570 "move\t$29, %0\n\t"
2571 "j\tsyscall_exit"
2572 :/* no outputs */
2573 :"r" (&regs));
2574 /* Unreached */
2575 #endif
2577 regs->active_tc.PC = regs->CP0_EPC;
2578 /* I am not sure this is right, but it seems to work
2579 * maybe a problem with nested signals ? */
2580 regs->CP0_EPC = 0;
2581 return 0;
2583 badframe:
2584 force_sig(TARGET_SIGSEGV/*, current*/);
2585 return 0;
2588 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2589 target_siginfo_t *info,
2590 target_sigset_t *set, CPUState *env)
2592 fprintf(stderr, "setup_rt_frame: not implemented\n");
2595 long do_rt_sigreturn(CPUState *env)
2597 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2598 return -TARGET_ENOSYS;
2601 #elif defined(TARGET_SH4)
2604 * code and data structures from linux kernel:
2605 * include/asm-sh/sigcontext.h
2606 * arch/sh/kernel/signal.c
2609 struct target_sigcontext {
2610 target_ulong oldmask;
2612 /* CPU registers */
2613 target_ulong sc_gregs[16];
2614 target_ulong sc_pc;
2615 target_ulong sc_pr;
2616 target_ulong sc_sr;
2617 target_ulong sc_gbr;
2618 target_ulong sc_mach;
2619 target_ulong sc_macl;
2621 /* FPU registers */
2622 target_ulong sc_fpregs[16];
2623 target_ulong sc_xfpregs[16];
2624 unsigned int sc_fpscr;
2625 unsigned int sc_fpul;
2626 unsigned int sc_ownedfp;
2629 struct target_sigframe
2631 struct target_sigcontext sc;
2632 target_ulong extramask[TARGET_NSIG_WORDS-1];
2633 uint16_t retcode[3];
2637 struct target_ucontext {
2638 target_ulong uc_flags;
2639 struct target_ucontext *uc_link;
2640 target_stack_t uc_stack;
2641 struct target_sigcontext uc_mcontext;
2642 target_sigset_t uc_sigmask; /* mask last for extensibility */
2645 struct target_rt_sigframe
2647 struct target_siginfo info;
2648 struct target_ucontext uc;
2649 uint16_t retcode[3];
2653 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2654 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2656 static abi_ulong get_sigframe(struct target_sigaction *ka,
2657 unsigned long sp, size_t frame_size)
2659 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2660 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2663 return (sp - frame_size) & -8ul;
2666 static int setup_sigcontext(struct target_sigcontext *sc,
2667 CPUState *regs, unsigned long mask)
2669 int err = 0;
2671 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2672 COPY(gregs[0]); COPY(gregs[1]);
2673 COPY(gregs[2]); COPY(gregs[3]);
2674 COPY(gregs[4]); COPY(gregs[5]);
2675 COPY(gregs[6]); COPY(gregs[7]);
2676 COPY(gregs[8]); COPY(gregs[9]);
2677 COPY(gregs[10]); COPY(gregs[11]);
2678 COPY(gregs[12]); COPY(gregs[13]);
2679 COPY(gregs[14]); COPY(gregs[15]);
2680 COPY(gbr); COPY(mach);
2681 COPY(macl); COPY(pr);
2682 COPY(sr); COPY(pc);
2683 #undef COPY
2685 /* todo: save FPU registers here */
2687 /* non-iBCS2 extensions.. */
2688 err |= __put_user(mask, &sc->oldmask);
2690 return err;
2693 static int restore_sigcontext(struct CPUState *regs,
2694 struct target_sigcontext *sc)
2696 unsigned int err = 0;
2698 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2699 COPY(gregs[1]);
2700 COPY(gregs[2]); COPY(gregs[3]);
2701 COPY(gregs[4]); COPY(gregs[5]);
2702 COPY(gregs[6]); COPY(gregs[7]);
2703 COPY(gregs[8]); COPY(gregs[9]);
2704 COPY(gregs[10]); COPY(gregs[11]);
2705 COPY(gregs[12]); COPY(gregs[13]);
2706 COPY(gregs[14]); COPY(gregs[15]);
2707 COPY(gbr); COPY(mach);
2708 COPY(macl); COPY(pr);
2709 COPY(sr); COPY(pc);
2710 #undef COPY
2712 /* todo: restore FPU registers here */
2714 regs->tra = -1; /* disable syscall checks */
2715 return err;
2718 static void setup_frame(int sig, struct target_sigaction *ka,
2719 target_sigset_t *set, CPUState *regs)
2721 struct target_sigframe *frame;
2722 abi_ulong frame_addr;
2723 int i;
2724 int err = 0;
2725 int signal;
2727 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2728 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2729 goto give_sigsegv;
2731 signal = current_exec_domain_sig(sig);
2733 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2735 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2736 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2739 /* Set up to return from userspace. If provided, use a stub
2740 already in userspace. */
2741 if (ka->sa_flags & TARGET_SA_RESTORER) {
2742 regs->pr = (unsigned long) ka->sa_restorer;
2743 } else {
2744 /* Generate return code (system call to sigreturn) */
2745 err |= __put_user(MOVW(2), &frame->retcode[0]);
2746 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2747 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2748 regs->pr = (unsigned long) frame->retcode;
2751 if (err)
2752 goto give_sigsegv;
2754 /* Set up registers for signal handler */
2755 regs->gregs[15] = (unsigned long) frame;
2756 regs->gregs[4] = signal; /* Arg for signal handler */
2757 regs->gregs[5] = 0;
2758 regs->gregs[6] = (unsigned long) &frame->sc;
2759 regs->pc = (unsigned long) ka->_sa_handler;
2761 unlock_user_struct(frame, frame_addr, 1);
2762 return;
2764 give_sigsegv:
2765 unlock_user_struct(frame, frame_addr, 1);
2766 force_sig(SIGSEGV);
2769 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2770 target_siginfo_t *info,
2771 target_sigset_t *set, CPUState *regs)
2773 struct target_rt_sigframe *frame;
2774 abi_ulong frame_addr;
2775 int i;
2776 int err = 0;
2777 int signal;
2779 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2780 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2781 goto give_sigsegv;
2783 signal = current_exec_domain_sig(sig);
2785 err |= copy_siginfo_to_user(&frame->info, info);
2787 /* Create the ucontext. */
2788 err |= __put_user(0, &frame->uc.uc_flags);
2789 err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2790 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2791 &frame->uc.uc_stack.ss_sp);
2792 err |= __put_user(sas_ss_flags(regs->gregs[15]),
2793 &frame->uc.uc_stack.ss_flags);
2794 err |= __put_user(target_sigaltstack_used.ss_size,
2795 &frame->uc.uc_stack.ss_size);
2796 err |= setup_sigcontext(&frame->uc.uc_mcontext,
2797 regs, set->sig[0]);
2798 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2799 err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2802 /* Set up to return from userspace. If provided, use a stub
2803 already in userspace. */
2804 if (ka->sa_flags & TARGET_SA_RESTORER) {
2805 regs->pr = (unsigned long) ka->sa_restorer;
2806 } else {
2807 /* Generate return code (system call to sigreturn) */
2808 err |= __put_user(MOVW(2), &frame->retcode[0]);
2809 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2810 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2811 regs->pr = (unsigned long) frame->retcode;
2814 if (err)
2815 goto give_sigsegv;
2817 /* Set up registers for signal handler */
2818 regs->gregs[15] = (unsigned long) frame;
2819 regs->gregs[4] = signal; /* Arg for signal handler */
2820 regs->gregs[5] = (unsigned long) &frame->info;
2821 regs->gregs[6] = (unsigned long) &frame->uc;
2822 regs->pc = (unsigned long) ka->_sa_handler;
2824 unlock_user_struct(frame, frame_addr, 1);
2825 return;
2827 give_sigsegv:
2828 unlock_user_struct(frame, frame_addr, 1);
2829 force_sig(SIGSEGV);
2832 long do_sigreturn(CPUState *regs)
2834 struct target_sigframe *frame;
2835 abi_ulong frame_addr;
2836 sigset_t blocked;
2837 target_sigset_t target_set;
2838 int i;
2839 int err = 0;
2841 #if defined(DEBUG_SIGNAL)
2842 fprintf(stderr, "do_sigreturn\n");
2843 #endif
2844 frame_addr = regs->gregs[15];
2845 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2846 goto badframe;
2848 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2849 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2850 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2853 if (err)
2854 goto badframe;
2856 target_to_host_sigset_internal(&blocked, &target_set);
2857 sigprocmask(SIG_SETMASK, &blocked, NULL);
2859 if (restore_sigcontext(regs, &frame->sc))
2860 goto badframe;
2862 unlock_user_struct(frame, frame_addr, 0);
2863 return regs->gregs[0];
2865 badframe:
2866 unlock_user_struct(frame, frame_addr, 0);
2867 force_sig(TARGET_SIGSEGV);
2868 return 0;
2871 long do_rt_sigreturn(CPUState *regs)
2873 struct target_rt_sigframe *frame;
2874 abi_ulong frame_addr;
2875 sigset_t blocked;
2877 #if defined(DEBUG_SIGNAL)
2878 fprintf(stderr, "do_rt_sigreturn\n");
2879 #endif
2880 frame_addr = regs->gregs[15];
2881 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2882 goto badframe;
2884 target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2885 sigprocmask(SIG_SETMASK, &blocked, NULL);
2887 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2888 goto badframe;
2890 if (do_sigaltstack(frame_addr +
2891 offsetof(struct target_rt_sigframe, uc.uc_stack),
2892 0, get_sp_from_cpustate(regs)) == -EFAULT)
2893 goto badframe;
2895 unlock_user_struct(frame, frame_addr, 0);
2896 return regs->gregs[0];
2898 badframe:
2899 unlock_user_struct(frame, frame_addr, 0);
2900 force_sig(TARGET_SIGSEGV);
2901 return 0;
2903 #elif defined(TARGET_CRIS)
2905 struct target_sigcontext {
2906 struct target_pt_regs regs; /* needs to be first */
2907 uint32_t oldmask;
2908 uint32_t usp; /* usp before stacking this gunk on it */
2911 /* Signal frames. */
2912 struct target_signal_frame {
2913 struct target_sigcontext sc;
2914 uint32_t extramask[TARGET_NSIG_WORDS - 1];
2915 uint8_t retcode[8]; /* Trampoline code. */
2918 struct rt_signal_frame {
2919 struct siginfo *pinfo;
2920 void *puc;
2921 struct siginfo info;
2922 struct ucontext uc;
2923 uint8_t retcode[8]; /* Trampoline code. */
2926 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2928 __put_user(env->regs[0], &sc->regs.r0);
2929 __put_user(env->regs[1], &sc->regs.r1);
2930 __put_user(env->regs[2], &sc->regs.r2);
2931 __put_user(env->regs[3], &sc->regs.r3);
2932 __put_user(env->regs[4], &sc->regs.r4);
2933 __put_user(env->regs[5], &sc->regs.r5);
2934 __put_user(env->regs[6], &sc->regs.r6);
2935 __put_user(env->regs[7], &sc->regs.r7);
2936 __put_user(env->regs[8], &sc->regs.r8);
2937 __put_user(env->regs[9], &sc->regs.r9);
2938 __put_user(env->regs[10], &sc->regs.r10);
2939 __put_user(env->regs[11], &sc->regs.r11);
2940 __put_user(env->regs[12], &sc->regs.r12);
2941 __put_user(env->regs[13], &sc->regs.r13);
2942 __put_user(env->regs[14], &sc->usp);
2943 __put_user(env->regs[15], &sc->regs.acr);
2944 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2945 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2946 __put_user(env->pc, &sc->regs.erp);
2949 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2951 __get_user(env->regs[0], &sc->regs.r0);
2952 __get_user(env->regs[1], &sc->regs.r1);
2953 __get_user(env->regs[2], &sc->regs.r2);
2954 __get_user(env->regs[3], &sc->regs.r3);
2955 __get_user(env->regs[4], &sc->regs.r4);
2956 __get_user(env->regs[5], &sc->regs.r5);
2957 __get_user(env->regs[6], &sc->regs.r6);
2958 __get_user(env->regs[7], &sc->regs.r7);
2959 __get_user(env->regs[8], &sc->regs.r8);
2960 __get_user(env->regs[9], &sc->regs.r9);
2961 __get_user(env->regs[10], &sc->regs.r10);
2962 __get_user(env->regs[11], &sc->regs.r11);
2963 __get_user(env->regs[12], &sc->regs.r12);
2964 __get_user(env->regs[13], &sc->regs.r13);
2965 __get_user(env->regs[14], &sc->usp);
2966 __get_user(env->regs[15], &sc->regs.acr);
2967 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2968 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2969 __get_user(env->pc, &sc->regs.erp);
2972 static abi_ulong get_sigframe(CPUState *env, int framesize)
2974 abi_ulong sp;
2975 /* Align the stack downwards to 4. */
2976 sp = (env->regs[R_SP] & ~3);
2977 return sp - framesize;
2980 static void setup_frame(int sig, struct target_sigaction *ka,
2981 target_sigset_t *set, CPUState *env)
2983 struct target_signal_frame *frame;
2984 abi_ulong frame_addr;
2985 int err = 0;
2986 int i;
2988 frame_addr = get_sigframe(env, sizeof *frame);
2989 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2990 goto badframe;
2993 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2994 * use this trampoline anymore but it sets it up for GDB.
2995 * In QEMU, using the trampoline simplifies things a bit so we use it.
2997 * This is movu.w __NR_sigreturn, r9; break 13;
2999 err |= __put_user(0x9c5f, frame->retcode+0);
3000 err |= __put_user(TARGET_NR_sigreturn,
3001 frame->retcode+2);
3002 err |= __put_user(0xe93d, frame->retcode+4);
3004 /* Save the mask. */
3005 err |= __put_user(set->sig[0], &frame->sc.oldmask);
3006 if (err)
3007 goto badframe;
3009 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3010 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3011 goto badframe;
3014 setup_sigcontext(&frame->sc, env);
3016 /* Move the stack and setup the arguments for the handler. */
3017 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3018 env->regs[10] = sig;
3019 env->pc = (unsigned long) ka->_sa_handler;
3020 /* Link SRP so the guest returns through the trampoline. */
3021 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3023 unlock_user_struct(frame, frame_addr, 1);
3024 return;
3025 badframe:
3026 unlock_user_struct(frame, frame_addr, 1);
3027 force_sig(TARGET_SIGSEGV);
3030 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3031 target_siginfo_t *info,
3032 target_sigset_t *set, CPUState *env)
3034 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3037 long do_sigreturn(CPUState *env)
3039 struct target_signal_frame *frame;
3040 abi_ulong frame_addr;
3041 target_sigset_t target_set;
3042 sigset_t set;
3043 int i;
3045 frame_addr = env->regs[R_SP];
3046 /* Make sure the guest isn't playing games. */
3047 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3048 goto badframe;
3050 /* Restore blocked signals */
3051 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3052 goto badframe;
3053 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3054 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3055 goto badframe;
3057 target_to_host_sigset_internal(&set, &target_set);
3058 sigprocmask(SIG_SETMASK, &set, NULL);
3060 restore_sigcontext(&frame->sc, env);
3061 unlock_user_struct(frame, frame_addr, 0);
3062 return env->regs[10];
3063 badframe:
3064 unlock_user_struct(frame, frame_addr, 0);
3065 force_sig(TARGET_SIGSEGV);
3068 long do_rt_sigreturn(CPUState *env)
3070 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3071 return -TARGET_ENOSYS;
3074 #else
3076 static void setup_frame(int sig, struct target_sigaction *ka,
3077 target_sigset_t *set, CPUState *env)
3079 fprintf(stderr, "setup_frame: not implemented\n");
3082 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3083 target_siginfo_t *info,
3084 target_sigset_t *set, CPUState *env)
3086 fprintf(stderr, "setup_rt_frame: not implemented\n");
3089 long do_sigreturn(CPUState *env)
3091 fprintf(stderr, "do_sigreturn: not implemented\n");
3092 return -TARGET_ENOSYS;
3095 long do_rt_sigreturn(CPUState *env)
3097 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3098 return -TARGET_ENOSYS;
3101 #endif
3103 void process_pending_signals(CPUState *cpu_env)
3105 int sig;
3106 abi_ulong handler;
3107 sigset_t set, old_set;
3108 target_sigset_t target_old_set;
3109 struct emulated_sigtable *k;
3110 struct target_sigaction *sa;
3111 struct sigqueue *q;
3112 TaskState *ts = cpu_env->opaque;
3114 if (!ts->signal_pending)
3115 return;
3117 /* FIXME: This is not threadsafe. */
3118 k = ts->sigtab;
3119 for(sig = 1; sig <= TARGET_NSIG; sig++) {
3120 if (k->pending)
3121 goto handle_signal;
3122 k++;
3124 /* if no signal is pending, just return */
3125 ts->signal_pending = 0;
3126 return;
3128 handle_signal:
3129 #ifdef DEBUG_SIGNAL
3130 fprintf(stderr, "qemu: process signal %d\n", sig);
3131 #endif
3132 /* dequeue signal */
3133 q = k->first;
3134 k->first = q->next;
3135 if (!k->first)
3136 k->pending = 0;
3138 sig = gdb_handlesig (cpu_env, sig);
3139 if (!sig) {
3140 sa = NULL;
3141 handler = TARGET_SIG_IGN;
3142 } else {
3143 sa = &sigact_table[sig - 1];
3144 handler = sa->_sa_handler;
3147 if (handler == TARGET_SIG_DFL) {
3148 /* default handler : ignore some signal. The other are job control or fatal */
3149 if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
3150 kill(getpid(),SIGSTOP);
3151 } else if (sig != TARGET_SIGCHLD &&
3152 sig != TARGET_SIGURG &&
3153 sig != TARGET_SIGWINCH &&
3154 sig != TARGET_SIGCONT) {
3155 force_sig(sig);
3157 } else if (handler == TARGET_SIG_IGN) {
3158 /* ignore sig */
3159 } else if (handler == TARGET_SIG_ERR) {
3160 force_sig(sig);
3161 } else {
3162 /* compute the blocked signals during the handler execution */
3163 target_to_host_sigset(&set, &sa->sa_mask);
3164 /* SA_NODEFER indicates that the current signal should not be
3165 blocked during the handler */
3166 if (!(sa->sa_flags & TARGET_SA_NODEFER))
3167 sigaddset(&set, target_to_host_signal(sig));
3169 /* block signals in the handler using Linux */
3170 sigprocmask(SIG_BLOCK, &set, &old_set);
3171 /* save the previous blocked signal state to restore it at the
3172 end of the signal execution (see do_sigreturn) */
3173 host_to_target_sigset_internal(&target_old_set, &old_set);
3175 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3176 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3178 CPUX86State *env = cpu_env;
3179 if (env->eflags & VM_MASK)
3180 save_v86_state(env);
3182 #endif
3183 /* prepare the stack frame of the virtual CPU */
3184 if (sa->sa_flags & TARGET_SA_SIGINFO)
3185 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3186 else
3187 setup_frame(sig, sa, &target_old_set, cpu_env);
3188 if (sa->sa_flags & TARGET_SA_RESETHAND)
3189 sa->_sa_handler = TARGET_SIG_DFL;
3191 if (q != &k->info)
3192 free_sigqueue(cpu_env, q);