kvm: testsuite: add register compare helper for realmode tests
[qemu-kvm/fedora.git] / linux-user / signal.c
blobaf40238b2bf91d568b14bf59c0e0aefde3ba733f
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 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 void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
159 int i;
160 sigemptyset(d);
161 for (i = 1; i <= TARGET_NSIG; i++) {
162 if (target_sigismember(s, i)) {
163 sigaddset(d, target_to_host_signal(i));
168 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
170 target_sigset_t s1;
171 int i;
173 for(i = 0;i < TARGET_NSIG_WORDS; i++)
174 s1.sig[i] = tswapl(s->sig[i]);
175 target_to_host_sigset_internal(d, &s1);
178 void host_to_target_old_sigset(abi_ulong *old_sigset,
179 const sigset_t *sigset)
181 target_sigset_t d;
182 host_to_target_sigset(&d, sigset);
183 *old_sigset = d.sig[0];
186 void target_to_host_old_sigset(sigset_t *sigset,
187 const abi_ulong *old_sigset)
189 target_sigset_t d;
190 int i;
192 d.sig[0] = *old_sigset;
193 for(i = 1;i < TARGET_NSIG_WORDS; i++)
194 d.sig[i] = 0;
195 target_to_host_sigset(sigset, &d);
198 /* siginfo conversion */
200 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
201 const siginfo_t *info)
203 int sig;
204 sig = host_to_target_signal(info->si_signo);
205 tinfo->si_signo = sig;
206 tinfo->si_errno = 0;
207 tinfo->si_code = info->si_code;
208 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
209 sig == SIGBUS || sig == SIGTRAP) {
210 /* should never come here, but who knows. The information for
211 the target is irrelevant */
212 tinfo->_sifields._sigfault._addr = 0;
213 } else if (sig == SIGIO) {
214 tinfo->_sifields._sigpoll._fd = info->si_fd;
215 } else if (sig >= TARGET_SIGRTMIN) {
216 tinfo->_sifields._rt._pid = info->si_pid;
217 tinfo->_sifields._rt._uid = info->si_uid;
218 /* XXX: potential problem if 64 bit */
219 tinfo->_sifields._rt._sigval.sival_ptr =
220 (abi_ulong)(unsigned long)info->si_value.sival_ptr;
224 static void tswap_siginfo(target_siginfo_t *tinfo,
225 const target_siginfo_t *info)
227 int sig;
228 sig = info->si_signo;
229 tinfo->si_signo = tswap32(sig);
230 tinfo->si_errno = tswap32(info->si_errno);
231 tinfo->si_code = tswap32(info->si_code);
232 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
233 sig == SIGBUS || sig == SIGTRAP) {
234 tinfo->_sifields._sigfault._addr =
235 tswapl(info->_sifields._sigfault._addr);
236 } else if (sig == SIGIO) {
237 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
238 } else if (sig >= TARGET_SIGRTMIN) {
239 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
240 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
241 tinfo->_sifields._rt._sigval.sival_ptr =
242 tswapl(info->_sifields._rt._sigval.sival_ptr);
247 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
249 host_to_target_siginfo_noswap(tinfo, info);
250 tswap_siginfo(tinfo, tinfo);
253 /* XXX: we support only POSIX RT signals are used. */
254 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
255 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
257 info->si_signo = tswap32(tinfo->si_signo);
258 info->si_errno = tswap32(tinfo->si_errno);
259 info->si_code = tswap32(tinfo->si_code);
260 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
261 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
262 info->si_value.sival_ptr =
263 (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
266 void signal_init(void)
268 struct sigaction act;
269 struct sigaction oact;
270 int i, j;
271 int host_sig;
273 /* generate signal conversion tables */
274 for(i = 1; i <= 64; i++) {
275 if (host_to_target_signal_table[i] == 0)
276 host_to_target_signal_table[i] = i;
278 for(i = 1; i <= 64; i++) {
279 j = host_to_target_signal_table[i];
280 target_to_host_signal_table[j] = i;
283 /* set all host signal handlers. ALL signals are blocked during
284 the handlers to serialize them. */
285 memset(sigact_table, 0, sizeof(sigact_table));
287 sigfillset(&act.sa_mask);
288 act.sa_flags = SA_SIGINFO;
289 act.sa_sigaction = host_signal_handler;
290 for(i = 1; i <= TARGET_NSIG; i++) {
291 host_sig = target_to_host_signal(i);
292 sigaction(host_sig, NULL, &oact);
293 if (oact.sa_sigaction == (void *)SIG_IGN) {
294 sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
295 } else if (oact.sa_sigaction == (void *)SIG_DFL) {
296 sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
298 /* If there's already a handler installed then something has
299 gone horribly wrong, so don't even try to handle that case. */
300 /* Install some handlers for our own use. */
301 if (host_sig == SIGSEGV || host_sig == SIGBUS) {
302 sigaction(host_sig, &act, NULL);
307 /* signal queue handling */
309 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
311 TaskState *ts = env->opaque;
312 struct sigqueue *q = ts->first_free;
313 if (!q)
314 return NULL;
315 ts->first_free = q->next;
316 return q;
319 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
321 TaskState *ts = env->opaque;
322 q->next = ts->first_free;
323 ts->first_free = q;
326 /* abort execution with signal */
327 void __attribute((noreturn)) force_sig(int sig)
329 int host_sig;
330 host_sig = target_to_host_signal(sig);
331 fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
332 sig, strsignal(host_sig));
333 #if 1
334 _exit(-host_sig);
335 #else
337 struct sigaction act;
338 sigemptyset(&act.sa_mask);
339 act.sa_flags = SA_SIGINFO;
340 act.sa_sigaction = SIG_DFL;
341 sigaction(SIGABRT, &act, NULL);
342 abort();
344 #endif
347 /* queue a signal so that it will be send to the virtual CPU as soon
348 as possible */
349 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
351 TaskState *ts = env->opaque;
352 struct emulated_sigtable *k;
353 struct sigqueue *q, **pq;
354 abi_ulong handler;
356 #if defined(DEBUG_SIGNAL)
357 fprintf(stderr, "queue_signal: sig=%d\n",
358 sig);
359 #endif
360 k = &ts->sigtab[sig - 1];
361 handler = sigact_table[sig - 1]._sa_handler;
362 if (handler == TARGET_SIG_DFL) {
363 /* default handler : ignore some signal. The other are fatal */
364 if (sig != TARGET_SIGCHLD &&
365 sig != TARGET_SIGURG &&
366 sig != TARGET_SIGWINCH) {
367 force_sig(sig);
368 } else {
369 return 0; /* indicate ignored */
371 } else if (handler == TARGET_SIG_IGN) {
372 /* ignore signal */
373 return 0;
374 } else if (handler == TARGET_SIG_ERR) {
375 force_sig(sig);
376 } else {
377 pq = &k->first;
378 if (sig < TARGET_SIGRTMIN) {
379 /* if non real time signal, we queue exactly one signal */
380 if (!k->pending)
381 q = &k->info;
382 else
383 return 0;
384 } else {
385 if (!k->pending) {
386 /* first signal */
387 q = &k->info;
388 } else {
389 q = alloc_sigqueue(env);
390 if (!q)
391 return -EAGAIN;
392 while (*pq != NULL)
393 pq = &(*pq)->next;
396 *pq = q;
397 q->info = *info;
398 q->next = NULL;
399 k->pending = 1;
400 /* signal that a new signal is pending */
401 ts->signal_pending = 1;
402 return 1; /* indicates that the signal was queued */
406 static void host_signal_handler(int host_signum, siginfo_t *info,
407 void *puc)
409 int sig;
410 target_siginfo_t tinfo;
412 /* the CPU emulator uses some host signals to detect exceptions,
413 we we forward to it some signals */
414 if (host_signum == SIGSEGV || host_signum == SIGBUS) {
415 if (cpu_signal_handler(host_signum, info, puc))
416 return;
419 /* get target signal number */
420 sig = host_to_target_signal(host_signum);
421 if (sig < 1 || sig > TARGET_NSIG)
422 return;
423 #if defined(DEBUG_SIGNAL)
424 fprintf(stderr, "qemu: got signal %d\n", sig);
425 #endif
426 host_to_target_siginfo_noswap(&tinfo, info);
427 if (queue_signal(thread_env, sig, &tinfo) == 1) {
428 /* interrupt the virtual CPU as soon as possible */
429 cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
433 /* do_sigaltstack() returns target values and errnos. */
434 /* compare linux/kernel/signal.c:do_sigaltstack() */
435 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
437 int ret;
438 struct target_sigaltstack oss;
440 /* XXX: test errors */
441 if(uoss_addr)
443 __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
444 __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
445 __put_user(sas_ss_flags(sp), &oss.ss_flags);
448 if(uss_addr)
450 struct target_sigaltstack *uss;
451 struct target_sigaltstack ss;
453 ret = -TARGET_EFAULT;
454 if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
455 || __get_user(ss.ss_sp, &uss->ss_sp)
456 || __get_user(ss.ss_size, &uss->ss_size)
457 || __get_user(ss.ss_flags, &uss->ss_flags))
458 goto out;
459 unlock_user_struct(uss, uss_addr, 0);
461 ret = -TARGET_EPERM;
462 if (on_sig_stack(sp))
463 goto out;
465 ret = -TARGET_EINVAL;
466 if (ss.ss_flags != TARGET_SS_DISABLE
467 && ss.ss_flags != TARGET_SS_ONSTACK
468 && ss.ss_flags != 0)
469 goto out;
471 if (ss.ss_flags == TARGET_SS_DISABLE) {
472 ss.ss_size = 0;
473 ss.ss_sp = 0;
474 } else {
475 ret = -TARGET_ENOMEM;
476 if (ss.ss_size < MINSIGSTKSZ)
477 goto out;
480 target_sigaltstack_used.ss_sp = ss.ss_sp;
481 target_sigaltstack_used.ss_size = ss.ss_size;
484 if (uoss_addr) {
485 ret = -TARGET_EFAULT;
486 if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
487 goto out;
490 ret = 0;
491 out:
492 return ret;
495 /* do_sigaction() return host values and errnos */
496 int do_sigaction(int sig, const struct target_sigaction *act,
497 struct target_sigaction *oact)
499 struct target_sigaction *k;
500 struct sigaction act1;
501 int host_sig;
502 int ret = 0;
504 if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP)
505 return -EINVAL;
506 k = &sigact_table[sig - 1];
507 #if defined(DEBUG_SIGNAL)
508 fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
509 sig, (int)act, (int)oact);
510 #endif
511 if (oact) {
512 oact->_sa_handler = tswapl(k->_sa_handler);
513 oact->sa_flags = tswapl(k->sa_flags);
514 #if !defined(TARGET_MIPS)
515 oact->sa_restorer = tswapl(k->sa_restorer);
516 #endif
517 oact->sa_mask = k->sa_mask;
519 if (act) {
520 /* FIXME: This is not threadsafe. */
521 k->_sa_handler = tswapl(act->_sa_handler);
522 k->sa_flags = tswapl(act->sa_flags);
523 #if !defined(TARGET_MIPS)
524 k->sa_restorer = tswapl(act->sa_restorer);
525 #endif
526 k->sa_mask = act->sa_mask;
528 /* we update the host linux signal state */
529 host_sig = target_to_host_signal(sig);
530 if (host_sig != SIGSEGV && host_sig != SIGBUS) {
531 sigfillset(&act1.sa_mask);
532 act1.sa_flags = SA_SIGINFO;
533 if (k->sa_flags & TARGET_SA_RESTART)
534 act1.sa_flags |= SA_RESTART;
535 /* NOTE: it is important to update the host kernel signal
536 ignore state to avoid getting unexpected interrupted
537 syscalls */
538 if (k->_sa_handler == TARGET_SIG_IGN) {
539 act1.sa_sigaction = (void *)SIG_IGN;
540 } else if (k->_sa_handler == TARGET_SIG_DFL) {
541 act1.sa_sigaction = (void *)SIG_DFL;
542 } else {
543 act1.sa_sigaction = host_signal_handler;
545 ret = sigaction(host_sig, &act1, NULL);
548 return ret;
551 #ifndef offsetof
552 #define offsetof(type, field) ((size_t) &((type *)0)->field)
553 #endif
555 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
556 const target_siginfo_t *info)
558 tswap_siginfo(tinfo, info);
559 return 0;
562 static inline int current_exec_domain_sig(int sig)
564 return /* current->exec_domain && current->exec_domain->signal_invmap
565 && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
568 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
570 /* from the Linux kernel */
572 struct target_fpreg {
573 uint16_t significand[4];
574 uint16_t exponent;
577 struct target_fpxreg {
578 uint16_t significand[4];
579 uint16_t exponent;
580 uint16_t padding[3];
583 struct target_xmmreg {
584 abi_ulong element[4];
587 struct target_fpstate {
588 /* Regular FPU environment */
589 abi_ulong cw;
590 abi_ulong sw;
591 abi_ulong tag;
592 abi_ulong ipoff;
593 abi_ulong cssel;
594 abi_ulong dataoff;
595 abi_ulong datasel;
596 struct target_fpreg _st[8];
597 uint16_t status;
598 uint16_t magic; /* 0xffff = regular FPU data only */
600 /* FXSR FPU environment */
601 abi_ulong _fxsr_env[6]; /* FXSR FPU env is ignored */
602 abi_ulong mxcsr;
603 abi_ulong reserved;
604 struct target_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
605 struct target_xmmreg _xmm[8];
606 abi_ulong padding[56];
609 #define X86_FXSR_MAGIC 0x0000
611 struct target_sigcontext {
612 uint16_t gs, __gsh;
613 uint16_t fs, __fsh;
614 uint16_t es, __esh;
615 uint16_t ds, __dsh;
616 abi_ulong edi;
617 abi_ulong esi;
618 abi_ulong ebp;
619 abi_ulong esp;
620 abi_ulong ebx;
621 abi_ulong edx;
622 abi_ulong ecx;
623 abi_ulong eax;
624 abi_ulong trapno;
625 abi_ulong err;
626 abi_ulong eip;
627 uint16_t cs, __csh;
628 abi_ulong eflags;
629 abi_ulong esp_at_signal;
630 uint16_t ss, __ssh;
631 abi_ulong fpstate; /* pointer */
632 abi_ulong oldmask;
633 abi_ulong cr2;
636 struct target_ucontext {
637 abi_ulong tuc_flags;
638 abi_ulong tuc_link;
639 target_stack_t tuc_stack;
640 struct target_sigcontext tuc_mcontext;
641 target_sigset_t tuc_sigmask; /* mask last for extensibility */
644 struct sigframe
646 abi_ulong pretcode;
647 int sig;
648 struct target_sigcontext sc;
649 struct target_fpstate fpstate;
650 abi_ulong extramask[TARGET_NSIG_WORDS-1];
651 char retcode[8];
654 struct rt_sigframe
656 abi_ulong pretcode;
657 int sig;
658 abi_ulong pinfo;
659 abi_ulong puc;
660 struct target_siginfo info;
661 struct target_ucontext uc;
662 struct target_fpstate fpstate;
663 char retcode[8];
667 * Set up a signal frame.
670 /* XXX: save x87 state */
671 static int
672 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
673 CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
675 int err = 0;
676 uint16_t magic;
678 /* already locked in setup_frame() */
679 err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
680 err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
681 err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
682 err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
683 err |= __put_user(env->regs[R_EDI], &sc->edi);
684 err |= __put_user(env->regs[R_ESI], &sc->esi);
685 err |= __put_user(env->regs[R_EBP], &sc->ebp);
686 err |= __put_user(env->regs[R_ESP], &sc->esp);
687 err |= __put_user(env->regs[R_EBX], &sc->ebx);
688 err |= __put_user(env->regs[R_EDX], &sc->edx);
689 err |= __put_user(env->regs[R_ECX], &sc->ecx);
690 err |= __put_user(env->regs[R_EAX], &sc->eax);
691 err |= __put_user(env->exception_index, &sc->trapno);
692 err |= __put_user(env->error_code, &sc->err);
693 err |= __put_user(env->eip, &sc->eip);
694 err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
695 err |= __put_user(env->eflags, &sc->eflags);
696 err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
697 err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
699 cpu_x86_fsave(env, fpstate_addr, 1);
700 fpstate->status = fpstate->sw;
701 magic = 0xffff;
702 err |= __put_user(magic, &fpstate->magic);
703 err |= __put_user(fpstate_addr, &sc->fpstate);
705 /* non-iBCS2 extensions.. */
706 err |= __put_user(mask, &sc->oldmask);
707 err |= __put_user(env->cr[2], &sc->cr2);
708 return err;
712 * Determine which stack to use..
715 static inline abi_ulong
716 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
718 unsigned long esp;
720 /* Default to using normal stack */
721 esp = env->regs[R_ESP];
722 /* This is the X/Open sanctioned signal stack switching. */
723 if (ka->sa_flags & TARGET_SA_ONSTACK) {
724 if (sas_ss_flags(esp) == 0)
725 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
728 /* This is the legacy signal stack switching. */
729 else
730 if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
731 !(ka->sa_flags & TARGET_SA_RESTORER) &&
732 ka->sa_restorer) {
733 esp = (unsigned long) ka->sa_restorer;
735 return (esp - frame_size) & -8ul;
738 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
739 static void setup_frame(int sig, struct target_sigaction *ka,
740 target_sigset_t *set, CPUX86State *env)
742 abi_ulong frame_addr;
743 struct sigframe *frame;
744 int i, err = 0;
746 frame_addr = get_sigframe(ka, env, sizeof(*frame));
748 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
749 goto give_sigsegv;
751 err |= __put_user(current_exec_domain_sig(sig),
752 &frame->sig);
753 if (err)
754 goto give_sigsegv;
756 setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
757 frame_addr + offsetof(struct sigframe, fpstate));
758 if (err)
759 goto give_sigsegv;
761 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
762 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
763 goto give_sigsegv;
766 /* Set up to return from userspace. If provided, use a stub
767 already in userspace. */
768 if (ka->sa_flags & TARGET_SA_RESTORER) {
769 err |= __put_user(ka->sa_restorer, &frame->pretcode);
770 } else {
771 uint16_t val16;
772 abi_ulong retcode_addr;
773 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
774 err |= __put_user(retcode_addr, &frame->pretcode);
775 /* This is popl %eax ; movl $,%eax ; int $0x80 */
776 val16 = 0xb858;
777 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
778 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
779 val16 = 0x80cd;
780 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
783 if (err)
784 goto give_sigsegv;
786 /* Set up registers for signal handler */
787 env->regs[R_ESP] = frame_addr;
788 env->eip = ka->_sa_handler;
790 cpu_x86_load_seg(env, R_DS, __USER_DS);
791 cpu_x86_load_seg(env, R_ES, __USER_DS);
792 cpu_x86_load_seg(env, R_SS, __USER_DS);
793 cpu_x86_load_seg(env, R_CS, __USER_CS);
794 env->eflags &= ~TF_MASK;
796 unlock_user_struct(frame, frame_addr, 1);
798 return;
800 give_sigsegv:
801 unlock_user_struct(frame, frame_addr, 1);
802 if (sig == TARGET_SIGSEGV)
803 ka->_sa_handler = TARGET_SIG_DFL;
804 force_sig(TARGET_SIGSEGV /* , current */);
807 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
808 static void setup_rt_frame(int sig, struct target_sigaction *ka,
809 target_siginfo_t *info,
810 target_sigset_t *set, CPUX86State *env)
812 abi_ulong frame_addr, addr;
813 struct rt_sigframe *frame;
814 int i, err = 0;
816 frame_addr = get_sigframe(ka, env, sizeof(*frame));
818 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
819 goto give_sigsegv;
821 err |= __put_user(current_exec_domain_sig(sig),
822 &frame->sig);
823 addr = frame_addr + offsetof(struct rt_sigframe, info);
824 err |= __put_user(addr, &frame->pinfo);
825 addr = frame_addr + offsetof(struct rt_sigframe, uc);
826 err |= __put_user(addr, &frame->puc);
827 err |= copy_siginfo_to_user(&frame->info, info);
828 if (err)
829 goto give_sigsegv;
831 /* Create the ucontext. */
832 err |= __put_user(0, &frame->uc.tuc_flags);
833 err |= __put_user(0, &frame->uc.tuc_link);
834 err |= __put_user(target_sigaltstack_used.ss_sp,
835 &frame->uc.tuc_stack.ss_sp);
836 err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
837 &frame->uc.tuc_stack.ss_flags);
838 err |= __put_user(target_sigaltstack_used.ss_size,
839 &frame->uc.tuc_stack.ss_size);
840 err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
841 env, set->sig[0],
842 frame_addr + offsetof(struct rt_sigframe, fpstate));
843 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
844 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
845 goto give_sigsegv;
848 /* Set up to return from userspace. If provided, use a stub
849 already in userspace. */
850 if (ka->sa_flags & TARGET_SA_RESTORER) {
851 err |= __put_user(ka->sa_restorer, &frame->pretcode);
852 } else {
853 uint16_t val16;
854 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
855 err |= __put_user(addr, &frame->pretcode);
856 /* This is movl $,%eax ; int $0x80 */
857 err |= __put_user(0xb8, (char *)(frame->retcode+0));
858 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
859 val16 = 0x80cd;
860 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
863 if (err)
864 goto give_sigsegv;
866 /* Set up registers for signal handler */
867 env->regs[R_ESP] = frame_addr;
868 env->eip = ka->_sa_handler;
870 cpu_x86_load_seg(env, R_DS, __USER_DS);
871 cpu_x86_load_seg(env, R_ES, __USER_DS);
872 cpu_x86_load_seg(env, R_SS, __USER_DS);
873 cpu_x86_load_seg(env, R_CS, __USER_CS);
874 env->eflags &= ~TF_MASK;
876 unlock_user_struct(frame, frame_addr, 1);
878 return;
880 give_sigsegv:
881 unlock_user_struct(frame, frame_addr, 1);
882 if (sig == TARGET_SIGSEGV)
883 ka->_sa_handler = TARGET_SIG_DFL;
884 force_sig(TARGET_SIGSEGV /* , current */);
887 static int
888 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
890 unsigned int err = 0;
891 abi_ulong fpstate_addr;
892 unsigned int tmpflags;
894 cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
895 cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
896 cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
897 cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
899 env->regs[R_EDI] = tswapl(sc->edi);
900 env->regs[R_ESI] = tswapl(sc->esi);
901 env->regs[R_EBP] = tswapl(sc->ebp);
902 env->regs[R_ESP] = tswapl(sc->esp);
903 env->regs[R_EBX] = tswapl(sc->ebx);
904 env->regs[R_EDX] = tswapl(sc->edx);
905 env->regs[R_ECX] = tswapl(sc->ecx);
906 env->eip = tswapl(sc->eip);
908 cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
909 cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
911 tmpflags = tswapl(sc->eflags);
912 env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
913 // regs->orig_eax = -1; /* disable syscall checks */
915 fpstate_addr = tswapl(sc->fpstate);
916 if (fpstate_addr != 0) {
917 if (!access_ok(VERIFY_READ, fpstate_addr,
918 sizeof(struct target_fpstate)))
919 goto badframe;
920 cpu_x86_frstor(env, fpstate_addr, 1);
923 *peax = tswapl(sc->eax);
924 return err;
925 badframe:
926 return 1;
929 long do_sigreturn(CPUX86State *env)
931 struct sigframe *frame;
932 abi_ulong frame_addr = env->regs[R_ESP] - 8;
933 target_sigset_t target_set;
934 sigset_t set;
935 int eax, i;
937 #if defined(DEBUG_SIGNAL)
938 fprintf(stderr, "do_sigreturn\n");
939 #endif
940 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
941 goto badframe;
942 /* set blocked signals */
943 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
944 goto badframe;
945 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
946 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
947 goto badframe;
950 target_to_host_sigset_internal(&set, &target_set);
951 sigprocmask(SIG_SETMASK, &set, NULL);
953 /* restore registers */
954 if (restore_sigcontext(env, &frame->sc, &eax))
955 goto badframe;
956 unlock_user_struct(frame, frame_addr, 0);
957 return eax;
959 badframe:
960 unlock_user_struct(frame, frame_addr, 0);
961 force_sig(TARGET_SIGSEGV);
962 return 0;
965 long do_rt_sigreturn(CPUX86State *env)
967 abi_ulong frame_addr;
968 struct rt_sigframe *frame;
969 sigset_t set;
970 int eax;
972 frame_addr = env->regs[R_ESP] - 4;
973 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
974 goto badframe;
975 target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
976 sigprocmask(SIG_SETMASK, &set, NULL);
978 if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
979 goto badframe;
981 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
982 get_sp_from_cpustate(env)) == -EFAULT)
983 goto badframe;
985 unlock_user_struct(frame, frame_addr, 0);
986 return eax;
988 badframe:
989 unlock_user_struct(frame, frame_addr, 0);
990 force_sig(TARGET_SIGSEGV);
991 return 0;
994 #elif defined(TARGET_ARM)
996 struct target_sigcontext {
997 abi_ulong trap_no;
998 abi_ulong error_code;
999 abi_ulong oldmask;
1000 abi_ulong arm_r0;
1001 abi_ulong arm_r1;
1002 abi_ulong arm_r2;
1003 abi_ulong arm_r3;
1004 abi_ulong arm_r4;
1005 abi_ulong arm_r5;
1006 abi_ulong arm_r6;
1007 abi_ulong arm_r7;
1008 abi_ulong arm_r8;
1009 abi_ulong arm_r9;
1010 abi_ulong arm_r10;
1011 abi_ulong arm_fp;
1012 abi_ulong arm_ip;
1013 abi_ulong arm_sp;
1014 abi_ulong arm_lr;
1015 abi_ulong arm_pc;
1016 abi_ulong arm_cpsr;
1017 abi_ulong fault_address;
1020 struct target_ucontext_v1 {
1021 abi_ulong tuc_flags;
1022 abi_ulong tuc_link;
1023 target_stack_t tuc_stack;
1024 struct target_sigcontext tuc_mcontext;
1025 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1028 struct target_ucontext_v2 {
1029 abi_ulong tuc_flags;
1030 abi_ulong tuc_link;
1031 target_stack_t tuc_stack;
1032 struct target_sigcontext tuc_mcontext;
1033 target_sigset_t tuc_sigmask; /* mask last for extensibility */
1034 char __unused[128 - sizeof(sigset_t)];
1035 abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1038 struct sigframe_v1
1040 struct target_sigcontext sc;
1041 abi_ulong extramask[TARGET_NSIG_WORDS-1];
1042 abi_ulong retcode;
1045 struct sigframe_v2
1047 struct target_ucontext_v2 uc;
1048 abi_ulong retcode;
1051 struct rt_sigframe_v1
1053 abi_ulong pinfo;
1054 abi_ulong puc;
1055 struct target_siginfo info;
1056 struct target_ucontext_v1 uc;
1057 abi_ulong retcode;
1060 struct rt_sigframe_v2
1062 struct target_siginfo info;
1063 struct target_ucontext_v2 uc;
1064 abi_ulong retcode;
1067 #define TARGET_CONFIG_CPU_32 1
1070 * For ARM syscalls, we encode the syscall number into the instruction.
1072 #define SWI_SYS_SIGRETURN (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1073 #define SWI_SYS_RT_SIGRETURN (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1076 * For Thumb syscalls, we pass the syscall number via r7. We therefore
1077 * need two 16-bit instructions.
1079 #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1080 #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1082 static const abi_ulong retcodes[4] = {
1083 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
1084 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
1088 #define __get_user_error(x,p,e) __get_user(x, p)
1090 static inline int valid_user_regs(CPUState *regs)
1092 return 1;
1095 static void
1096 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1097 CPUState *env, abi_ulong mask)
1099 __put_user(env->regs[0], &sc->arm_r0);
1100 __put_user(env->regs[1], &sc->arm_r1);
1101 __put_user(env->regs[2], &sc->arm_r2);
1102 __put_user(env->regs[3], &sc->arm_r3);
1103 __put_user(env->regs[4], &sc->arm_r4);
1104 __put_user(env->regs[5], &sc->arm_r5);
1105 __put_user(env->regs[6], &sc->arm_r6);
1106 __put_user(env->regs[7], &sc->arm_r7);
1107 __put_user(env->regs[8], &sc->arm_r8);
1108 __put_user(env->regs[9], &sc->arm_r9);
1109 __put_user(env->regs[10], &sc->arm_r10);
1110 __put_user(env->regs[11], &sc->arm_fp);
1111 __put_user(env->regs[12], &sc->arm_ip);
1112 __put_user(env->regs[13], &sc->arm_sp);
1113 __put_user(env->regs[14], &sc->arm_lr);
1114 __put_user(env->regs[15], &sc->arm_pc);
1115 #ifdef TARGET_CONFIG_CPU_32
1116 __put_user(cpsr_read(env), &sc->arm_cpsr);
1117 #endif
1119 __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1120 __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1121 __put_user(/* current->thread.address */ 0, &sc->fault_address);
1122 __put_user(mask, &sc->oldmask);
1125 static inline abi_ulong
1126 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1128 unsigned long sp = regs->regs[13];
1131 * This is the X/Open sanctioned signal stack switching.
1133 if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1134 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1136 * ATPCS B01 mandates 8-byte alignment
1138 return (sp - framesize) & ~7;
1141 static int
1142 setup_return(CPUState *env, struct target_sigaction *ka,
1143 abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1145 abi_ulong handler = ka->_sa_handler;
1146 abi_ulong retcode;
1147 int thumb = handler & 1;
1149 if (ka->sa_flags & TARGET_SA_RESTORER) {
1150 retcode = ka->sa_restorer;
1151 } else {
1152 unsigned int idx = thumb;
1154 if (ka->sa_flags & TARGET_SA_SIGINFO)
1155 idx += 2;
1157 if (__put_user(retcodes[idx], rc))
1158 return 1;
1159 #if 0
1160 flush_icache_range((abi_ulong)rc,
1161 (abi_ulong)(rc + 1));
1162 #endif
1163 retcode = rc_addr + thumb;
1166 env->regs[0] = usig;
1167 env->regs[13] = frame_addr;
1168 env->regs[14] = retcode;
1169 env->regs[15] = handler & (thumb ? ~1 : ~3);
1170 env->thumb = thumb;
1172 #if 0
1173 #ifdef TARGET_CONFIG_CPU_32
1174 env->cpsr = cpsr;
1175 #endif
1176 #endif
1178 return 0;
1181 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1182 target_sigset_t *set, CPUState *env)
1184 struct target_sigaltstack stack;
1185 int i;
1187 /* Clear all the bits of the ucontext we don't use. */
1188 memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1190 memset(&stack, 0, sizeof(stack));
1191 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1192 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1193 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1194 memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1196 setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1197 /* FIXME: Save coprocessor signal frame. */
1198 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1199 __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1203 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1204 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1205 target_sigset_t *set, CPUState *regs)
1207 struct sigframe_v1 *frame;
1208 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1209 int i;
1211 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1212 return;
1214 setup_sigcontext(&frame->sc, regs, set->sig[0]);
1216 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1217 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1218 goto end;
1221 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1222 frame_addr + offsetof(struct sigframe_v1, retcode));
1224 end:
1225 unlock_user_struct(frame, frame_addr, 1);
1228 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1229 target_sigset_t *set, CPUState *regs)
1231 struct sigframe_v2 *frame;
1232 abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1234 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1235 return;
1237 setup_sigframe_v2(&frame->uc, set, regs);
1239 setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1240 frame_addr + offsetof(struct sigframe_v2, retcode));
1242 unlock_user_struct(frame, frame_addr, 1);
1245 static void setup_frame(int usig, struct target_sigaction *ka,
1246 target_sigset_t *set, CPUState *regs)
1248 if (get_osversion() >= 0x020612) {
1249 setup_frame_v2(usig, ka, set, regs);
1250 } else {
1251 setup_frame_v1(usig, ka, set, regs);
1255 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1256 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1257 target_siginfo_t *info,
1258 target_sigset_t *set, CPUState *env)
1260 struct rt_sigframe_v1 *frame;
1261 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1262 struct target_sigaltstack stack;
1263 int i;
1264 abi_ulong info_addr, uc_addr;
1266 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1267 return /* 1 */;
1269 info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1270 __put_user(info_addr, &frame->pinfo);
1271 uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1272 __put_user(uc_addr, &frame->puc);
1273 copy_siginfo_to_user(&frame->info, info);
1275 /* Clear all the bits of the ucontext we don't use. */
1276 memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1278 memset(&stack, 0, sizeof(stack));
1279 __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1280 __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1281 __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1282 memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1284 setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1285 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1286 if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1287 goto end;
1290 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1291 frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1293 env->regs[1] = info_addr;
1294 env->regs[2] = uc_addr;
1296 end:
1297 unlock_user_struct(frame, frame_addr, 1);
1300 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1301 target_siginfo_t *info,
1302 target_sigset_t *set, CPUState *env)
1304 struct rt_sigframe_v2 *frame;
1305 abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1306 abi_ulong info_addr, uc_addr;
1308 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1309 return /* 1 */;
1311 info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1312 uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1313 copy_siginfo_to_user(&frame->info, info);
1315 setup_sigframe_v2(&frame->uc, set, env);
1317 setup_return(env, ka, &frame->retcode, frame_addr, usig,
1318 frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1320 env->regs[1] = info_addr;
1321 env->regs[2] = uc_addr;
1323 unlock_user_struct(frame, frame_addr, 1);
1326 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1327 target_siginfo_t *info,
1328 target_sigset_t *set, CPUState *env)
1330 if (get_osversion() >= 0x020612) {
1331 setup_rt_frame_v2(usig, ka, info, set, env);
1332 } else {
1333 setup_rt_frame_v1(usig, ka, info, set, env);
1337 static int
1338 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1340 int err = 0;
1341 uint32_t cpsr;
1343 __get_user_error(env->regs[0], &sc->arm_r0, err);
1344 __get_user_error(env->regs[1], &sc->arm_r1, err);
1345 __get_user_error(env->regs[2], &sc->arm_r2, err);
1346 __get_user_error(env->regs[3], &sc->arm_r3, err);
1347 __get_user_error(env->regs[4], &sc->arm_r4, err);
1348 __get_user_error(env->regs[5], &sc->arm_r5, err);
1349 __get_user_error(env->regs[6], &sc->arm_r6, err);
1350 __get_user_error(env->regs[7], &sc->arm_r7, err);
1351 __get_user_error(env->regs[8], &sc->arm_r8, err);
1352 __get_user_error(env->regs[9], &sc->arm_r9, err);
1353 __get_user_error(env->regs[10], &sc->arm_r10, err);
1354 __get_user_error(env->regs[11], &sc->arm_fp, err);
1355 __get_user_error(env->regs[12], &sc->arm_ip, err);
1356 __get_user_error(env->regs[13], &sc->arm_sp, err);
1357 __get_user_error(env->regs[14], &sc->arm_lr, err);
1358 __get_user_error(env->regs[15], &sc->arm_pc, err);
1359 #ifdef TARGET_CONFIG_CPU_32
1360 __get_user_error(cpsr, &sc->arm_cpsr, err);
1361 cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1362 #endif
1364 err |= !valid_user_regs(env);
1366 return err;
1369 long do_sigreturn_v1(CPUState *env)
1371 abi_ulong frame_addr;
1372 struct sigframe_v1 *frame;
1373 target_sigset_t set;
1374 sigset_t host_set;
1375 int i;
1378 * Since we stacked the signal on a 64-bit boundary,
1379 * then 'sp' should be word aligned here. If it's
1380 * not, then the user is trying to mess with us.
1382 if (env->regs[13] & 7)
1383 goto badframe;
1385 frame_addr = env->regs[13];
1386 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1387 goto badframe;
1389 if (__get_user(set.sig[0], &frame->sc.oldmask))
1390 goto badframe;
1391 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1392 if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1393 goto badframe;
1396 target_to_host_sigset_internal(&host_set, &set);
1397 sigprocmask(SIG_SETMASK, &host_set, NULL);
1399 if (restore_sigcontext(env, &frame->sc))
1400 goto badframe;
1402 #if 0
1403 /* Send SIGTRAP if we're single-stepping */
1404 if (ptrace_cancel_bpt(current))
1405 send_sig(SIGTRAP, current, 1);
1406 #endif
1407 unlock_user_struct(frame, frame_addr, 0);
1408 return env->regs[0];
1410 badframe:
1411 unlock_user_struct(frame, frame_addr, 0);
1412 force_sig(SIGSEGV /* , current */);
1413 return 0;
1416 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1417 struct target_ucontext_v2 *uc)
1419 sigset_t host_set;
1421 target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1422 sigprocmask(SIG_SETMASK, &host_set, NULL);
1424 if (restore_sigcontext(env, &uc->tuc_mcontext))
1425 return 1;
1427 if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1428 return 1;
1430 #if 0
1431 /* Send SIGTRAP if we're single-stepping */
1432 if (ptrace_cancel_bpt(current))
1433 send_sig(SIGTRAP, current, 1);
1434 #endif
1436 return 0;
1439 long do_sigreturn_v2(CPUState *env)
1441 abi_ulong frame_addr;
1442 struct sigframe_v2 *frame;
1445 * Since we stacked the signal on a 64-bit boundary,
1446 * then 'sp' should be word aligned here. If it's
1447 * not, then the user is trying to mess with us.
1449 if (env->regs[13] & 7)
1450 goto badframe;
1452 frame_addr = env->regs[13];
1453 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1454 goto badframe;
1456 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1457 goto badframe;
1459 unlock_user_struct(frame, frame_addr, 0);
1460 return env->regs[0];
1462 badframe:
1463 unlock_user_struct(frame, frame_addr, 0);
1464 force_sig(SIGSEGV /* , current */);
1465 return 0;
1468 long do_sigreturn(CPUState *env)
1470 if (get_osversion() >= 0x020612) {
1471 return do_sigreturn_v2(env);
1472 } else {
1473 return do_sigreturn_v1(env);
1477 long do_rt_sigreturn_v1(CPUState *env)
1479 abi_ulong frame_addr;
1480 struct rt_sigframe_v1 *frame;
1481 sigset_t host_set;
1484 * Since we stacked the signal on a 64-bit boundary,
1485 * then 'sp' should be word aligned here. If it's
1486 * not, then the user is trying to mess with us.
1488 if (env->regs[13] & 7)
1489 goto badframe;
1491 frame_addr = env->regs[13];
1492 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1493 goto badframe;
1495 target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1496 sigprocmask(SIG_SETMASK, &host_set, NULL);
1498 if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1499 goto badframe;
1501 if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1502 goto badframe;
1504 #if 0
1505 /* Send SIGTRAP if we're single-stepping */
1506 if (ptrace_cancel_bpt(current))
1507 send_sig(SIGTRAP, current, 1);
1508 #endif
1509 unlock_user_struct(frame, frame_addr, 0);
1510 return env->regs[0];
1512 badframe:
1513 unlock_user_struct(frame, frame_addr, 0);
1514 force_sig(SIGSEGV /* , current */);
1515 return 0;
1518 long do_rt_sigreturn_v2(CPUState *env)
1520 abi_ulong frame_addr;
1521 struct rt_sigframe_v2 *frame;
1524 * Since we stacked the signal on a 64-bit boundary,
1525 * then 'sp' should be word aligned here. If it's
1526 * not, then the user is trying to mess with us.
1528 if (env->regs[13] & 7)
1529 goto badframe;
1531 frame_addr = env->regs[13];
1532 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1533 goto badframe;
1535 if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1536 goto badframe;
1538 unlock_user_struct(frame, frame_addr, 0);
1539 return env->regs[0];
1541 badframe:
1542 unlock_user_struct(frame, frame_addr, 0);
1543 force_sig(SIGSEGV /* , current */);
1544 return 0;
1547 long do_rt_sigreturn(CPUState *env)
1549 if (get_osversion() >= 0x020612) {
1550 return do_rt_sigreturn_v2(env);
1551 } else {
1552 return do_rt_sigreturn_v1(env);
1556 #elif defined(TARGET_SPARC)
1558 #define __SUNOS_MAXWIN 31
1560 /* This is what SunOS does, so shall I. */
1561 struct target_sigcontext {
1562 abi_ulong sigc_onstack; /* state to restore */
1564 abi_ulong sigc_mask; /* sigmask to restore */
1565 abi_ulong sigc_sp; /* stack pointer */
1566 abi_ulong sigc_pc; /* program counter */
1567 abi_ulong sigc_npc; /* next program counter */
1568 abi_ulong sigc_psr; /* for condition codes etc */
1569 abi_ulong sigc_g1; /* User uses these two registers */
1570 abi_ulong sigc_o0; /* within the trampoline code. */
1572 /* Now comes information regarding the users window set
1573 * at the time of the signal.
1575 abi_ulong sigc_oswins; /* outstanding windows */
1577 /* stack ptrs for each regwin buf */
1578 char *sigc_spbuf[__SUNOS_MAXWIN];
1580 /* Windows to restore after signal */
1581 struct {
1582 abi_ulong locals[8];
1583 abi_ulong ins[8];
1584 } sigc_wbuf[__SUNOS_MAXWIN];
1586 /* A Sparc stack frame */
1587 struct sparc_stackf {
1588 abi_ulong locals[8];
1589 abi_ulong ins[6];
1590 struct sparc_stackf *fp;
1591 abi_ulong callers_pc;
1592 char *structptr;
1593 abi_ulong xargs[6];
1594 abi_ulong xxargs[1];
1597 typedef struct {
1598 struct {
1599 abi_ulong psr;
1600 abi_ulong pc;
1601 abi_ulong npc;
1602 abi_ulong y;
1603 abi_ulong u_regs[16]; /* globals and ins */
1604 } si_regs;
1605 int si_mask;
1606 } __siginfo_t;
1608 typedef struct {
1609 unsigned long si_float_regs [32];
1610 unsigned long si_fsr;
1611 unsigned long si_fpqdepth;
1612 struct {
1613 unsigned long *insn_addr;
1614 unsigned long insn;
1615 } si_fpqueue [16];
1616 } qemu_siginfo_fpu_t;
1619 struct target_signal_frame {
1620 struct sparc_stackf ss;
1621 __siginfo_t info;
1622 abi_ulong fpu_save;
1623 abi_ulong insns[2] __attribute__ ((aligned (8)));
1624 abi_ulong extramask[TARGET_NSIG_WORDS - 1];
1625 abi_ulong extra_size; /* Should be 0 */
1626 qemu_siginfo_fpu_t fpu_state;
1628 struct target_rt_signal_frame {
1629 struct sparc_stackf ss;
1630 siginfo_t info;
1631 abi_ulong regs[20];
1632 sigset_t mask;
1633 abi_ulong fpu_save;
1634 unsigned int insns[2];
1635 stack_t stack;
1636 unsigned int extra_size; /* Should be 0 */
1637 qemu_siginfo_fpu_t fpu_state;
1640 #define UREG_O0 16
1641 #define UREG_O6 22
1642 #define UREG_I0 0
1643 #define UREG_I1 1
1644 #define UREG_I2 2
1645 #define UREG_I3 3
1646 #define UREG_I4 4
1647 #define UREG_I5 5
1648 #define UREG_I6 6
1649 #define UREG_I7 7
1650 #define UREG_L0 8
1651 #define UREG_FP UREG_I6
1652 #define UREG_SP UREG_O6
1654 static inline abi_ulong get_sigframe(struct target_sigaction *sa,
1655 CPUState *env, unsigned long framesize)
1657 abi_ulong sp;
1659 sp = env->regwptr[UREG_FP];
1661 /* This is the X/Open sanctioned signal stack switching. */
1662 if (sa->sa_flags & TARGET_SA_ONSTACK) {
1663 if (!on_sig_stack(sp)
1664 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1665 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1667 return sp - framesize;
1670 static int
1671 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1673 int err = 0, i;
1675 err |= __put_user(env->psr, &si->si_regs.psr);
1676 err |= __put_user(env->pc, &si->si_regs.pc);
1677 err |= __put_user(env->npc, &si->si_regs.npc);
1678 err |= __put_user(env->y, &si->si_regs.y);
1679 for (i=0; i < 8; i++) {
1680 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1682 for (i=0; i < 8; i++) {
1683 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1685 err |= __put_user(mask, &si->si_mask);
1686 return err;
1689 #if 0
1690 static int
1691 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1692 CPUState *env, unsigned long mask)
1694 int err = 0;
1696 err |= __put_user(mask, &sc->sigc_mask);
1697 err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1698 err |= __put_user(env->pc, &sc->sigc_pc);
1699 err |= __put_user(env->npc, &sc->sigc_npc);
1700 err |= __put_user(env->psr, &sc->sigc_psr);
1701 err |= __put_user(env->gregs[1], &sc->sigc_g1);
1702 err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1704 return err;
1706 #endif
1707 #define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
1709 static void setup_frame(int sig, struct target_sigaction *ka,
1710 target_sigset_t *set, CPUState *env)
1712 abi_ulong sf_addr;
1713 struct target_signal_frame *sf;
1714 int sigframe_size, err, i;
1716 /* 1. Make sure everything is clean */
1717 //synchronize_user_stack();
1719 sigframe_size = NF_ALIGNEDSZ;
1720 sf_addr = get_sigframe(ka, env, sigframe_size);
1722 sf = lock_user(VERIFY_WRITE, sf_addr,
1723 sizeof(struct target_signal_frame), 0);
1724 if (!sf)
1725 goto sigsegv;
1727 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1728 #if 0
1729 if (invalid_frame_pointer(sf, sigframe_size))
1730 goto sigill_and_return;
1731 #endif
1732 /* 2. Save the current process state */
1733 err = setup___siginfo(&sf->info, env, set->sig[0]);
1734 err |= __put_user(0, &sf->extra_size);
1736 //err |= save_fpu_state(regs, &sf->fpu_state);
1737 //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1739 err |= __put_user(set->sig[0], &sf->info.si_mask);
1740 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1741 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1744 for (i = 0; i < 8; i++) {
1745 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1747 for (i = 0; i < 8; i++) {
1748 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1750 if (err)
1751 goto sigsegv;
1753 /* 3. signal handler back-trampoline and parameters */
1754 env->regwptr[UREG_FP] = sf_addr;
1755 env->regwptr[UREG_I0] = sig;
1756 env->regwptr[UREG_I1] = sf_addr +
1757 offsetof(struct target_signal_frame, info);
1758 env->regwptr[UREG_I2] = sf_addr +
1759 offsetof(struct target_signal_frame, info);
1761 /* 4. signal handler */
1762 env->pc = ka->_sa_handler;
1763 env->npc = (env->pc + 4);
1764 /* 5. return to kernel instructions */
1765 if (ka->sa_restorer)
1766 env->regwptr[UREG_I7] = ka->sa_restorer;
1767 else {
1768 uint32_t val32;
1770 env->regwptr[UREG_I7] = sf_addr +
1771 offsetof(struct target_signal_frame, insns) - 2 * 4;
1773 /* mov __NR_sigreturn, %g1 */
1774 val32 = 0x821020d8;
1775 err |= __put_user(val32, &sf->insns[0]);
1777 /* t 0x10 */
1778 val32 = 0x91d02010;
1779 err |= __put_user(val32, &sf->insns[1]);
1780 if (err)
1781 goto sigsegv;
1783 /* Flush instruction space. */
1784 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1785 // tb_flush(env);
1787 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1788 return;
1789 #if 0
1790 sigill_and_return:
1791 force_sig(TARGET_SIGILL);
1792 #endif
1793 sigsegv:
1794 //fprintf(stderr, "force_sig\n");
1795 unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1796 force_sig(TARGET_SIGSEGV);
1798 static inline int
1799 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1801 int err;
1802 #if 0
1803 #ifdef CONFIG_SMP
1804 if (current->flags & PF_USEDFPU)
1805 regs->psr &= ~PSR_EF;
1806 #else
1807 if (current == last_task_used_math) {
1808 last_task_used_math = 0;
1809 regs->psr &= ~PSR_EF;
1811 #endif
1812 current->used_math = 1;
1813 current->flags &= ~PF_USEDFPU;
1814 #endif
1815 #if 0
1816 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1817 return -EFAULT;
1818 #endif
1820 #if 0
1821 /* XXX: incorrect */
1822 err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1823 (sizeof(unsigned long) * 32));
1824 #endif
1825 err |= __get_user(env->fsr, &fpu->si_fsr);
1826 #if 0
1827 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1828 if (current->thread.fpqdepth != 0)
1829 err |= __copy_from_user(&current->thread.fpqueue[0],
1830 &fpu->si_fpqueue[0],
1831 ((sizeof(unsigned long) +
1832 (sizeof(unsigned long *)))*16));
1833 #endif
1834 return err;
1838 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1839 target_siginfo_t *info,
1840 target_sigset_t *set, CPUState *env)
1842 fprintf(stderr, "setup_rt_frame: not implemented\n");
1845 long do_sigreturn(CPUState *env)
1847 abi_ulong sf_addr;
1848 struct target_signal_frame *sf;
1849 uint32_t up_psr, pc, npc;
1850 target_sigset_t set;
1851 sigset_t host_set;
1852 abi_ulong fpu_save_addr;
1853 int err, i;
1855 sf_addr = env->regwptr[UREG_FP];
1856 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1857 goto segv_and_exit;
1858 #if 0
1859 fprintf(stderr, "sigreturn\n");
1860 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1861 #endif
1862 //cpu_dump_state(env, stderr, fprintf, 0);
1864 /* 1. Make sure we are not getting garbage from the user */
1866 if (sf_addr & 3)
1867 goto segv_and_exit;
1869 err = __get_user(pc, &sf->info.si_regs.pc);
1870 err |= __get_user(npc, &sf->info.si_regs.npc);
1872 if ((pc | npc) & 3)
1873 goto segv_and_exit;
1875 /* 2. Restore the state */
1876 err |= __get_user(up_psr, &sf->info.si_regs.psr);
1878 /* User can only change condition codes and FPU enabling in %psr. */
1879 env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1880 | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1882 env->pc = pc;
1883 env->npc = npc;
1884 err |= __get_user(env->y, &sf->info.si_regs.y);
1885 for (i=0; i < 8; i++) {
1886 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1888 for (i=0; i < 8; i++) {
1889 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1892 err |= __get_user(fpu_save_addr, &sf->fpu_save);
1894 //if (fpu_save)
1895 // err |= restore_fpu_state(env, fpu_save);
1897 /* This is pretty much atomic, no amount locking would prevent
1898 * the races which exist anyways.
1900 err |= __get_user(set.sig[0], &sf->info.si_mask);
1901 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1902 err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1905 target_to_host_sigset_internal(&host_set, &set);
1906 sigprocmask(SIG_SETMASK, &host_set, NULL);
1908 if (err)
1909 goto segv_and_exit;
1910 unlock_user_struct(sf, sf_addr, 0);
1911 return env->regwptr[0];
1913 segv_and_exit:
1914 unlock_user_struct(sf, sf_addr, 0);
1915 force_sig(TARGET_SIGSEGV);
1918 long do_rt_sigreturn(CPUState *env)
1920 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1921 return -TARGET_ENOSYS;
1924 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1925 #define MC_TSTATE 0
1926 #define MC_PC 1
1927 #define MC_NPC 2
1928 #define MC_Y 3
1929 #define MC_G1 4
1930 #define MC_G2 5
1931 #define MC_G3 6
1932 #define MC_G4 7
1933 #define MC_G5 8
1934 #define MC_G6 9
1935 #define MC_G7 10
1936 #define MC_O0 11
1937 #define MC_O1 12
1938 #define MC_O2 13
1939 #define MC_O3 14
1940 #define MC_O4 15
1941 #define MC_O5 16
1942 #define MC_O6 17
1943 #define MC_O7 18
1944 #define MC_NGREG 19
1946 typedef abi_ulong target_mc_greg_t;
1947 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1949 struct target_mc_fq {
1950 abi_ulong *mcfq_addr;
1951 uint32_t mcfq_insn;
1954 struct target_mc_fpu {
1955 union {
1956 uint32_t sregs[32];
1957 uint64_t dregs[32];
1958 //uint128_t qregs[16];
1959 } mcfpu_fregs;
1960 abi_ulong mcfpu_fsr;
1961 abi_ulong mcfpu_fprs;
1962 abi_ulong mcfpu_gsr;
1963 struct target_mc_fq *mcfpu_fq;
1964 unsigned char mcfpu_qcnt;
1965 unsigned char mcfpu_qentsz;
1966 unsigned char mcfpu_enab;
1968 typedef struct target_mc_fpu target_mc_fpu_t;
1970 typedef struct {
1971 target_mc_gregset_t mc_gregs;
1972 target_mc_greg_t mc_fp;
1973 target_mc_greg_t mc_i7;
1974 target_mc_fpu_t mc_fpregs;
1975 } target_mcontext_t;
1977 struct target_ucontext {
1978 struct target_ucontext *uc_link;
1979 abi_ulong uc_flags;
1980 target_sigset_t uc_sigmask;
1981 target_mcontext_t uc_mcontext;
1984 /* A V9 register window */
1985 struct target_reg_window {
1986 abi_ulong locals[8];
1987 abi_ulong ins[8];
1990 #define TARGET_STACK_BIAS 2047
1992 /* {set, get}context() needed for 64-bit SparcLinux userland. */
1993 void sparc64_set_context(CPUSPARCState *env)
1995 abi_ulong ucp_addr;
1996 struct target_ucontext *ucp;
1997 target_mc_gregset_t *grp;
1998 abi_ulong pc, npc, tstate;
1999 abi_ulong fp, i7, w_addr;
2000 unsigned char fenab;
2001 int err;
2002 unsigned int i;
2004 ucp_addr = env->regwptr[UREG_I0];
2005 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2006 goto do_sigsegv;
2007 grp = &ucp->uc_mcontext.mc_gregs;
2008 err = __get_user(pc, &((*grp)[MC_PC]));
2009 err |= __get_user(npc, &((*grp)[MC_NPC]));
2010 if (err || ((pc | npc) & 3))
2011 goto do_sigsegv;
2012 if (env->regwptr[UREG_I1]) {
2013 target_sigset_t target_set;
2014 sigset_t set;
2016 if (TARGET_NSIG_WORDS == 1) {
2017 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2018 goto do_sigsegv;
2019 } else {
2020 abi_ulong *src, *dst;
2021 src = ucp->uc_sigmask.sig;
2022 dst = target_set.sig;
2023 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2024 i++, dst++, src++)
2025 err |= __get_user(*dst, src);
2026 if (err)
2027 goto do_sigsegv;
2029 target_to_host_sigset_internal(&set, &target_set);
2030 sigprocmask(SIG_SETMASK, &set, NULL);
2032 env->pc = pc;
2033 env->npc = npc;
2034 err |= __get_user(env->y, &((*grp)[MC_Y]));
2035 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2036 env->asi = (tstate >> 24) & 0xff;
2037 PUT_CCR(env, tstate >> 32);
2038 PUT_CWP64(env, tstate & 0x1f);
2039 err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2040 err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2041 err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2042 err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2043 err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2044 err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2045 err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2046 err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2047 err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2048 err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2049 err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2050 err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2051 err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2052 err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2053 err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2055 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2056 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2058 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2059 if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2060 abi_ulong) != 0)
2061 goto do_sigsegv;
2062 if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2063 abi_ulong) != 0)
2064 goto do_sigsegv;
2065 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2066 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2068 uint32_t *src, *dst;
2069 src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2070 dst = env->fpr;
2071 /* XXX: check that the CPU storage is the same as user context */
2072 for (i = 0; i < 64; i++, dst++, src++)
2073 err |= __get_user(*dst, src);
2075 err |= __get_user(env->fsr,
2076 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2077 err |= __get_user(env->gsr,
2078 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2079 if (err)
2080 goto do_sigsegv;
2081 unlock_user_struct(ucp, ucp_addr, 0);
2082 return;
2083 do_sigsegv:
2084 unlock_user_struct(ucp, ucp_addr, 0);
2085 force_sig(SIGSEGV);
2088 void sparc64_get_context(CPUSPARCState *env)
2090 abi_ulong ucp_addr;
2091 struct target_ucontext *ucp;
2092 target_mc_gregset_t *grp;
2093 target_mcontext_t *mcp;
2094 abi_ulong fp, i7, w_addr;
2095 int err;
2096 unsigned int i;
2097 target_sigset_t target_set;
2098 sigset_t set;
2100 ucp_addr = env->regwptr[UREG_I0];
2101 if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2102 goto do_sigsegv;
2104 mcp = &ucp->uc_mcontext;
2105 grp = &mcp->mc_gregs;
2107 /* Skip over the trap instruction, first. */
2108 env->pc = env->npc;
2109 env->npc += 4;
2111 err = 0;
2113 sigprocmask(0, NULL, &set);
2114 host_to_target_sigset_internal(&target_set, &set);
2115 if (TARGET_NSIG_WORDS == 1) {
2116 err |= __put_user(target_set.sig[0],
2117 (abi_ulong *)&ucp->uc_sigmask);
2118 } else {
2119 abi_ulong *src, *dst;
2120 src = target_set.sig;
2121 dst = ucp->uc_sigmask.sig;
2122 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2123 i++, dst++, src++)
2124 err |= __put_user(*src, dst);
2125 if (err)
2126 goto do_sigsegv;
2129 /* XXX: tstate must be saved properly */
2130 // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2131 err |= __put_user(env->pc, &((*grp)[MC_PC]));
2132 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2133 err |= __put_user(env->y, &((*grp)[MC_Y]));
2134 err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2135 err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2136 err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2137 err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2138 err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2139 err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2140 err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2141 err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2142 err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2143 err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2144 err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2145 err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2146 err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2147 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2148 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2150 w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2151 fp = i7 = 0;
2152 if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
2153 abi_ulong) != 0)
2154 goto do_sigsegv;
2155 if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
2156 abi_ulong) != 0)
2157 goto do_sigsegv;
2158 err |= __put_user(fp, &(mcp->mc_fp));
2159 err |= __put_user(i7, &(mcp->mc_i7));
2162 uint32_t *src, *dst;
2163 src = env->fpr;
2164 dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2165 /* XXX: check that the CPU storage is the same as user context */
2166 for (i = 0; i < 64; i++, dst++, src++)
2167 err |= __put_user(*src, dst);
2169 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2170 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2171 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2173 if (err)
2174 goto do_sigsegv;
2175 unlock_user_struct(ucp, ucp_addr, 1);
2176 return;
2177 do_sigsegv:
2178 unlock_user_struct(ucp, ucp_addr, 1);
2179 force_sig(SIGSEGV);
2181 #endif
2182 #elif defined(TARGET_ABI_MIPSN64)
2184 # warning signal handling not implemented
2186 static void setup_frame(int sig, struct target_sigaction *ka,
2187 target_sigset_t *set, CPUState *env)
2189 fprintf(stderr, "setup_frame: not implemented\n");
2192 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2193 target_siginfo_t *info,
2194 target_sigset_t *set, CPUState *env)
2196 fprintf(stderr, "setup_rt_frame: not implemented\n");
2199 long do_sigreturn(CPUState *env)
2201 fprintf(stderr, "do_sigreturn: not implemented\n");
2202 return -TARGET_ENOSYS;
2205 long do_rt_sigreturn(CPUState *env)
2207 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2208 return -TARGET_ENOSYS;
2211 #elif defined(TARGET_ABI_MIPSN32)
2213 # warning signal handling not implemented
2215 static void setup_frame(int sig, struct target_sigaction *ka,
2216 target_sigset_t *set, CPUState *env)
2218 fprintf(stderr, "setup_frame: not implemented\n");
2221 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2222 target_siginfo_t *info,
2223 target_sigset_t *set, CPUState *env)
2225 fprintf(stderr, "setup_rt_frame: not implemented\n");
2228 long do_sigreturn(CPUState *env)
2230 fprintf(stderr, "do_sigreturn: not implemented\n");
2231 return -TARGET_ENOSYS;
2234 long do_rt_sigreturn(CPUState *env)
2236 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2237 return -TARGET_ENOSYS;
2240 #elif defined(TARGET_ABI_MIPSO32)
2242 struct target_sigcontext {
2243 uint32_t sc_regmask; /* Unused */
2244 uint32_t sc_status;
2245 uint64_t sc_pc;
2246 uint64_t sc_regs[32];
2247 uint64_t sc_fpregs[32];
2248 uint32_t sc_ownedfp; /* Unused */
2249 uint32_t sc_fpc_csr;
2250 uint32_t sc_fpc_eir; /* Unused */
2251 uint32_t sc_used_math;
2252 uint32_t sc_dsp; /* dsp status, was sc_ssflags */
2253 uint64_t sc_mdhi;
2254 uint64_t sc_mdlo;
2255 target_ulong sc_hi1; /* Was sc_cause */
2256 target_ulong sc_lo1; /* Was sc_badvaddr */
2257 target_ulong sc_hi2; /* Was sc_sigset[4] */
2258 target_ulong sc_lo2;
2259 target_ulong sc_hi3;
2260 target_ulong sc_lo3;
2263 struct sigframe {
2264 uint32_t sf_ass[4]; /* argument save space for o32 */
2265 uint32_t sf_code[2]; /* signal trampoline */
2266 struct target_sigcontext sf_sc;
2267 target_sigset_t sf_mask;
2270 /* Install trampoline to jump back from signal handler */
2271 static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall)
2273 int err;
2276 * Set up the return code ...
2278 * li v0, __NR__foo_sigreturn
2279 * syscall
2282 err = __put_user(0x24020000 + syscall, tramp + 0);
2283 err |= __put_user(0x0000000c , tramp + 1);
2284 /* flush_cache_sigtramp((unsigned long) tramp); */
2285 return err;
2288 static inline int
2289 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2291 int err = 0;
2293 err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2295 #define save_gp_reg(i) do { \
2296 err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2297 } while(0)
2298 __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2299 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2300 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2301 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2302 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2303 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2304 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2305 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2306 save_gp_reg(31);
2307 #undef save_gp_reg
2309 err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2310 err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2312 /* Not used yet, but might be useful if we ever have DSP suppport */
2313 #if 0
2314 if (cpu_has_dsp) {
2315 err |= __put_user(mfhi1(), &sc->sc_hi1);
2316 err |= __put_user(mflo1(), &sc->sc_lo1);
2317 err |= __put_user(mfhi2(), &sc->sc_hi2);
2318 err |= __put_user(mflo2(), &sc->sc_lo2);
2319 err |= __put_user(mfhi3(), &sc->sc_hi3);
2320 err |= __put_user(mflo3(), &sc->sc_lo3);
2321 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2323 /* same with 64 bit */
2324 #ifdef CONFIG_64BIT
2325 err |= __put_user(regs->hi, &sc->sc_hi[0]);
2326 err |= __put_user(regs->lo, &sc->sc_lo[0]);
2327 if (cpu_has_dsp) {
2328 err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2329 err |= __put_user(mflo1(), &sc->sc_lo[1]);
2330 err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2331 err |= __put_user(mflo2(), &sc->sc_lo[2]);
2332 err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2333 err |= __put_user(mflo3(), &sc->sc_lo[3]);
2334 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2336 #endif
2337 #endif
2339 #if 0
2340 err |= __put_user(!!used_math(), &sc->sc_used_math);
2342 if (!used_math())
2343 goto out;
2346 * Save FPU state to signal context. Signal handler will "inherit"
2347 * current FPU state.
2349 preempt_disable();
2351 if (!is_fpu_owner()) {
2352 own_fpu();
2353 restore_fp(current);
2355 err |= save_fp_context(sc);
2357 preempt_enable();
2358 out:
2359 #endif
2360 return err;
2363 static inline int
2364 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2366 int err = 0;
2368 err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2370 err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2371 err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2373 #define restore_gp_reg(i) do { \
2374 err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
2375 } while(0)
2376 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2377 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2378 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2379 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2380 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2381 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2382 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2383 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2384 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2385 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2386 restore_gp_reg(31);
2387 #undef restore_gp_reg
2389 #if 0
2390 if (cpu_has_dsp) {
2391 err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2392 err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2393 err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2394 err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2395 err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2396 err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2397 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2399 #ifdef CONFIG_64BIT
2400 err |= __get_user(regs->hi, &sc->sc_hi[0]);
2401 err |= __get_user(regs->lo, &sc->sc_lo[0]);
2402 if (cpu_has_dsp) {
2403 err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2404 err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2405 err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2406 err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2407 err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2408 err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2409 err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2411 #endif
2413 err |= __get_user(used_math, &sc->sc_used_math);
2414 conditional_used_math(used_math);
2416 preempt_disable();
2418 if (used_math()) {
2419 /* restore fpu context if we have used it before */
2420 own_fpu();
2421 err |= restore_fp_context(sc);
2422 } else {
2423 /* signal handler may have used FPU. Give it up. */
2424 lose_fpu();
2427 preempt_enable();
2428 #endif
2429 return err;
2432 * Determine which stack to use..
2434 static inline abi_ulong
2435 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2437 unsigned long sp;
2439 /* Default to using normal stack */
2440 sp = regs->active_tc.gpr[29];
2443 * FPU emulator may have it's own trampoline active just
2444 * above the user stack, 16-bytes before the next lowest
2445 * 16 byte boundary. Try to avoid trashing it.
2447 sp -= 32;
2449 /* This is the X/Open sanctioned signal stack switching. */
2450 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2451 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2454 return (sp - frame_size) & ~7;
2457 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2458 static void setup_frame(int sig, struct target_sigaction * ka,
2459 target_sigset_t *set, CPUState *regs)
2461 struct sigframe *frame;
2462 abi_ulong frame_addr;
2463 int i;
2465 frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2466 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2467 goto give_sigsegv;
2469 install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2471 if(setup_sigcontext(regs, &frame->sf_sc))
2472 goto give_sigsegv;
2474 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2475 if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2476 goto give_sigsegv;
2480 * Arguments to signal handler:
2482 * a0 = signal number
2483 * a1 = 0 (should be cause)
2484 * a2 = pointer to struct sigcontext
2486 * $25 and PC point to the signal handler, $29 points to the
2487 * struct sigframe.
2489 regs->active_tc.gpr[ 4] = sig;
2490 regs->active_tc.gpr[ 5] = 0;
2491 regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2492 regs->active_tc.gpr[29] = frame_addr;
2493 regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2494 /* The original kernel code sets CP0_EPC to the handler
2495 * since it returns to userland using eret
2496 * we cannot do this here, and we must set PC directly */
2497 regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2498 unlock_user_struct(frame, frame_addr, 1);
2499 return;
2501 give_sigsegv:
2502 unlock_user_struct(frame, frame_addr, 1);
2503 force_sig(TARGET_SIGSEGV/*, current*/);
2504 return;
2507 long do_sigreturn(CPUState *regs)
2509 struct sigframe *frame;
2510 abi_ulong frame_addr;
2511 sigset_t blocked;
2512 target_sigset_t target_set;
2513 int i;
2515 #if defined(DEBUG_SIGNAL)
2516 fprintf(stderr, "do_sigreturn\n");
2517 #endif
2518 frame_addr = regs->active_tc.gpr[29];
2519 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2520 goto badframe;
2522 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2523 if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2524 goto badframe;
2527 target_to_host_sigset_internal(&blocked, &target_set);
2528 sigprocmask(SIG_SETMASK, &blocked, NULL);
2530 if (restore_sigcontext(regs, &frame->sf_sc))
2531 goto badframe;
2533 #if 0
2535 * Don't let your children do this ...
2537 __asm__ __volatile__(
2538 "move\t$29, %0\n\t"
2539 "j\tsyscall_exit"
2540 :/* no outputs */
2541 :"r" (&regs));
2542 /* Unreached */
2543 #endif
2545 regs->active_tc.PC = regs->CP0_EPC;
2546 /* I am not sure this is right, but it seems to work
2547 * maybe a problem with nested signals ? */
2548 regs->CP0_EPC = 0;
2549 return 0;
2551 badframe:
2552 force_sig(TARGET_SIGSEGV/*, current*/);
2553 return 0;
2556 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2557 target_siginfo_t *info,
2558 target_sigset_t *set, CPUState *env)
2560 fprintf(stderr, "setup_rt_frame: not implemented\n");
2563 long do_rt_sigreturn(CPUState *env)
2565 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2566 return -TARGET_ENOSYS;
2569 #elif defined(TARGET_SH4)
2572 * code and data structures from linux kernel:
2573 * include/asm-sh/sigcontext.h
2574 * arch/sh/kernel/signal.c
2577 struct target_sigcontext {
2578 target_ulong oldmask;
2580 /* CPU registers */
2581 target_ulong sc_gregs[16];
2582 target_ulong sc_pc;
2583 target_ulong sc_pr;
2584 target_ulong sc_sr;
2585 target_ulong sc_gbr;
2586 target_ulong sc_mach;
2587 target_ulong sc_macl;
2589 /* FPU registers */
2590 target_ulong sc_fpregs[16];
2591 target_ulong sc_xfpregs[16];
2592 unsigned int sc_fpscr;
2593 unsigned int sc_fpul;
2594 unsigned int sc_ownedfp;
2597 struct target_sigframe
2599 struct target_sigcontext sc;
2600 target_ulong extramask[TARGET_NSIG_WORDS-1];
2601 uint16_t retcode[3];
2605 struct target_ucontext {
2606 target_ulong uc_flags;
2607 struct target_ucontext *uc_link;
2608 target_stack_t uc_stack;
2609 struct target_sigcontext uc_mcontext;
2610 target_sigset_t uc_sigmask; /* mask last for extensibility */
2613 struct target_rt_sigframe
2615 struct target_siginfo info;
2616 struct target_ucontext uc;
2617 uint16_t retcode[3];
2621 #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2622 #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) SH3/4 */
2624 static abi_ulong get_sigframe(struct target_sigaction *ka,
2625 unsigned long sp, size_t frame_size)
2627 if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2628 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2631 return (sp - frame_size) & -8ul;
2634 static int setup_sigcontext(struct target_sigcontext *sc,
2635 CPUState *regs, unsigned long mask)
2637 int err = 0;
2639 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
2640 COPY(gregs[0]); COPY(gregs[1]);
2641 COPY(gregs[2]); COPY(gregs[3]);
2642 COPY(gregs[4]); COPY(gregs[5]);
2643 COPY(gregs[6]); COPY(gregs[7]);
2644 COPY(gregs[8]); COPY(gregs[9]);
2645 COPY(gregs[10]); COPY(gregs[11]);
2646 COPY(gregs[12]); COPY(gregs[13]);
2647 COPY(gregs[14]); COPY(gregs[15]);
2648 COPY(gbr); COPY(mach);
2649 COPY(macl); COPY(pr);
2650 COPY(sr); COPY(pc);
2651 #undef COPY
2653 /* todo: save FPU registers here */
2655 /* non-iBCS2 extensions.. */
2656 err |= __put_user(mask, &sc->oldmask);
2658 return err;
2661 static int restore_sigcontext(struct CPUState *regs,
2662 struct target_sigcontext *sc)
2664 unsigned int err = 0;
2666 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
2667 COPY(gregs[1]);
2668 COPY(gregs[2]); COPY(gregs[3]);
2669 COPY(gregs[4]); COPY(gregs[5]);
2670 COPY(gregs[6]); COPY(gregs[7]);
2671 COPY(gregs[8]); COPY(gregs[9]);
2672 COPY(gregs[10]); COPY(gregs[11]);
2673 COPY(gregs[12]); COPY(gregs[13]);
2674 COPY(gregs[14]); COPY(gregs[15]);
2675 COPY(gbr); COPY(mach);
2676 COPY(macl); COPY(pr);
2677 COPY(sr); COPY(pc);
2678 #undef COPY
2680 /* todo: restore FPU registers here */
2682 regs->tra = -1; /* disable syscall checks */
2683 return err;
2686 static void setup_frame(int sig, struct target_sigaction *ka,
2687 target_sigset_t *set, CPUState *regs)
2689 struct target_sigframe *frame;
2690 abi_ulong frame_addr;
2691 int i;
2692 int err = 0;
2693 int signal;
2695 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2696 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2697 goto give_sigsegv;
2699 signal = current_exec_domain_sig(sig);
2701 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2703 for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2704 err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2707 /* Set up to return from userspace. If provided, use a stub
2708 already in userspace. */
2709 if (ka->sa_flags & TARGET_SA_RESTORER) {
2710 regs->pr = (unsigned long) ka->sa_restorer;
2711 } else {
2712 /* Generate return code (system call to sigreturn) */
2713 err |= __put_user(MOVW(2), &frame->retcode[0]);
2714 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2715 err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2716 regs->pr = (unsigned long) frame->retcode;
2719 if (err)
2720 goto give_sigsegv;
2722 /* Set up registers for signal handler */
2723 regs->gregs[15] = (unsigned long) frame;
2724 regs->gregs[4] = signal; /* Arg for signal handler */
2725 regs->gregs[5] = 0;
2726 regs->gregs[6] = (unsigned long) &frame->sc;
2727 regs->pc = (unsigned long) ka->_sa_handler;
2729 unlock_user_struct(frame, frame_addr, 1);
2730 return;
2732 give_sigsegv:
2733 unlock_user_struct(frame, frame_addr, 1);
2734 force_sig(SIGSEGV);
2737 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2738 target_siginfo_t *info,
2739 target_sigset_t *set, CPUState *regs)
2741 struct target_rt_sigframe *frame;
2742 abi_ulong frame_addr;
2743 int i;
2744 int err = 0;
2745 int signal;
2747 frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2748 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2749 goto give_sigsegv;
2751 signal = current_exec_domain_sig(sig);
2753 err |= copy_siginfo_to_user(&frame->info, info);
2755 /* Create the ucontext. */
2756 err |= __put_user(0, &frame->uc.uc_flags);
2757 err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2758 err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2759 &frame->uc.uc_stack.ss_sp);
2760 err |= __put_user(sas_ss_flags(regs->gregs[15]),
2761 &frame->uc.uc_stack.ss_flags);
2762 err |= __put_user(target_sigaltstack_used.ss_size,
2763 &frame->uc.uc_stack.ss_size);
2764 err |= setup_sigcontext(&frame->uc.uc_mcontext,
2765 regs, set->sig[0]);
2766 for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2767 err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2770 /* Set up to return from userspace. If provided, use a stub
2771 already in userspace. */
2772 if (ka->sa_flags & TARGET_SA_RESTORER) {
2773 regs->pr = (unsigned long) ka->sa_restorer;
2774 } else {
2775 /* Generate return code (system call to sigreturn) */
2776 err |= __put_user(MOVW(2), &frame->retcode[0]);
2777 err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2778 err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2779 regs->pr = (unsigned long) frame->retcode;
2782 if (err)
2783 goto give_sigsegv;
2785 /* Set up registers for signal handler */
2786 regs->gregs[15] = (unsigned long) frame;
2787 regs->gregs[4] = signal; /* Arg for signal handler */
2788 regs->gregs[5] = (unsigned long) &frame->info;
2789 regs->gregs[6] = (unsigned long) &frame->uc;
2790 regs->pc = (unsigned long) ka->_sa_handler;
2792 unlock_user_struct(frame, frame_addr, 1);
2793 return;
2795 give_sigsegv:
2796 unlock_user_struct(frame, frame_addr, 1);
2797 force_sig(SIGSEGV);
2800 long do_sigreturn(CPUState *regs)
2802 struct target_sigframe *frame;
2803 abi_ulong frame_addr;
2804 sigset_t blocked;
2805 target_sigset_t target_set;
2806 int i;
2807 int err = 0;
2809 #if defined(DEBUG_SIGNAL)
2810 fprintf(stderr, "do_sigreturn\n");
2811 #endif
2812 frame_addr = regs->gregs[15];
2813 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2814 goto badframe;
2816 err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2817 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2818 err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2821 if (err)
2822 goto badframe;
2824 target_to_host_sigset_internal(&blocked, &target_set);
2825 sigprocmask(SIG_SETMASK, &blocked, NULL);
2827 if (restore_sigcontext(regs, &frame->sc))
2828 goto badframe;
2830 unlock_user_struct(frame, frame_addr, 0);
2831 return regs->gregs[0];
2833 badframe:
2834 unlock_user_struct(frame, frame_addr, 0);
2835 force_sig(TARGET_SIGSEGV);
2836 return 0;
2839 long do_rt_sigreturn(CPUState *regs)
2841 struct target_rt_sigframe *frame;
2842 abi_ulong frame_addr;
2843 sigset_t blocked;
2845 #if defined(DEBUG_SIGNAL)
2846 fprintf(stderr, "do_rt_sigreturn\n");
2847 #endif
2848 frame_addr = regs->gregs[15];
2849 if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2850 goto badframe;
2852 target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2853 sigprocmask(SIG_SETMASK, &blocked, NULL);
2855 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2856 goto badframe;
2858 if (do_sigaltstack(frame_addr +
2859 offsetof(struct target_rt_sigframe, uc.uc_stack),
2860 0, get_sp_from_cpustate(regs)) == -EFAULT)
2861 goto badframe;
2863 unlock_user_struct(frame, frame_addr, 0);
2864 return regs->gregs[0];
2866 badframe:
2867 unlock_user_struct(frame, frame_addr, 0);
2868 force_sig(TARGET_SIGSEGV);
2869 return 0;
2871 #elif defined(TARGET_CRIS)
2873 struct target_sigcontext {
2874 struct target_pt_regs regs; /* needs to be first */
2875 uint32_t oldmask;
2876 uint32_t usp; /* usp before stacking this gunk on it */
2879 /* Signal frames. */
2880 struct target_signal_frame {
2881 struct target_sigcontext sc;
2882 uint32_t extramask[TARGET_NSIG_WORDS - 1];
2883 uint8_t retcode[8]; /* Trampoline code. */
2886 struct rt_signal_frame {
2887 struct siginfo *pinfo;
2888 void *puc;
2889 struct siginfo info;
2890 struct ucontext uc;
2891 uint8_t retcode[8]; /* Trampoline code. */
2894 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2896 __put_user(env->regs[0], &sc->regs.r0);
2897 __put_user(env->regs[1], &sc->regs.r1);
2898 __put_user(env->regs[2], &sc->regs.r2);
2899 __put_user(env->regs[3], &sc->regs.r3);
2900 __put_user(env->regs[4], &sc->regs.r4);
2901 __put_user(env->regs[5], &sc->regs.r5);
2902 __put_user(env->regs[6], &sc->regs.r6);
2903 __put_user(env->regs[7], &sc->regs.r7);
2904 __put_user(env->regs[8], &sc->regs.r8);
2905 __put_user(env->regs[9], &sc->regs.r9);
2906 __put_user(env->regs[10], &sc->regs.r10);
2907 __put_user(env->regs[11], &sc->regs.r11);
2908 __put_user(env->regs[12], &sc->regs.r12);
2909 __put_user(env->regs[13], &sc->regs.r13);
2910 __put_user(env->regs[14], &sc->usp);
2911 __put_user(env->regs[15], &sc->regs.acr);
2912 __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2913 __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2914 __put_user(env->pc, &sc->regs.erp);
2917 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2919 __get_user(env->regs[0], &sc->regs.r0);
2920 __get_user(env->regs[1], &sc->regs.r1);
2921 __get_user(env->regs[2], &sc->regs.r2);
2922 __get_user(env->regs[3], &sc->regs.r3);
2923 __get_user(env->regs[4], &sc->regs.r4);
2924 __get_user(env->regs[5], &sc->regs.r5);
2925 __get_user(env->regs[6], &sc->regs.r6);
2926 __get_user(env->regs[7], &sc->regs.r7);
2927 __get_user(env->regs[8], &sc->regs.r8);
2928 __get_user(env->regs[9], &sc->regs.r9);
2929 __get_user(env->regs[10], &sc->regs.r10);
2930 __get_user(env->regs[11], &sc->regs.r11);
2931 __get_user(env->regs[12], &sc->regs.r12);
2932 __get_user(env->regs[13], &sc->regs.r13);
2933 __get_user(env->regs[14], &sc->usp);
2934 __get_user(env->regs[15], &sc->regs.acr);
2935 __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2936 __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2937 __get_user(env->pc, &sc->regs.erp);
2940 static abi_ulong get_sigframe(CPUState *env, int framesize)
2942 abi_ulong sp;
2943 /* Align the stack downwards to 4. */
2944 sp = (env->regs[R_SP] & ~3);
2945 return sp - framesize;
2948 static void setup_frame(int sig, struct target_sigaction *ka,
2949 target_sigset_t *set, CPUState *env)
2951 struct target_signal_frame *frame;
2952 abi_ulong frame_addr;
2953 int err = 0;
2954 int i;
2956 frame_addr = get_sigframe(env, sizeof *frame);
2957 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2958 goto badframe;
2961 * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2962 * use this trampoline anymore but it sets it up for GDB.
2963 * In QEMU, using the trampoline simplifies things a bit so we use it.
2965 * This is movu.w __NR_sigreturn, r9; break 13;
2967 err |= __put_user(0x9c5f, frame->retcode+0);
2968 err |= __put_user(TARGET_NR_sigreturn,
2969 frame->retcode+2);
2970 err |= __put_user(0xe93d, frame->retcode+4);
2972 /* Save the mask. */
2973 err |= __put_user(set->sig[0], &frame->sc.oldmask);
2974 if (err)
2975 goto badframe;
2977 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2978 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
2979 goto badframe;
2982 setup_sigcontext(&frame->sc, env);
2984 /* Move the stack and setup the arguments for the handler. */
2985 env->regs[R_SP] = (uint32_t) (unsigned long) frame;
2986 env->regs[10] = sig;
2987 env->pc = (unsigned long) ka->_sa_handler;
2988 /* Link SRP so the guest returns through the trampoline. */
2989 env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
2991 unlock_user_struct(frame, frame_addr, 1);
2992 return;
2993 badframe:
2994 unlock_user_struct(frame, frame_addr, 1);
2995 force_sig(TARGET_SIGSEGV);
2998 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2999 target_siginfo_t *info,
3000 target_sigset_t *set, CPUState *env)
3002 fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3005 long do_sigreturn(CPUState *env)
3007 struct target_signal_frame *frame;
3008 abi_ulong frame_addr;
3009 target_sigset_t target_set;
3010 sigset_t set;
3011 int i;
3013 frame_addr = env->regs[R_SP];
3014 /* Make sure the guest isn't playing games. */
3015 if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3016 goto badframe;
3018 /* Restore blocked signals */
3019 if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3020 goto badframe;
3021 for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3022 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3023 goto badframe;
3025 target_to_host_sigset_internal(&set, &target_set);
3026 sigprocmask(SIG_SETMASK, &set, NULL);
3028 restore_sigcontext(&frame->sc, env);
3029 /* Compensate for the syscall return path advancing brk. */
3030 env->pc -= 2;
3032 unlock_user_struct(frame, frame_addr, 0);
3033 return env->regs[10];
3034 badframe:
3035 unlock_user_struct(frame, frame_addr, 0);
3036 force_sig(TARGET_SIGSEGV);
3039 long do_rt_sigreturn(CPUState *env)
3041 fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3042 return -TARGET_ENOSYS;
3045 #else
3047 static void setup_frame(int sig, struct target_sigaction *ka,
3048 target_sigset_t *set, CPUState *env)
3050 fprintf(stderr, "setup_frame: not implemented\n");
3053 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3054 target_siginfo_t *info,
3055 target_sigset_t *set, CPUState *env)
3057 fprintf(stderr, "setup_rt_frame: not implemented\n");
3060 long do_sigreturn(CPUState *env)
3062 fprintf(stderr, "do_sigreturn: not implemented\n");
3063 return -TARGET_ENOSYS;
3066 long do_rt_sigreturn(CPUState *env)
3068 fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3069 return -TARGET_ENOSYS;
3072 #endif
3074 void process_pending_signals(CPUState *cpu_env)
3076 int sig;
3077 abi_ulong handler;
3078 sigset_t set, old_set;
3079 target_sigset_t target_old_set;
3080 struct emulated_sigtable *k;
3081 struct target_sigaction *sa;
3082 struct sigqueue *q;
3083 TaskState *ts = cpu_env->opaque;
3085 if (!ts->signal_pending)
3086 return;
3088 /* FIXME: This is not threadsafe. */
3089 k = ts->sigtab;
3090 for(sig = 1; sig <= TARGET_NSIG; sig++) {
3091 if (k->pending)
3092 goto handle_signal;
3093 k++;
3095 /* if no signal is pending, just return */
3096 ts->signal_pending = 0;
3097 return;
3099 handle_signal:
3100 #ifdef DEBUG_SIGNAL
3101 fprintf(stderr, "qemu: process signal %d\n", sig);
3102 #endif
3103 /* dequeue signal */
3104 q = k->first;
3105 k->first = q->next;
3106 if (!k->first)
3107 k->pending = 0;
3109 sig = gdb_handlesig (cpu_env, sig);
3110 if (!sig) {
3111 fprintf (stderr, "Lost signal\n");
3112 abort();
3115 sa = &sigact_table[sig - 1];
3116 handler = sa->_sa_handler;
3117 if (handler == TARGET_SIG_DFL) {
3118 /* default handler : ignore some signal. The other are fatal */
3119 if (sig != TARGET_SIGCHLD &&
3120 sig != TARGET_SIGURG &&
3121 sig != TARGET_SIGWINCH) {
3122 force_sig(sig);
3124 } else if (handler == TARGET_SIG_IGN) {
3125 /* ignore sig */
3126 } else if (handler == TARGET_SIG_ERR) {
3127 force_sig(sig);
3128 } else {
3129 /* compute the blocked signals during the handler execution */
3130 target_to_host_sigset(&set, &sa->sa_mask);
3131 /* SA_NODEFER indicates that the current signal should not be
3132 blocked during the handler */
3133 if (!(sa->sa_flags & TARGET_SA_NODEFER))
3134 sigaddset(&set, target_to_host_signal(sig));
3136 /* block signals in the handler using Linux */
3137 sigprocmask(SIG_BLOCK, &set, &old_set);
3138 /* save the previous blocked signal state to restore it at the
3139 end of the signal execution (see do_sigreturn) */
3140 host_to_target_sigset_internal(&target_old_set, &old_set);
3142 /* if the CPU is in VM86 mode, we restore the 32 bit values */
3143 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3145 CPUX86State *env = cpu_env;
3146 if (env->eflags & VM_MASK)
3147 save_v86_state(env);
3149 #endif
3150 /* prepare the stack frame of the virtual CPU */
3151 if (sa->sa_flags & TARGET_SA_SIGINFO)
3152 setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3153 else
3154 setup_frame(sig, sa, &target_old_set, cpu_env);
3155 if (sa->sa_flags & TARGET_SA_RESETHAND)
3156 sa->_sa_handler = TARGET_SIG_DFL;
3158 if (q != &k->info)
3159 free_sigqueue(cpu_env, q);