5e30522091d9be3624b501591a71c0f93937125d
[qemu] / linux-user / signal.c
1 /*
2  *  Emulation of Linux signals
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
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.
10  *
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.
15  *
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.
19  */
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>
28
29 #include "qemu.h"
30 #include "target_signal.h"
31
32 //#define DEBUG_SIGNAL
33
34 static struct target_sigaltstack target_sigaltstack_used = {
35     .ss_sp = 0,
36     .ss_size = 0,
37     .ss_flags = TARGET_SS_DISABLE,
38 };
39
40 static struct target_sigaction sigact_table[TARGET_NSIG];
41
42 static void host_signal_handler(int host_signum, siginfo_t *info,
43                                 void *puc);
44
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,
87 };
88 static uint8_t target_to_host_signal_table[65];
89
90 static inline int on_sig_stack(unsigned long sp)
91 {
92     return (sp - target_sigaltstack_used.ss_sp
93             < target_sigaltstack_used.ss_size);
94 }
95
96 static inline int sas_ss_flags(unsigned long sp)
97 {
98     return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
99             : on_sig_stack(sp) ? SS_ONSTACK : 0);
100 }
101
102 static inline int host_to_target_signal(int sig)
103 {
104     if (sig > 64)
105         return sig;
106     return host_to_target_signal_table[sig];
107 }
108
109 int target_to_host_signal(int sig)
110 {
111     if (sig > 64)
112         return sig;
113     return target_to_host_signal_table[sig];
114 }
115
116 static inline void target_sigemptyset(target_sigset_t *set)
117 {
118     memset(set, 0, sizeof(*set));
119 }
120
121 static inline void target_sigaddset(target_sigset_t *set, int signum)
122 {
123     signum--;
124     abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
125     set->sig[signum / TARGET_NSIG_BPW] |= mask;
126 }
127
128 static inline int target_sigismember(const target_sigset_t *set, int signum)
129 {
130     signum--;
131     abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW);
132     return ((set->sig[signum / TARGET_NSIG_BPW] & mask) != 0);
133 }
134
135 static void host_to_target_sigset_internal(target_sigset_t *d,
136                                            const sigset_t *s)
137 {
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));
143         }
144     }
145 }
146
147 void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
148 {
149     target_sigset_t d1;
150     int i;
151
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]);
155 }
156
157 static void target_to_host_sigset_internal(sigset_t *d,
158                                            const target_sigset_t *s)
159 {
160     int i;
161     sigemptyset(d);
162     for (i = 1; i <= TARGET_NSIG; i++) {
163         if (target_sigismember(s, i)) {
164             sigaddset(d, target_to_host_signal(i));
165         }
166      }
167 }
168
169 void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
170 {
171     target_sigset_t s1;
172     int i;
173
174     for(i = 0;i < TARGET_NSIG_WORDS; i++)
175         s1.sig[i] = tswapl(s->sig[i]);
176     target_to_host_sigset_internal(d, &s1);
177 }
178
179 void host_to_target_old_sigset(abi_ulong *old_sigset,
180                                const sigset_t *sigset)
181 {
182     target_sigset_t d;
183     host_to_target_sigset(&d, sigset);
184     *old_sigset = d.sig[0];
185 }
186
187 void target_to_host_old_sigset(sigset_t *sigset,
188                                const abi_ulong *old_sigset)
189 {
190     target_sigset_t d;
191     int i;
192
193     d.sig[0] = *old_sigset;
194     for(i = 1;i < TARGET_NSIG_WORDS; i++)
195         d.sig[i] = 0;
196     target_to_host_sigset(sigset, &d);
197 }
198
199 /* siginfo conversion */
200
201 static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
202                                                  const siginfo_t *info)
203 {
204     int sig;
205     sig = host_to_target_signal(info->si_signo);
206     tinfo->si_signo = sig;
207     tinfo->si_errno = 0;
208     tinfo->si_code = info->si_code;
209     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
210         sig == SIGBUS || sig == SIGTRAP) {
211         /* should never come here, but who knows. The information for
212            the target is irrelevant */
213         tinfo->_sifields._sigfault._addr = 0;
214     } else if (sig == SIGIO) {
215         tinfo->_sifields._sigpoll._fd = info->si_fd;
216     } else if (sig >= TARGET_SIGRTMIN) {
217         tinfo->_sifields._rt._pid = info->si_pid;
218         tinfo->_sifields._rt._uid = info->si_uid;
219         /* XXX: potential problem if 64 bit */
220         tinfo->_sifields._rt._sigval.sival_ptr =
221             (abi_ulong)(unsigned long)info->si_value.sival_ptr;
222     }
223 }
224
225 static void tswap_siginfo(target_siginfo_t *tinfo,
226                           const target_siginfo_t *info)
227 {
228     int sig;
229     sig = info->si_signo;
230     tinfo->si_signo = tswap32(sig);
231     tinfo->si_errno = tswap32(info->si_errno);
232     tinfo->si_code = tswap32(info->si_code);
233     if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
234         sig == SIGBUS || sig == SIGTRAP) {
235         tinfo->_sifields._sigfault._addr =
236             tswapl(info->_sifields._sigfault._addr);
237     } else if (sig == SIGIO) {
238         tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
239     } else if (sig >= TARGET_SIGRTMIN) {
240         tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
241         tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
242         tinfo->_sifields._rt._sigval.sival_ptr =
243             tswapl(info->_sifields._rt._sigval.sival_ptr);
244     }
245 }
246
247
248 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
249 {
250     host_to_target_siginfo_noswap(tinfo, info);
251     tswap_siginfo(tinfo, tinfo);
252 }
253
254 /* XXX: we support only POSIX RT signals are used. */
255 /* XXX: find a solution for 64 bit (additional malloced data is needed) */
256 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
257 {
258     info->si_signo = tswap32(tinfo->si_signo);
259     info->si_errno = tswap32(tinfo->si_errno);
260     info->si_code = tswap32(tinfo->si_code);
261     info->si_pid = tswap32(tinfo->_sifields._rt._pid);
262     info->si_uid = tswap32(tinfo->_sifields._rt._uid);
263     info->si_value.sival_ptr =
264             (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
265 }
266
267 static int fatal_signal (int sig)
268 {
269     switch (sig) {
270     case TARGET_SIGCHLD:
271     case TARGET_SIGURG:
272     case TARGET_SIGWINCH:
273         /* Ignored by default.  */
274         return 0;
275     case TARGET_SIGCONT:
276     case TARGET_SIGSTOP:
277     case TARGET_SIGTSTP:
278     case TARGET_SIGTTIN:
279     case TARGET_SIGTTOU:
280         /* Job control signals.  */
281         return 0;
282     default:
283         return 1;
284     }
285 }
286
287 void signal_init(void)
288 {
289     struct sigaction act;
290     struct sigaction oact;
291     int i, j;
292     int host_sig;
293
294     /* generate signal conversion tables */
295     for(i = 1; i <= 64; i++) {
296         if (host_to_target_signal_table[i] == 0)
297             host_to_target_signal_table[i] = i;
298     }
299     for(i = 1; i <= 64; i++) {
300         j = host_to_target_signal_table[i];
301         target_to_host_signal_table[j] = i;
302     }
303
304     /* set all host signal handlers. ALL signals are blocked during
305        the handlers to serialize them. */
306     memset(sigact_table, 0, sizeof(sigact_table));
307
308     sigfillset(&act.sa_mask);
309     act.sa_flags = SA_SIGINFO;
310     act.sa_sigaction = host_signal_handler;
311     for(i = 1; i <= TARGET_NSIG; i++) {
312         host_sig = target_to_host_signal(i);
313         sigaction(host_sig, NULL, &oact);
314         if (oact.sa_sigaction == (void *)SIG_IGN) {
315             sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN;
316         } else if (oact.sa_sigaction == (void *)SIG_DFL) {
317             sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL;
318         }
319         /* If there's already a handler installed then something has
320            gone horribly wrong, so don't even try to handle that case.  */
321         /* Install some handlers for our own use.  We need at least
322            SIGSEGV and SIGBUS, to detect exceptions.  We can not just
323            trap all signals because it affects syscall interrupt
324            behavior.  But do trap all default-fatal signals.  */
325         if (fatal_signal (i))
326             sigaction(host_sig, &act, NULL);
327     }
328 }
329
330 /* signal queue handling */
331
332 static inline struct sigqueue *alloc_sigqueue(CPUState *env)
333 {
334     TaskState *ts = env->opaque;
335     struct sigqueue *q = ts->first_free;
336     if (!q)
337         return NULL;
338     ts->first_free = q->next;
339     return q;
340 }
341
342 static inline void free_sigqueue(CPUState *env, struct sigqueue *q)
343 {
344     TaskState *ts = env->opaque;
345     q->next = ts->first_free;
346     ts->first_free = q;
347 }
348
349 /* abort execution with signal */
350 static void __attribute((noreturn)) force_sig(int sig)
351 {
352     int host_sig;
353     host_sig = target_to_host_signal(sig);
354     fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
355             sig, strsignal(host_sig));
356 #if 1
357     gdb_signalled(thread_env, sig);
358     _exit(-host_sig);
359 #else
360     {
361         struct sigaction act;
362         sigemptyset(&act.sa_mask);
363         act.sa_flags = SA_SIGINFO;
364         act.sa_sigaction = SIG_DFL;
365         sigaction(SIGABRT, &act, NULL);
366         abort();
367     }
368 #endif
369 }
370
371 /* queue a signal so that it will be send to the virtual CPU as soon
372    as possible */
373 int queue_signal(CPUState *env, int sig, target_siginfo_t *info)
374 {
375     TaskState *ts = env->opaque;
376     struct emulated_sigtable *k;
377     struct sigqueue *q, **pq;
378     abi_ulong handler;
379     int queue;
380
381 #if defined(DEBUG_SIGNAL)
382     fprintf(stderr, "queue_signal: sig=%d\n",
383             sig);
384 #endif
385     k = &ts->sigtab[sig - 1];
386     queue = gdb_queuesig ();
387     handler = sigact_table[sig - 1]._sa_handler;
388     if (!queue && handler == TARGET_SIG_DFL) {
389         if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
390             kill(getpid(),SIGSTOP);
391             return 0;
392         } else
393         /* default handler : ignore some signal. The other are fatal */
394         if (sig != TARGET_SIGCHLD &&
395             sig != TARGET_SIGURG &&
396             sig != TARGET_SIGWINCH &&
397             sig != TARGET_SIGCONT) {
398             force_sig(sig);
399         } else {
400             return 0; /* indicate ignored */
401         }
402     } else if (!queue && handler == TARGET_SIG_IGN) {
403         /* ignore signal */
404         return 0;
405     } else if (!queue && handler == TARGET_SIG_ERR) {
406         force_sig(sig);
407     } else {
408         pq = &k->first;
409         if (sig < TARGET_SIGRTMIN) {
410             /* if non real time signal, we queue exactly one signal */
411             if (!k->pending)
412                 q = &k->info;
413             else
414                 return 0;
415         } else {
416             if (!k->pending) {
417                 /* first signal */
418                 q = &k->info;
419             } else {
420                 q = alloc_sigqueue(env);
421                 if (!q)
422                     return -EAGAIN;
423                 while (*pq != NULL)
424                     pq = &(*pq)->next;
425             }
426         }
427         *pq = q;
428         q->info = *info;
429         q->next = NULL;
430         k->pending = 1;
431         /* signal that a new signal is pending */
432         ts->signal_pending = 1;
433         return 1; /* indicates that the signal was queued */
434     }
435 }
436
437 static void host_signal_handler(int host_signum, siginfo_t *info,
438                                 void *puc)
439 {
440     int sig;
441     target_siginfo_t tinfo;
442
443     /* the CPU emulator uses some host signals to detect exceptions,
444        we we forward to it some signals */
445     if ((host_signum == SIGSEGV || host_signum == SIGBUS)
446         && info->si_code == SI_KERNEL) {
447         if (cpu_signal_handler(host_signum, info, puc))
448             return;
449     }
450
451     /* get target signal number */
452     sig = host_to_target_signal(host_signum);
453     if (sig < 1 || sig > TARGET_NSIG)
454         return;
455 #if defined(DEBUG_SIGNAL)
456     fprintf(stderr, "qemu: got signal %d\n", sig);
457 #endif
458     host_to_target_siginfo_noswap(&tinfo, info);
459     if (queue_signal(thread_env, sig, &tinfo) == 1) {
460         /* interrupt the virtual CPU as soon as possible */
461         cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
462     }
463 }
464
465 /* do_sigaltstack() returns target values and errnos. */
466 /* compare linux/kernel/signal.c:do_sigaltstack() */
467 abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
468 {
469     int ret;
470     struct target_sigaltstack oss;
471
472     /* XXX: test errors */
473     if(uoss_addr)
474     {
475         __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
476         __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
477         __put_user(sas_ss_flags(sp), &oss.ss_flags);
478     }
479
480     if(uss_addr)
481     {
482         struct target_sigaltstack *uss;
483         struct target_sigaltstack ss;
484
485         ret = -TARGET_EFAULT;
486         if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)
487             || __get_user(ss.ss_sp, &uss->ss_sp)
488             || __get_user(ss.ss_size, &uss->ss_size)
489             || __get_user(ss.ss_flags, &uss->ss_flags))
490             goto out;
491         unlock_user_struct(uss, uss_addr, 0);
492
493         ret = -TARGET_EPERM;
494         if (on_sig_stack(sp))
495             goto out;
496
497         ret = -TARGET_EINVAL;
498         if (ss.ss_flags != TARGET_SS_DISABLE
499             && ss.ss_flags != TARGET_SS_ONSTACK
500             && ss.ss_flags != 0)
501             goto out;
502
503         if (ss.ss_flags == TARGET_SS_DISABLE) {
504             ss.ss_size = 0;
505             ss.ss_sp = 0;
506         } else {
507             ret = -TARGET_ENOMEM;
508             if (ss.ss_size < MINSIGSTKSZ)
509                 goto out;
510         }
511
512         target_sigaltstack_used.ss_sp = ss.ss_sp;
513         target_sigaltstack_used.ss_size = ss.ss_size;
514     }
515
516     if (uoss_addr) {
517         ret = -TARGET_EFAULT;
518         if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
519             goto out;
520     }
521
522     ret = 0;
523 out:
524     return ret;
525 }
526
527 /* do_sigaction() return host values and errnos */
528 int do_sigaction(int sig, const struct target_sigaction *act,
529                  struct target_sigaction *oact)
530 {
531     struct target_sigaction *k;
532     struct sigaction act1;
533     int host_sig;
534     int ret = 0;
535
536     if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
537         return -EINVAL;
538     k = &sigact_table[sig - 1];
539 #if defined(DEBUG_SIGNAL)
540     fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n",
541             sig, (int)act, (int)oact);
542 #endif
543     if (oact) {
544         oact->_sa_handler = tswapl(k->_sa_handler);
545         oact->sa_flags = tswapl(k->sa_flags);
546 #if !defined(TARGET_MIPS)
547         oact->sa_restorer = tswapl(k->sa_restorer);
548 #endif
549         oact->sa_mask = k->sa_mask;
550     }
551     if (act) {
552         /* FIXME: This is not threadsafe.  */
553         k->_sa_handler = tswapl(act->_sa_handler);
554         k->sa_flags = tswapl(act->sa_flags);
555 #if !defined(TARGET_MIPS)
556         k->sa_restorer = tswapl(act->sa_restorer);
557 #endif
558         k->sa_mask = act->sa_mask;
559
560         /* we update the host linux signal state */
561         host_sig = target_to_host_signal(sig);
562         if (host_sig != SIGSEGV && host_sig != SIGBUS) {
563             sigfillset(&act1.sa_mask);
564             act1.sa_flags = SA_SIGINFO;
565             if (k->sa_flags & TARGET_SA_RESTART)
566                 act1.sa_flags |= SA_RESTART;
567             /* NOTE: it is important to update the host kernel signal
568                ignore state to avoid getting unexpected interrupted
569                syscalls */
570             if (k->_sa_handler == TARGET_SIG_IGN) {
571                 act1.sa_sigaction = (void *)SIG_IGN;
572             } else if (k->_sa_handler == TARGET_SIG_DFL) {
573                 if (fatal_signal (sig))
574                     act1.sa_sigaction = host_signal_handler;
575                 else
576                     act1.sa_sigaction = (void *)SIG_DFL;
577             } else {
578                 act1.sa_sigaction = host_signal_handler;
579             }
580             ret = sigaction(host_sig, &act1, NULL);
581         }
582     }
583     return ret;
584 }
585
586 static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
587                                        const target_siginfo_t *info)
588 {
589     tswap_siginfo(tinfo, info);
590     return 0;
591 }
592
593 static inline int current_exec_domain_sig(int sig)
594 {
595     return /* current->exec_domain && current->exec_domain->signal_invmap
596               && sig < 32 ? current->exec_domain->signal_invmap[sig] : */ sig;
597 }
598
599 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
600
601 /* from the Linux kernel */
602
603 struct target_fpreg {
604         uint16_t significand[4];
605         uint16_t exponent;
606 };
607
608 struct target_fpxreg {
609         uint16_t significand[4];
610         uint16_t exponent;
611         uint16_t padding[3];
612 };
613
614 struct target_xmmreg {
615         abi_ulong element[4];
616 };
617
618 struct target_fpstate {
619         /* Regular FPU environment */
620         abi_ulong       cw;
621         abi_ulong       sw;
622         abi_ulong       tag;
623         abi_ulong       ipoff;
624         abi_ulong       cssel;
625         abi_ulong       dataoff;
626         abi_ulong       datasel;
627         struct target_fpreg     _st[8];
628         uint16_t        status;
629         uint16_t        magic;          /* 0xffff = regular FPU data only */
630
631         /* FXSR FPU environment */
632         abi_ulong       _fxsr_env[6];   /* FXSR FPU env is ignored */
633         abi_ulong       mxcsr;
634         abi_ulong       reserved;
635         struct target_fpxreg    _fxsr_st[8];    /* FXSR FPU reg data is ignored */
636         struct target_xmmreg    _xmm[8];
637         abi_ulong       padding[56];
638 };
639
640 #define X86_FXSR_MAGIC          0x0000
641
642 struct target_sigcontext {
643         uint16_t gs, __gsh;
644         uint16_t fs, __fsh;
645         uint16_t es, __esh;
646         uint16_t ds, __dsh;
647         abi_ulong edi;
648         abi_ulong esi;
649         abi_ulong ebp;
650         abi_ulong esp;
651         abi_ulong ebx;
652         abi_ulong edx;
653         abi_ulong ecx;
654         abi_ulong eax;
655         abi_ulong trapno;
656         abi_ulong err;
657         abi_ulong eip;
658         uint16_t cs, __csh;
659         abi_ulong eflags;
660         abi_ulong esp_at_signal;
661         uint16_t ss, __ssh;
662         abi_ulong fpstate; /* pointer */
663         abi_ulong oldmask;
664         abi_ulong cr2;
665 };
666
667 struct target_ucontext {
668         abi_ulong         tuc_flags;
669         abi_ulong         tuc_link;
670         target_stack_t    tuc_stack;
671         struct target_sigcontext tuc_mcontext;
672         target_sigset_t   tuc_sigmask;  /* mask last for extensibility */
673 };
674
675 struct sigframe
676 {
677     abi_ulong pretcode;
678     int sig;
679     struct target_sigcontext sc;
680     struct target_fpstate fpstate;
681     abi_ulong extramask[TARGET_NSIG_WORDS-1];
682     char retcode[8];
683 };
684
685 struct rt_sigframe
686 {
687     abi_ulong pretcode;
688     int sig;
689     abi_ulong pinfo;
690     abi_ulong puc;
691     struct target_siginfo info;
692     struct target_ucontext uc;
693     struct target_fpstate fpstate;
694     char retcode[8];
695 };
696
697 /*
698  * Set up a signal frame.
699  */
700
701 /* XXX: save x87 state */
702 static int
703 setup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,
704                  CPUX86State *env, abi_ulong mask, abi_ulong fpstate_addr)
705 {
706         int err = 0;
707         uint16_t magic;
708
709         /* already locked in setup_frame() */
710         err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);
711         err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);
712         err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);
713         err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);
714         err |= __put_user(env->regs[R_EDI], &sc->edi);
715         err |= __put_user(env->regs[R_ESI], &sc->esi);
716         err |= __put_user(env->regs[R_EBP], &sc->ebp);
717         err |= __put_user(env->regs[R_ESP], &sc->esp);
718         err |= __put_user(env->regs[R_EBX], &sc->ebx);
719         err |= __put_user(env->regs[R_EDX], &sc->edx);
720         err |= __put_user(env->regs[R_ECX], &sc->ecx);
721         err |= __put_user(env->regs[R_EAX], &sc->eax);
722         err |= __put_user(env->exception_index, &sc->trapno);
723         err |= __put_user(env->error_code, &sc->err);
724         err |= __put_user(env->eip, &sc->eip);
725         err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);
726         err |= __put_user(env->eflags, &sc->eflags);
727         err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);
728         err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);
729
730         cpu_x86_fsave(env, fpstate_addr, 1);
731         fpstate->status = fpstate->sw;
732         magic = 0xffff;
733         err |= __put_user(magic, &fpstate->magic);
734         err |= __put_user(fpstate_addr, &sc->fpstate);
735
736         /* non-iBCS2 extensions.. */
737         err |= __put_user(mask, &sc->oldmask);
738         err |= __put_user(env->cr[2], &sc->cr2);
739         return err;
740 }
741
742 /*
743  * Determine which stack to use..
744  */
745
746 static inline abi_ulong
747 get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
748 {
749         unsigned long esp;
750
751         /* Default to using normal stack */
752         esp = env->regs[R_ESP];
753         /* This is the X/Open sanctioned signal stack switching.  */
754         if (ka->sa_flags & TARGET_SA_ONSTACK) {
755             if (sas_ss_flags(esp) == 0)
756                 esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
757         }
758
759         /* This is the legacy signal stack switching. */
760         else
761         if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&
762             !(ka->sa_flags & TARGET_SA_RESTORER) &&
763             ka->sa_restorer) {
764             esp = (unsigned long) ka->sa_restorer;
765         }
766         return (esp - frame_size) & -8ul;
767 }
768
769 /* compare linux/arch/i386/kernel/signal.c:setup_frame() */
770 static void setup_frame(int sig, struct target_sigaction *ka,
771                         target_sigset_t *set, CPUX86State *env)
772 {
773         abi_ulong frame_addr;
774         struct sigframe *frame;
775         int i, err = 0;
776
777         frame_addr = get_sigframe(ka, env, sizeof(*frame));
778
779         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
780                 goto give_sigsegv;
781
782         err |= __put_user(current_exec_domain_sig(sig),
783                           &frame->sig);
784         if (err)
785                 goto give_sigsegv;
786
787         setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0],
788                          frame_addr + offsetof(struct sigframe, fpstate));
789         if (err)
790                 goto give_sigsegv;
791
792         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
793             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
794                 goto give_sigsegv;
795         }
796
797         /* Set up to return from userspace.  If provided, use a stub
798            already in userspace.  */
799         if (ka->sa_flags & TARGET_SA_RESTORER) {
800                 err |= __put_user(ka->sa_restorer, &frame->pretcode);
801         } else {
802                 uint16_t val16;
803                 abi_ulong retcode_addr;
804                 retcode_addr = frame_addr + offsetof(struct sigframe, retcode);
805                 err |= __put_user(retcode_addr, &frame->pretcode);
806                 /* This is popl %eax ; movl $,%eax ; int $0x80 */
807                 val16 = 0xb858;
808                 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
809                 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
810                 val16 = 0x80cd;
811                 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
812         }
813
814         if (err)
815                 goto give_sigsegv;
816
817         /* Set up registers for signal handler */
818         env->regs[R_ESP] = frame_addr;
819         env->eip = ka->_sa_handler;
820
821         cpu_x86_load_seg(env, R_DS, __USER_DS);
822         cpu_x86_load_seg(env, R_ES, __USER_DS);
823         cpu_x86_load_seg(env, R_SS, __USER_DS);
824         cpu_x86_load_seg(env, R_CS, __USER_CS);
825         env->eflags &= ~TF_MASK;
826
827         unlock_user_struct(frame, frame_addr, 1);
828
829         return;
830
831 give_sigsegv:
832         unlock_user_struct(frame, frame_addr, 1);
833         if (sig == TARGET_SIGSEGV)
834                 ka->_sa_handler = TARGET_SIG_DFL;
835         force_sig(TARGET_SIGSEGV /* , current */);
836 }
837
838 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
839 static void setup_rt_frame(int sig, struct target_sigaction *ka,
840                            target_siginfo_t *info,
841                            target_sigset_t *set, CPUX86State *env)
842 {
843         abi_ulong frame_addr, addr;
844         struct rt_sigframe *frame;
845         int i, err = 0;
846
847         frame_addr = get_sigframe(ka, env, sizeof(*frame));
848
849         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
850                 goto give_sigsegv;
851
852         err |= __put_user(current_exec_domain_sig(sig),
853                           &frame->sig);
854         addr = frame_addr + offsetof(struct rt_sigframe, info);
855         err |= __put_user(addr, &frame->pinfo);
856         addr = frame_addr + offsetof(struct rt_sigframe, uc);
857         err |= __put_user(addr, &frame->puc);
858         err |= copy_siginfo_to_user(&frame->info, info);
859         if (err)
860                 goto give_sigsegv;
861
862         /* Create the ucontext.  */
863         err |= __put_user(0, &frame->uc.tuc_flags);
864         err |= __put_user(0, &frame->uc.tuc_link);
865         err |= __put_user(target_sigaltstack_used.ss_sp,
866                           &frame->uc.tuc_stack.ss_sp);
867         err |= __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
868                           &frame->uc.tuc_stack.ss_flags);
869         err |= __put_user(target_sigaltstack_used.ss_size,
870                           &frame->uc.tuc_stack.ss_size);
871         err |= setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate,
872                                 env, set->sig[0], 
873                                 frame_addr + offsetof(struct rt_sigframe, fpstate));
874         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
875             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
876                 goto give_sigsegv;
877         }
878
879         /* Set up to return from userspace.  If provided, use a stub
880            already in userspace.  */
881         if (ka->sa_flags & TARGET_SA_RESTORER) {
882                 err |= __put_user(ka->sa_restorer, &frame->pretcode);
883         } else {
884                 uint16_t val16;
885                 addr = frame_addr + offsetof(struct rt_sigframe, retcode);
886                 err |= __put_user(addr, &frame->pretcode);
887                 /* This is movl $,%eax ; int $0x80 */
888                 err |= __put_user(0xb8, (char *)(frame->retcode+0));
889                 err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));
890                 val16 = 0x80cd;
891                 err |= __put_user(val16, (uint16_t *)(frame->retcode+5));
892         }
893
894         if (err)
895                 goto give_sigsegv;
896
897         /* Set up registers for signal handler */
898         env->regs[R_ESP] = frame_addr;
899         env->eip = ka->_sa_handler;
900
901         cpu_x86_load_seg(env, R_DS, __USER_DS);
902         cpu_x86_load_seg(env, R_ES, __USER_DS);
903         cpu_x86_load_seg(env, R_SS, __USER_DS);
904         cpu_x86_load_seg(env, R_CS, __USER_CS);
905         env->eflags &= ~TF_MASK;
906
907         unlock_user_struct(frame, frame_addr, 1);
908
909         return;
910
911 give_sigsegv:
912         unlock_user_struct(frame, frame_addr, 1);
913         if (sig == TARGET_SIGSEGV)
914                 ka->_sa_handler = TARGET_SIG_DFL;
915         force_sig(TARGET_SIGSEGV /* , current */);
916 }
917
918 static int
919 restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
920 {
921         unsigned int err = 0;
922         abi_ulong fpstate_addr;
923         unsigned int tmpflags;
924
925         cpu_x86_load_seg(env, R_GS, tswap16(sc->gs));
926         cpu_x86_load_seg(env, R_FS, tswap16(sc->fs));
927         cpu_x86_load_seg(env, R_ES, tswap16(sc->es));
928         cpu_x86_load_seg(env, R_DS, tswap16(sc->ds));
929
930         env->regs[R_EDI] = tswapl(sc->edi);
931         env->regs[R_ESI] = tswapl(sc->esi);
932         env->regs[R_EBP] = tswapl(sc->ebp);
933         env->regs[R_ESP] = tswapl(sc->esp);
934         env->regs[R_EBX] = tswapl(sc->ebx);
935         env->regs[R_EDX] = tswapl(sc->edx);
936         env->regs[R_ECX] = tswapl(sc->ecx);
937         env->eip = tswapl(sc->eip);
938
939         cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
940         cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
941
942         tmpflags = tswapl(sc->eflags);
943         env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
944         //              regs->orig_eax = -1;            /* disable syscall checks */
945
946         fpstate_addr = tswapl(sc->fpstate);
947         if (fpstate_addr != 0) {
948                 if (!access_ok(VERIFY_READ, fpstate_addr, 
949                                sizeof(struct target_fpstate)))
950                         goto badframe;
951                 cpu_x86_frstor(env, fpstate_addr, 1);
952         }
953
954         *peax = tswapl(sc->eax);
955         return err;
956 badframe:
957         return 1;
958 }
959
960 long do_sigreturn(CPUX86State *env)
961 {
962     struct sigframe *frame;
963     abi_ulong frame_addr = env->regs[R_ESP] - 8;
964     target_sigset_t target_set;
965     sigset_t set;
966     int eax, i;
967
968 #if defined(DEBUG_SIGNAL)
969     fprintf(stderr, "do_sigreturn\n");
970 #endif
971     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
972         goto badframe;
973     /* set blocked signals */
974     if (__get_user(target_set.sig[0], &frame->sc.oldmask))
975         goto badframe;
976     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
977         if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
978             goto badframe;
979     }
980
981     target_to_host_sigset_internal(&set, &target_set);
982     sigprocmask(SIG_SETMASK, &set, NULL);
983
984     /* restore registers */
985     if (restore_sigcontext(env, &frame->sc, &eax))
986         goto badframe;
987     unlock_user_struct(frame, frame_addr, 0);
988     return eax;
989
990 badframe:
991     unlock_user_struct(frame, frame_addr, 0);
992     force_sig(TARGET_SIGSEGV);
993     return 0;
994 }
995
996 long do_rt_sigreturn(CPUX86State *env)
997 {
998         abi_ulong frame_addr;
999         struct rt_sigframe *frame;
1000         sigset_t set;
1001         int eax;
1002
1003         frame_addr = env->regs[R_ESP] - 4;
1004         if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1005                 goto badframe;
1006         target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
1007         sigprocmask(SIG_SETMASK, &set, NULL);
1008
1009         if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))
1010                 goto badframe;
1011
1012         if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0, 
1013                            get_sp_from_cpustate(env)) == -EFAULT)
1014                 goto badframe;
1015
1016         unlock_user_struct(frame, frame_addr, 0);
1017         return eax;
1018
1019 badframe:
1020         unlock_user_struct(frame, frame_addr, 0);
1021         force_sig(TARGET_SIGSEGV);
1022         return 0;
1023 }
1024
1025 #elif defined(TARGET_ARM)
1026
1027 struct target_sigcontext {
1028         abi_ulong trap_no;
1029         abi_ulong error_code;
1030         abi_ulong oldmask;
1031         abi_ulong arm_r0;
1032         abi_ulong arm_r1;
1033         abi_ulong arm_r2;
1034         abi_ulong arm_r3;
1035         abi_ulong arm_r4;
1036         abi_ulong arm_r5;
1037         abi_ulong arm_r6;
1038         abi_ulong arm_r7;
1039         abi_ulong arm_r8;
1040         abi_ulong arm_r9;
1041         abi_ulong arm_r10;
1042         abi_ulong arm_fp;
1043         abi_ulong arm_ip;
1044         abi_ulong arm_sp;
1045         abi_ulong arm_lr;
1046         abi_ulong arm_pc;
1047         abi_ulong arm_cpsr;
1048         abi_ulong fault_address;
1049 };
1050
1051 struct target_ucontext_v1 {
1052     abi_ulong tuc_flags;
1053     abi_ulong tuc_link;
1054     target_stack_t tuc_stack;
1055     struct target_sigcontext tuc_mcontext;
1056     target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
1057 };
1058
1059 struct target_ucontext_v2 {
1060     abi_ulong tuc_flags;
1061     abi_ulong tuc_link;
1062     target_stack_t tuc_stack;
1063     struct target_sigcontext tuc_mcontext;
1064     target_sigset_t  tuc_sigmask;       /* mask last for extensibility */
1065     char __unused[128 - sizeof(sigset_t)];
1066     abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
1067 };
1068
1069 struct sigframe_v1
1070 {
1071     struct target_sigcontext sc;
1072     abi_ulong extramask[TARGET_NSIG_WORDS-1];
1073     abi_ulong retcode;
1074 };
1075
1076 struct sigframe_v2
1077 {
1078     struct target_ucontext_v2 uc;
1079     abi_ulong retcode;
1080 };
1081
1082 struct rt_sigframe_v1
1083 {
1084     abi_ulong pinfo;
1085     abi_ulong puc;
1086     struct target_siginfo info;
1087     struct target_ucontext_v1 uc;
1088     abi_ulong retcode;
1089 };
1090
1091 struct rt_sigframe_v2
1092 {
1093     struct target_siginfo info;
1094     struct target_ucontext_v2 uc;
1095     abi_ulong retcode;
1096 };
1097
1098 #define TARGET_CONFIG_CPU_32 1
1099
1100 /*
1101  * For ARM syscalls, we encode the syscall number into the instruction.
1102  */
1103 #define SWI_SYS_SIGRETURN       (0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))
1104 #define SWI_SYS_RT_SIGRETURN    (0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))
1105
1106 /*
1107  * For Thumb syscalls, we pass the syscall number via r7.  We therefore
1108  * need two 16-bit instructions.
1109  */
1110 #define SWI_THUMB_SIGRETURN     (0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))
1111 #define SWI_THUMB_RT_SIGRETURN  (0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))
1112
1113 static const abi_ulong retcodes[4] = {
1114         SWI_SYS_SIGRETURN,      SWI_THUMB_SIGRETURN,
1115         SWI_SYS_RT_SIGRETURN,   SWI_THUMB_RT_SIGRETURN
1116 };
1117
1118
1119 #define __get_user_error(x,p,e) __get_user(x, p)
1120
1121 static inline int valid_user_regs(CPUState *regs)
1122 {
1123     return 1;
1124 }
1125
1126 static void
1127 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1128                  CPUState *env, abi_ulong mask)
1129 {
1130         __put_user(env->regs[0], &sc->arm_r0);
1131         __put_user(env->regs[1], &sc->arm_r1);
1132         __put_user(env->regs[2], &sc->arm_r2);
1133         __put_user(env->regs[3], &sc->arm_r3);
1134         __put_user(env->regs[4], &sc->arm_r4);
1135         __put_user(env->regs[5], &sc->arm_r5);
1136         __put_user(env->regs[6], &sc->arm_r6);
1137         __put_user(env->regs[7], &sc->arm_r7);
1138         __put_user(env->regs[8], &sc->arm_r8);
1139         __put_user(env->regs[9], &sc->arm_r9);
1140         __put_user(env->regs[10], &sc->arm_r10);
1141         __put_user(env->regs[11], &sc->arm_fp);
1142         __put_user(env->regs[12], &sc->arm_ip);
1143         __put_user(env->regs[13], &sc->arm_sp);
1144         __put_user(env->regs[14], &sc->arm_lr);
1145         __put_user(env->regs[15], &sc->arm_pc);
1146 #ifdef TARGET_CONFIG_CPU_32
1147         __put_user(cpsr_read(env), &sc->arm_cpsr);
1148 #endif
1149
1150         __put_user(/* current->thread.trap_no */ 0, &sc->trap_no);
1151         __put_user(/* current->thread.error_code */ 0, &sc->error_code);
1152         __put_user(/* current->thread.address */ 0, &sc->fault_address);
1153         __put_user(mask, &sc->oldmask);
1154 }
1155
1156 static inline abi_ulong
1157 get_sigframe(struct target_sigaction *ka, CPUState *regs, int framesize)
1158 {
1159         unsigned long sp = regs->regs[13];
1160
1161         /*
1162          * This is the X/Open sanctioned signal stack switching.
1163          */
1164         if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp))
1165             sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1166         /*
1167          * ATPCS B01 mandates 8-byte alignment
1168          */
1169         return (sp - framesize) & ~7;
1170 }
1171
1172 static int
1173 setup_return(CPUState *env, struct target_sigaction *ka,
1174              abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
1175 {
1176         abi_ulong handler = ka->_sa_handler;
1177         abi_ulong retcode;
1178         int thumb = handler & 1;
1179
1180         if (ka->sa_flags & TARGET_SA_RESTORER) {
1181                 retcode = ka->sa_restorer;
1182         } else {
1183                 unsigned int idx = thumb;
1184
1185                 if (ka->sa_flags & TARGET_SA_SIGINFO)
1186                         idx += 2;
1187
1188                 if (__put_user(retcodes[idx], rc))
1189                         return 1;
1190 #if 0
1191                 flush_icache_range((abi_ulong)rc,
1192                                    (abi_ulong)(rc + 1));
1193 #endif
1194                 retcode = rc_addr + thumb;
1195         }
1196
1197         env->regs[0] = usig;
1198         env->regs[13] = frame_addr;
1199         env->regs[14] = retcode;
1200         env->regs[15] = handler & (thumb ? ~1 : ~3);
1201         env->thumb = thumb;
1202
1203 #if 0
1204 #ifdef TARGET_CONFIG_CPU_32
1205         env->cpsr = cpsr;
1206 #endif
1207 #endif
1208
1209         return 0;
1210 }
1211
1212 static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
1213                               target_sigset_t *set, CPUState *env)
1214 {
1215     struct target_sigaltstack stack;
1216     int i;
1217
1218     /* Clear all the bits of the ucontext we don't use.  */
1219     memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
1220
1221     memset(&stack, 0, sizeof(stack));
1222     __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1223     __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1224     __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1225     memcpy(&uc->tuc_stack, &stack, sizeof(stack));
1226
1227     setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
1228     /* FIXME: Save coprocessor signal frame.  */
1229     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1230         __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
1231     }
1232 }
1233
1234 /* compare linux/arch/arm/kernel/signal.c:setup_frame() */
1235 static void setup_frame_v1(int usig, struct target_sigaction *ka,
1236                            target_sigset_t *set, CPUState *regs)
1237 {
1238         struct sigframe_v1 *frame;
1239         abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1240         int i;
1241
1242         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1243                 return;
1244
1245         setup_sigcontext(&frame->sc, regs, set->sig[0]);
1246
1247         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1248             if (__put_user(set->sig[i], &frame->extramask[i - 1]))
1249                 goto end;
1250         }
1251
1252         setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1253                      frame_addr + offsetof(struct sigframe_v1, retcode));
1254
1255 end:
1256         unlock_user_struct(frame, frame_addr, 1);
1257 }
1258
1259 static void setup_frame_v2(int usig, struct target_sigaction *ka,
1260                            target_sigset_t *set, CPUState *regs)
1261 {
1262         struct sigframe_v2 *frame;
1263         abi_ulong frame_addr = get_sigframe(ka, regs, sizeof(*frame));
1264
1265         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1266                 return;
1267
1268         setup_sigframe_v2(&frame->uc, set, regs);
1269
1270         setup_return(regs, ka, &frame->retcode, frame_addr, usig,
1271                      frame_addr + offsetof(struct sigframe_v2, retcode));
1272
1273         unlock_user_struct(frame, frame_addr, 1);
1274 }
1275
1276 static void setup_frame(int usig, struct target_sigaction *ka,
1277                         target_sigset_t *set, CPUState *regs)
1278 {
1279     if (get_osversion() >= 0x020612) {
1280         setup_frame_v2(usig, ka, set, regs);
1281     } else {
1282         setup_frame_v1(usig, ka, set, regs);
1283     }
1284 }
1285
1286 /* compare linux/arch/arm/kernel/signal.c:setup_rt_frame() */
1287 static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
1288                               target_siginfo_t *info,
1289                               target_sigset_t *set, CPUState *env)
1290 {
1291         struct rt_sigframe_v1 *frame;
1292         abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1293         struct target_sigaltstack stack;
1294         int i;
1295         abi_ulong info_addr, uc_addr;
1296
1297         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1298             return /* 1 */;
1299
1300         info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
1301         __put_user(info_addr, &frame->pinfo);
1302         uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);
1303         __put_user(uc_addr, &frame->puc);
1304         copy_siginfo_to_user(&frame->info, info);
1305
1306         /* Clear all the bits of the ucontext we don't use.  */
1307         memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
1308
1309         memset(&stack, 0, sizeof(stack));
1310         __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
1311         __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
1312         __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
1313         memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
1314
1315         setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
1316         for(i = 0; i < TARGET_NSIG_WORDS; i++) {
1317             if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))
1318                 goto end;
1319         }
1320
1321         setup_return(env, ka, &frame->retcode, frame_addr, usig,
1322                      frame_addr + offsetof(struct rt_sigframe_v1, retcode));
1323
1324         env->regs[1] = info_addr;
1325         env->regs[2] = uc_addr;
1326
1327 end:
1328         unlock_user_struct(frame, frame_addr, 1);
1329 }
1330
1331 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
1332                               target_siginfo_t *info,
1333                               target_sigset_t *set, CPUState *env)
1334 {
1335         struct rt_sigframe_v2 *frame;
1336         abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));
1337         abi_ulong info_addr, uc_addr;
1338
1339         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
1340             return /* 1 */;
1341
1342         info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
1343         uc_addr = frame_addr + offsetof(struct rt_sigframe_v2, uc);
1344         copy_siginfo_to_user(&frame->info, info);
1345
1346         setup_sigframe_v2(&frame->uc, set, env);
1347
1348         setup_return(env, ka, &frame->retcode, frame_addr, usig,
1349                      frame_addr + offsetof(struct rt_sigframe_v2, retcode));
1350
1351         env->regs[1] = info_addr;
1352         env->regs[2] = uc_addr;
1353
1354         unlock_user_struct(frame, frame_addr, 1);
1355 }
1356
1357 static void setup_rt_frame(int usig, struct target_sigaction *ka,
1358                            target_siginfo_t *info,
1359                            target_sigset_t *set, CPUState *env)
1360 {
1361     if (get_osversion() >= 0x020612) {
1362         setup_rt_frame_v2(usig, ka, info, set, env);
1363     } else {
1364         setup_rt_frame_v1(usig, ka, info, set, env);
1365     }
1366 }
1367
1368 static int
1369 restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
1370 {
1371         int err = 0;
1372         uint32_t cpsr;
1373
1374         __get_user_error(env->regs[0], &sc->arm_r0, err);
1375         __get_user_error(env->regs[1], &sc->arm_r1, err);
1376         __get_user_error(env->regs[2], &sc->arm_r2, err);
1377         __get_user_error(env->regs[3], &sc->arm_r3, err);
1378         __get_user_error(env->regs[4], &sc->arm_r4, err);
1379         __get_user_error(env->regs[5], &sc->arm_r5, err);
1380         __get_user_error(env->regs[6], &sc->arm_r6, err);
1381         __get_user_error(env->regs[7], &sc->arm_r7, err);
1382         __get_user_error(env->regs[8], &sc->arm_r8, err);
1383         __get_user_error(env->regs[9], &sc->arm_r9, err);
1384         __get_user_error(env->regs[10], &sc->arm_r10, err);
1385         __get_user_error(env->regs[11], &sc->arm_fp, err);
1386         __get_user_error(env->regs[12], &sc->arm_ip, err);
1387         __get_user_error(env->regs[13], &sc->arm_sp, err);
1388         __get_user_error(env->regs[14], &sc->arm_lr, err);
1389         __get_user_error(env->regs[15], &sc->arm_pc, err);
1390 #ifdef TARGET_CONFIG_CPU_32
1391         __get_user_error(cpsr, &sc->arm_cpsr, err);
1392         cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC);
1393 #endif
1394
1395         err |= !valid_user_regs(env);
1396
1397         return err;
1398 }
1399
1400 long do_sigreturn_v1(CPUState *env)
1401 {
1402         abi_ulong frame_addr;
1403         struct sigframe_v1 *frame;
1404         target_sigset_t set;
1405         sigset_t host_set;
1406         int i;
1407
1408         /*
1409          * Since we stacked the signal on a 64-bit boundary,
1410          * then 'sp' should be word aligned here.  If it's
1411          * not, then the user is trying to mess with us.
1412          */
1413         if (env->regs[13] & 7)
1414                 goto badframe;
1415
1416         frame_addr = env->regs[13];
1417         if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1418                 goto badframe;
1419
1420         if (__get_user(set.sig[0], &frame->sc.oldmask))
1421             goto badframe;
1422         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1423             if (__get_user(set.sig[i], &frame->extramask[i - 1]))
1424                 goto badframe;
1425         }
1426
1427         target_to_host_sigset_internal(&host_set, &set);
1428         sigprocmask(SIG_SETMASK, &host_set, NULL);
1429
1430         if (restore_sigcontext(env, &frame->sc))
1431                 goto badframe;
1432
1433 #if 0
1434         /* Send SIGTRAP if we're single-stepping */
1435         if (ptrace_cancel_bpt(current))
1436                 send_sig(SIGTRAP, current, 1);
1437 #endif
1438         unlock_user_struct(frame, frame_addr, 0);
1439         return env->regs[0];
1440
1441 badframe:
1442         unlock_user_struct(frame, frame_addr, 0);
1443         force_sig(SIGSEGV /* , current */);
1444         return 0;
1445 }
1446
1447 static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
1448                                  struct target_ucontext_v2 *uc)
1449 {
1450     sigset_t host_set;
1451
1452     target_to_host_sigset(&host_set, &uc->tuc_sigmask);
1453     sigprocmask(SIG_SETMASK, &host_set, NULL);
1454
1455     if (restore_sigcontext(env, &uc->tuc_mcontext))
1456         return 1;
1457
1458     if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1459         return 1;
1460
1461 #if 0
1462     /* Send SIGTRAP if we're single-stepping */
1463     if (ptrace_cancel_bpt(current))
1464             send_sig(SIGTRAP, current, 1);
1465 #endif
1466
1467     return 0;
1468 }
1469
1470 long do_sigreturn_v2(CPUState *env)
1471 {
1472         abi_ulong frame_addr;
1473         struct sigframe_v2 *frame;
1474
1475         /*
1476          * Since we stacked the signal on a 64-bit boundary,
1477          * then 'sp' should be word aligned here.  If it's
1478          * not, then the user is trying to mess with us.
1479          */
1480         if (env->regs[13] & 7)
1481                 goto badframe;
1482
1483         frame_addr = env->regs[13];
1484         if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1485                 goto badframe;
1486
1487         if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1488                 goto badframe;
1489
1490         unlock_user_struct(frame, frame_addr, 0);
1491         return env->regs[0];
1492
1493 badframe:
1494         unlock_user_struct(frame, frame_addr, 0);
1495         force_sig(SIGSEGV /* , current */);
1496         return 0;
1497 }
1498
1499 long do_sigreturn(CPUState *env)
1500 {
1501     if (get_osversion() >= 0x020612) {
1502         return do_sigreturn_v2(env);
1503     } else {
1504         return do_sigreturn_v1(env);
1505     }
1506 }
1507
1508 long do_rt_sigreturn_v1(CPUState *env)
1509 {
1510         abi_ulong frame_addr;
1511         struct rt_sigframe_v1 *frame;
1512         sigset_t host_set;
1513
1514         /*
1515          * Since we stacked the signal on a 64-bit boundary,
1516          * then 'sp' should be word aligned here.  If it's
1517          * not, then the user is trying to mess with us.
1518          */
1519         if (env->regs[13] & 7)
1520                 goto badframe;
1521
1522         frame_addr = env->regs[13];
1523         if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1524                 goto badframe;
1525
1526         target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);
1527         sigprocmask(SIG_SETMASK, &host_set, NULL);
1528
1529         if (restore_sigcontext(env, &frame->uc.tuc_mcontext))
1530                 goto badframe;
1531
1532         if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
1533                 goto badframe;
1534
1535 #if 0
1536         /* Send SIGTRAP if we're single-stepping */
1537         if (ptrace_cancel_bpt(current))
1538                 send_sig(SIGTRAP, current, 1);
1539 #endif
1540         unlock_user_struct(frame, frame_addr, 0);
1541         return env->regs[0];
1542
1543 badframe:
1544         unlock_user_struct(frame, frame_addr, 0);
1545         force_sig(SIGSEGV /* , current */);
1546         return 0;
1547 }
1548
1549 long do_rt_sigreturn_v2(CPUState *env)
1550 {
1551         abi_ulong frame_addr;
1552         struct rt_sigframe_v2 *frame;
1553
1554         /*
1555          * Since we stacked the signal on a 64-bit boundary,
1556          * then 'sp' should be word aligned here.  If it's
1557          * not, then the user is trying to mess with us.
1558          */
1559         if (env->regs[13] & 7)
1560                 goto badframe;
1561
1562         frame_addr = env->regs[13];
1563         if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
1564                 goto badframe;
1565
1566         if (do_sigframe_return_v2(env, frame_addr, &frame->uc))
1567                 goto badframe;
1568
1569         unlock_user_struct(frame, frame_addr, 0);
1570         return env->regs[0];
1571
1572 badframe:
1573         unlock_user_struct(frame, frame_addr, 0);
1574         force_sig(SIGSEGV /* , current */);
1575         return 0;
1576 }
1577
1578 long do_rt_sigreturn(CPUState *env)
1579 {
1580     if (get_osversion() >= 0x020612) {
1581         return do_rt_sigreturn_v2(env);
1582     } else {
1583         return do_rt_sigreturn_v1(env);
1584     }
1585 }
1586
1587 #elif defined(TARGET_SPARC)
1588
1589 #define __SUNOS_MAXWIN   31
1590
1591 /* This is what SunOS does, so shall I. */
1592 struct target_sigcontext {
1593         abi_ulong sigc_onstack;      /* state to restore */
1594
1595         abi_ulong sigc_mask;         /* sigmask to restore */
1596         abi_ulong sigc_sp;           /* stack pointer */
1597         abi_ulong sigc_pc;           /* program counter */
1598         abi_ulong sigc_npc;          /* next program counter */
1599         abi_ulong sigc_psr;          /* for condition codes etc */
1600         abi_ulong sigc_g1;           /* User uses these two registers */
1601         abi_ulong sigc_o0;           /* within the trampoline code. */
1602
1603         /* Now comes information regarding the users window set
1604          * at the time of the signal.
1605          */
1606         abi_ulong sigc_oswins;       /* outstanding windows */
1607
1608         /* stack ptrs for each regwin buf */
1609         char *sigc_spbuf[__SUNOS_MAXWIN];
1610
1611         /* Windows to restore after signal */
1612         struct {
1613                 abi_ulong locals[8];
1614                 abi_ulong ins[8];
1615         } sigc_wbuf[__SUNOS_MAXWIN];
1616 };
1617 /* A Sparc stack frame */
1618 struct sparc_stackf {
1619         abi_ulong locals[8];
1620         abi_ulong ins[6];
1621         struct sparc_stackf *fp;
1622         abi_ulong callers_pc;
1623         char *structptr;
1624         abi_ulong xargs[6];
1625         abi_ulong xxargs[1];
1626 };
1627
1628 typedef struct {
1629         struct {
1630                 abi_ulong psr;
1631                 abi_ulong pc;
1632                 abi_ulong npc;
1633                 abi_ulong y;
1634                 abi_ulong u_regs[16]; /* globals and ins */
1635         }               si_regs;
1636         int             si_mask;
1637 } __siginfo_t;
1638
1639 typedef struct {
1640         unsigned   long si_float_regs [32];
1641         unsigned   long si_fsr;
1642         unsigned   long si_fpqdepth;
1643         struct {
1644                 unsigned long *insn_addr;
1645                 unsigned long insn;
1646         } si_fpqueue [16];
1647 } qemu_siginfo_fpu_t;
1648
1649
1650 struct target_signal_frame {
1651         struct sparc_stackf     ss;
1652         __siginfo_t             info;
1653         abi_ulong               fpu_save;
1654         abi_ulong               insns[2] __attribute__ ((aligned (8)));
1655         abi_ulong               extramask[TARGET_NSIG_WORDS - 1];
1656         abi_ulong               extra_size; /* Should be 0 */
1657         qemu_siginfo_fpu_t      fpu_state;
1658 };
1659 struct target_rt_signal_frame {
1660         struct sparc_stackf     ss;
1661         siginfo_t               info;
1662         abi_ulong               regs[20];
1663         sigset_t                mask;
1664         abi_ulong               fpu_save;
1665         unsigned int            insns[2];
1666         stack_t                 stack;
1667         unsigned int            extra_size; /* Should be 0 */
1668         qemu_siginfo_fpu_t      fpu_state;
1669 };
1670
1671 #define UREG_O0        16
1672 #define UREG_O6        22
1673 #define UREG_I0        0
1674 #define UREG_I1        1
1675 #define UREG_I2        2
1676 #define UREG_I3        3
1677 #define UREG_I4        4
1678 #define UREG_I5        5
1679 #define UREG_I6        6
1680 #define UREG_I7        7
1681 #define UREG_L0        8
1682 #define UREG_FP        UREG_I6
1683 #define UREG_SP        UREG_O6
1684
1685 static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
1686                                      CPUState *env, unsigned long framesize)
1687 {
1688         abi_ulong sp;
1689
1690         sp = env->regwptr[UREG_FP];
1691
1692         /* This is the X/Open sanctioned signal stack switching.  */
1693         if (sa->sa_flags & TARGET_SA_ONSTACK) {
1694             if (!on_sig_stack(sp)
1695                 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1696                 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1697         }
1698         return sp - framesize;
1699 }
1700
1701 static int
1702 setup___siginfo(__siginfo_t *si, CPUState *env, abi_ulong mask)
1703 {
1704         int err = 0, i;
1705
1706         err |= __put_user(env->psr, &si->si_regs.psr);
1707         err |= __put_user(env->pc, &si->si_regs.pc);
1708         err |= __put_user(env->npc, &si->si_regs.npc);
1709         err |= __put_user(env->y, &si->si_regs.y);
1710         for (i=0; i < 8; i++) {
1711                 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1712         }
1713         for (i=0; i < 8; i++) {
1714                 err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1715         }
1716         err |= __put_user(mask, &si->si_mask);
1717         return err;
1718 }
1719
1720 #if 0
1721 static int
1722 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1723                  CPUState *env, unsigned long mask)
1724 {
1725         int err = 0;
1726
1727         err |= __put_user(mask, &sc->sigc_mask);
1728         err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
1729         err |= __put_user(env->pc, &sc->sigc_pc);
1730         err |= __put_user(env->npc, &sc->sigc_npc);
1731         err |= __put_user(env->psr, &sc->sigc_psr);
1732         err |= __put_user(env->gregs[1], &sc->sigc_g1);
1733         err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
1734
1735         return err;
1736 }
1737 #endif
1738 #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
1739
1740 static void setup_frame(int sig, struct target_sigaction *ka,
1741                         target_sigset_t *set, CPUState *env)
1742 {
1743         abi_ulong sf_addr;
1744         struct target_signal_frame *sf;
1745         int sigframe_size, err, i;
1746
1747         /* 1. Make sure everything is clean */
1748         //synchronize_user_stack();
1749
1750         sigframe_size = NF_ALIGNEDSZ;
1751         sf_addr = get_sigframe(ka, env, sigframe_size);
1752
1753         sf = lock_user(VERIFY_WRITE, sf_addr, 
1754                        sizeof(struct target_signal_frame), 0);
1755         if (!sf)
1756                 goto sigsegv;
1757                 
1758         //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1759 #if 0
1760         if (invalid_frame_pointer(sf, sigframe_size))
1761                 goto sigill_and_return;
1762 #endif
1763         /* 2. Save the current process state */
1764         err = setup___siginfo(&sf->info, env, set->sig[0]);
1765         err |= __put_user(0, &sf->extra_size);
1766
1767         //err |= save_fpu_state(regs, &sf->fpu_state);
1768         //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
1769
1770         err |= __put_user(set->sig[0], &sf->info.si_mask);
1771         for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
1772                 err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
1773         }
1774
1775         for (i = 0; i < 8; i++) {
1776                 err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1777         }
1778         for (i = 0; i < 8; i++) {
1779                 err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1780         }
1781         if (err)
1782                 goto sigsegv;
1783
1784         /* 3. signal handler back-trampoline and parameters */
1785         env->regwptr[UREG_FP] = sf_addr;
1786         env->regwptr[UREG_I0] = sig;
1787         env->regwptr[UREG_I1] = sf_addr + 
1788                 offsetof(struct target_signal_frame, info);
1789         env->regwptr[UREG_I2] = sf_addr + 
1790                 offsetof(struct target_signal_frame, info);
1791
1792         /* 4. signal handler */
1793         env->pc = ka->_sa_handler;
1794         env->npc = (env->pc + 4);
1795         /* 5. return to kernel instructions */
1796         if (ka->sa_restorer)
1797                 env->regwptr[UREG_I7] = ka->sa_restorer;
1798         else {
1799                 uint32_t val32;
1800
1801                 env->regwptr[UREG_I7] = sf_addr + 
1802                         offsetof(struct target_signal_frame, insns) - 2 * 4;
1803
1804                 /* mov __NR_sigreturn, %g1 */
1805                 val32 = 0x821020d8;
1806                 err |= __put_user(val32, &sf->insns[0]);
1807
1808                 /* t 0x10 */
1809                 val32 = 0x91d02010;
1810                 err |= __put_user(val32, &sf->insns[1]);
1811                 if (err)
1812                         goto sigsegv;
1813
1814                 /* Flush instruction space. */
1815                 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1816                 //              tb_flush(env);
1817         }
1818         unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1819         return;
1820 #if 0
1821 sigill_and_return:
1822         force_sig(TARGET_SIGILL);
1823 #endif
1824 sigsegv:
1825         //fprintf(stderr, "force_sig\n");
1826         unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1827         force_sig(TARGET_SIGSEGV);
1828 }
1829 static inline int
1830 restore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu)
1831 {
1832         int err;
1833 #if 0
1834 #ifdef CONFIG_SMP
1835         if (current->flags & PF_USEDFPU)
1836                 regs->psr &= ~PSR_EF;
1837 #else
1838         if (current == last_task_used_math) {
1839                 last_task_used_math = 0;
1840                 regs->psr &= ~PSR_EF;
1841         }
1842 #endif
1843         current->used_math = 1;
1844         current->flags &= ~PF_USEDFPU;
1845 #endif
1846 #if 0
1847         if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
1848                 return -EFAULT;
1849 #endif
1850
1851 #if 0
1852         /* XXX: incorrect */
1853         err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
1854                                      (sizeof(unsigned long) * 32));
1855 #endif
1856         err |= __get_user(env->fsr, &fpu->si_fsr);
1857 #if 0
1858         err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
1859         if (current->thread.fpqdepth != 0)
1860                 err |= __copy_from_user(&current->thread.fpqueue[0],
1861                                         &fpu->si_fpqueue[0],
1862                                         ((sizeof(unsigned long) +
1863                                         (sizeof(unsigned long *)))*16));
1864 #endif
1865         return err;
1866 }
1867
1868
1869 static void setup_rt_frame(int sig, struct target_sigaction *ka,
1870                            target_siginfo_t *info,
1871                            target_sigset_t *set, CPUState *env)
1872 {
1873     fprintf(stderr, "setup_rt_frame: not implemented\n");
1874 }
1875
1876 long do_sigreturn(CPUState *env)
1877 {
1878         abi_ulong sf_addr;
1879         struct target_signal_frame *sf;
1880         uint32_t up_psr, pc, npc;
1881         target_sigset_t set;
1882         sigset_t host_set;
1883         abi_ulong fpu_save_addr;
1884         int err, i;
1885
1886         sf_addr = env->regwptr[UREG_FP];
1887         if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1))
1888                 goto segv_and_exit;
1889 #if 0
1890         fprintf(stderr, "sigreturn\n");
1891         fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1892 #endif
1893         //cpu_dump_state(env, stderr, fprintf, 0);
1894
1895         /* 1. Make sure we are not getting garbage from the user */
1896
1897         if (sf_addr & 3)
1898                 goto segv_and_exit;
1899
1900         err = __get_user(pc,  &sf->info.si_regs.pc);
1901         err |= __get_user(npc, &sf->info.si_regs.npc);
1902
1903         if ((pc | npc) & 3)
1904                 goto segv_and_exit;
1905
1906         /* 2. Restore the state */
1907         err |= __get_user(up_psr, &sf->info.si_regs.psr);
1908
1909         /* User can only change condition codes and FPU enabling in %psr. */
1910         env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
1911                   | (env->psr & ~(PSR_ICC /* | PSR_EF */));
1912
1913         env->pc = pc;
1914         env->npc = npc;
1915         err |= __get_user(env->y, &sf->info.si_regs.y);
1916         for (i=0; i < 8; i++) {
1917                 err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
1918         }
1919         for (i=0; i < 8; i++) {
1920                 err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
1921         }
1922
1923         err |= __get_user(fpu_save_addr, &sf->fpu_save);
1924
1925         //if (fpu_save)
1926         //        err |= restore_fpu_state(env, fpu_save);
1927
1928         /* This is pretty much atomic, no amount locking would prevent
1929          * the races which exist anyways.
1930          */
1931         err |= __get_user(set.sig[0], &sf->info.si_mask);
1932         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
1933             err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
1934         }
1935
1936         target_to_host_sigset_internal(&host_set, &set);
1937         sigprocmask(SIG_SETMASK, &host_set, NULL);
1938
1939         if (err)
1940                 goto segv_and_exit;
1941         unlock_user_struct(sf, sf_addr, 0);
1942         return env->regwptr[0];
1943
1944 segv_and_exit:
1945         unlock_user_struct(sf, sf_addr, 0);
1946         force_sig(TARGET_SIGSEGV);
1947 }
1948
1949 long do_rt_sigreturn(CPUState *env)
1950 {
1951     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
1952     return -TARGET_ENOSYS;
1953 }
1954
1955 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1956 #define MC_TSTATE 0
1957 #define MC_PC 1
1958 #define MC_NPC 2
1959 #define MC_Y 3
1960 #define MC_G1 4
1961 #define MC_G2 5
1962 #define MC_G3 6
1963 #define MC_G4 7
1964 #define MC_G5 8
1965 #define MC_G6 9
1966 #define MC_G7 10
1967 #define MC_O0 11
1968 #define MC_O1 12
1969 #define MC_O2 13
1970 #define MC_O3 14
1971 #define MC_O4 15
1972 #define MC_O5 16
1973 #define MC_O6 17
1974 #define MC_O7 18
1975 #define MC_NGREG 19
1976
1977 typedef abi_ulong target_mc_greg_t;
1978 typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];
1979
1980 struct target_mc_fq {
1981     abi_ulong *mcfq_addr;
1982     uint32_t mcfq_insn;
1983 };
1984
1985 struct target_mc_fpu {
1986     union {
1987         uint32_t sregs[32];
1988         uint64_t dregs[32];
1989         //uint128_t qregs[16];
1990     } mcfpu_fregs;
1991     abi_ulong mcfpu_fsr;
1992     abi_ulong mcfpu_fprs;
1993     abi_ulong mcfpu_gsr;
1994     struct target_mc_fq *mcfpu_fq;
1995     unsigned char mcfpu_qcnt;
1996     unsigned char mcfpu_qentsz;
1997     unsigned char mcfpu_enab;
1998 };
1999 typedef struct target_mc_fpu target_mc_fpu_t;
2000
2001 typedef struct {
2002     target_mc_gregset_t mc_gregs;
2003     target_mc_greg_t mc_fp;
2004     target_mc_greg_t mc_i7;
2005     target_mc_fpu_t mc_fpregs;
2006 } target_mcontext_t;
2007
2008 struct target_ucontext {
2009     struct target_ucontext *uc_link;
2010     abi_ulong uc_flags;
2011     target_sigset_t uc_sigmask;
2012     target_mcontext_t uc_mcontext;
2013 };
2014
2015 /* A V9 register window */
2016 struct target_reg_window {
2017     abi_ulong locals[8];
2018     abi_ulong ins[8];
2019 };
2020
2021 #define TARGET_STACK_BIAS 2047
2022
2023 /* {set, get}context() needed for 64-bit SparcLinux userland. */
2024 void sparc64_set_context(CPUSPARCState *env)
2025 {
2026     abi_ulong ucp_addr;
2027     struct target_ucontext *ucp;
2028     target_mc_gregset_t *grp;
2029     abi_ulong pc, npc, tstate;
2030     abi_ulong fp, i7, w_addr;
2031     unsigned char fenab;
2032     int err;
2033     unsigned int i;
2034
2035     ucp_addr = env->regwptr[UREG_I0];
2036     if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
2037         goto do_sigsegv;
2038     grp  = &ucp->uc_mcontext.mc_gregs;
2039     err  = __get_user(pc, &((*grp)[MC_PC]));
2040     err |= __get_user(npc, &((*grp)[MC_NPC]));
2041     if (err || ((pc | npc) & 3))
2042         goto do_sigsegv;
2043     if (env->regwptr[UREG_I1]) {
2044         target_sigset_t target_set;
2045         sigset_t set;
2046
2047         if (TARGET_NSIG_WORDS == 1) {
2048             if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
2049                 goto do_sigsegv;
2050         } else {
2051             abi_ulong *src, *dst;
2052             src = ucp->uc_sigmask.sig;
2053             dst = target_set.sig;
2054             for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2055                  i++, dst++, src++)
2056                 err |= __get_user(*dst, src);
2057             if (err)
2058                 goto do_sigsegv;
2059         }
2060         target_to_host_sigset_internal(&set, &target_set);
2061         sigprocmask(SIG_SETMASK, &set, NULL);
2062     }
2063     env->pc = pc;
2064     env->npc = npc;
2065     err |= __get_user(env->y, &((*grp)[MC_Y]));
2066     err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
2067     env->asi = (tstate >> 24) & 0xff;
2068     PUT_CCR(env, tstate >> 32);
2069     PUT_CWP64(env, tstate & 0x1f);
2070     err |= __get_user(env->gregs[1], (&(*grp)[MC_G1]));
2071     err |= __get_user(env->gregs[2], (&(*grp)[MC_G2]));
2072     err |= __get_user(env->gregs[3], (&(*grp)[MC_G3]));
2073     err |= __get_user(env->gregs[4], (&(*grp)[MC_G4]));
2074     err |= __get_user(env->gregs[5], (&(*grp)[MC_G5]));
2075     err |= __get_user(env->gregs[6], (&(*grp)[MC_G6]));
2076     err |= __get_user(env->gregs[7], (&(*grp)[MC_G7]));
2077     err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0]));
2078     err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1]));
2079     err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2]));
2080     err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3]));
2081     err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4]));
2082     err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5]));
2083     err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6]));
2084     err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7]));
2085
2086     err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
2087     err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
2088
2089     w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2090     if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2091                  abi_ulong) != 0)
2092         goto do_sigsegv;
2093     if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2094                  abi_ulong) != 0)
2095         goto do_sigsegv;
2096     err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
2097     err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
2098     {
2099         uint32_t *src, *dst;
2100         src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2101         dst = env->fpr;
2102         /* XXX: check that the CPU storage is the same as user context */
2103         for (i = 0; i < 64; i++, dst++, src++)
2104             err |= __get_user(*dst, src);
2105     }
2106     err |= __get_user(env->fsr,
2107                       &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
2108     err |= __get_user(env->gsr,
2109                       &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
2110     if (err)
2111         goto do_sigsegv;
2112     unlock_user_struct(ucp, ucp_addr, 0);
2113     return;
2114  do_sigsegv:
2115     unlock_user_struct(ucp, ucp_addr, 0);
2116     force_sig(SIGSEGV);
2117 }
2118
2119 void sparc64_get_context(CPUSPARCState *env)
2120 {
2121     abi_ulong ucp_addr;
2122     struct target_ucontext *ucp;
2123     target_mc_gregset_t *grp;
2124     target_mcontext_t *mcp;
2125     abi_ulong fp, i7, w_addr;
2126     int err;
2127     unsigned int i;
2128     target_sigset_t target_set;
2129     sigset_t set;
2130
2131     ucp_addr = env->regwptr[UREG_I0];
2132     if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
2133         goto do_sigsegv;
2134     
2135     mcp = &ucp->uc_mcontext;
2136     grp = &mcp->mc_gregs;
2137
2138     /* Skip over the trap instruction, first. */
2139     env->pc = env->npc;
2140     env->npc += 4;
2141
2142     err = 0;
2143
2144     sigprocmask(0, NULL, &set);
2145     host_to_target_sigset_internal(&target_set, &set);
2146     if (TARGET_NSIG_WORDS == 1) {
2147         err |= __put_user(target_set.sig[0],
2148                           (abi_ulong *)&ucp->uc_sigmask);
2149     } else {
2150         abi_ulong *src, *dst;
2151         src = target_set.sig;
2152         dst = ucp->uc_sigmask.sig;
2153         for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
2154              i++, dst++, src++)
2155             err |= __put_user(*src, dst);
2156         if (err)
2157             goto do_sigsegv;
2158     }
2159
2160     /* XXX: tstate must be saved properly */
2161     //    err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
2162     err |= __put_user(env->pc, &((*grp)[MC_PC]));
2163     err |= __put_user(env->npc, &((*grp)[MC_NPC]));
2164     err |= __put_user(env->y, &((*grp)[MC_Y]));
2165     err |= __put_user(env->gregs[1], &((*grp)[MC_G1]));
2166     err |= __put_user(env->gregs[2], &((*grp)[MC_G2]));
2167     err |= __put_user(env->gregs[3], &((*grp)[MC_G3]));
2168     err |= __put_user(env->gregs[4], &((*grp)[MC_G4]));
2169     err |= __put_user(env->gregs[5], &((*grp)[MC_G5]));
2170     err |= __put_user(env->gregs[6], &((*grp)[MC_G6]));
2171     err |= __put_user(env->gregs[7], &((*grp)[MC_G7]));
2172     err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0]));
2173     err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1]));
2174     err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2]));
2175     err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3]));
2176     err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4]));
2177     err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5]));
2178     err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
2179     err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
2180
2181     w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
2182     fp = i7 = 0;
2183     if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 
2184                  abi_ulong) != 0)
2185         goto do_sigsegv;
2186     if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
2187                  abi_ulong) != 0)
2188         goto do_sigsegv;
2189     err |= __put_user(fp, &(mcp->mc_fp));
2190     err |= __put_user(i7, &(mcp->mc_i7));
2191
2192     {
2193         uint32_t *src, *dst;
2194         src = env->fpr;
2195         dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
2196         /* XXX: check that the CPU storage is the same as user context */
2197         for (i = 0; i < 64; i++, dst++, src++)
2198             err |= __put_user(*src, dst);
2199     }
2200     err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
2201     err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
2202     err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
2203
2204     if (err)
2205         goto do_sigsegv;
2206     unlock_user_struct(ucp, ucp_addr, 1);
2207     return;
2208  do_sigsegv:
2209     unlock_user_struct(ucp, ucp_addr, 1);
2210     force_sig(SIGSEGV);
2211 }
2212 #endif
2213 #elif defined(TARGET_ABI_MIPSN64)
2214
2215 # warning signal handling not implemented
2216
2217 static void setup_frame(int sig, struct target_sigaction *ka,
2218                         target_sigset_t *set, CPUState *env)
2219 {
2220     fprintf(stderr, "setup_frame: not implemented\n");
2221 }
2222
2223 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2224                            target_siginfo_t *info,
2225                            target_sigset_t *set, CPUState *env)
2226 {
2227     fprintf(stderr, "setup_rt_frame: not implemented\n");
2228 }
2229
2230 long do_sigreturn(CPUState *env)
2231 {
2232     fprintf(stderr, "do_sigreturn: not implemented\n");
2233     return -TARGET_ENOSYS;
2234 }
2235
2236 long do_rt_sigreturn(CPUState *env)
2237 {
2238     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2239     return -TARGET_ENOSYS;
2240 }
2241
2242 #elif defined(TARGET_ABI_MIPSN32)
2243
2244 # warning signal handling not implemented
2245
2246 static void setup_frame(int sig, struct target_sigaction *ka,
2247                         target_sigset_t *set, CPUState *env)
2248 {
2249     fprintf(stderr, "setup_frame: not implemented\n");
2250 }
2251
2252 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2253                            target_siginfo_t *info,
2254                            target_sigset_t *set, CPUState *env)
2255 {
2256     fprintf(stderr, "setup_rt_frame: not implemented\n");
2257 }
2258
2259 long do_sigreturn(CPUState *env)
2260 {
2261     fprintf(stderr, "do_sigreturn: not implemented\n");
2262     return -TARGET_ENOSYS;
2263 }
2264
2265 long do_rt_sigreturn(CPUState *env)
2266 {
2267     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2268     return -TARGET_ENOSYS;
2269 }
2270
2271 #elif defined(TARGET_ABI_MIPSO32)
2272
2273 struct target_sigcontext {
2274     uint32_t   sc_regmask;     /* Unused */
2275     uint32_t   sc_status;
2276     uint64_t   sc_pc;
2277     uint64_t   sc_regs[32];
2278     uint64_t   sc_fpregs[32];
2279     uint32_t   sc_ownedfp;     /* Unused */
2280     uint32_t   sc_fpc_csr;
2281     uint32_t   sc_fpc_eir;     /* Unused */
2282     uint32_t   sc_used_math;
2283     uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
2284     uint64_t   sc_mdhi;
2285     uint64_t   sc_mdlo;
2286     target_ulong   sc_hi1;         /* Was sc_cause */
2287     target_ulong   sc_lo1;         /* Was sc_badvaddr */
2288     target_ulong   sc_hi2;         /* Was sc_sigset[4] */
2289     target_ulong   sc_lo2;
2290     target_ulong   sc_hi3;
2291     target_ulong   sc_lo3;
2292 };
2293
2294 struct sigframe {
2295     uint32_t sf_ass[4];                 /* argument save space for o32 */
2296     uint32_t sf_code[2];                        /* signal trampoline */
2297     struct target_sigcontext sf_sc;
2298     target_sigset_t sf_mask;
2299 };
2300
2301 /* Install trampoline to jump back from signal handler */
2302 static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
2303 {
2304     int err;
2305
2306     /*
2307     * Set up the return code ...
2308     *
2309     *         li      v0, __NR__foo_sigreturn
2310     *         syscall
2311     */
2312
2313     err = __put_user(0x24020000 + syscall, tramp + 0);
2314     err |= __put_user(0x0000000c          , tramp + 1);
2315     /* flush_cache_sigtramp((unsigned long) tramp); */
2316     return err;
2317 }
2318
2319 static inline int
2320 setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2321 {
2322     int err = 0;
2323
2324     err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
2325
2326 #define save_gp_reg(i) do {                                             \
2327         err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);     \
2328     } while(0)
2329     __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
2330     save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
2331     save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
2332     save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
2333     save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
2334     save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
2335     save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
2336     save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
2337     save_gp_reg(31);
2338 #undef save_gp_reg
2339
2340     err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2341     err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2342
2343     /* Not used yet, but might be useful if we ever have DSP suppport */
2344 #if 0
2345     if (cpu_has_dsp) {
2346         err |= __put_user(mfhi1(), &sc->sc_hi1);
2347         err |= __put_user(mflo1(), &sc->sc_lo1);
2348         err |= __put_user(mfhi2(), &sc->sc_hi2);
2349         err |= __put_user(mflo2(), &sc->sc_lo2);
2350         err |= __put_user(mfhi3(), &sc->sc_hi3);
2351         err |= __put_user(mflo3(), &sc->sc_lo3);
2352         err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2353     }
2354     /* same with 64 bit */
2355 #ifdef CONFIG_64BIT
2356     err |= __put_user(regs->hi, &sc->sc_hi[0]);
2357     err |= __put_user(regs->lo, &sc->sc_lo[0]);
2358     if (cpu_has_dsp) {
2359         err |= __put_user(mfhi1(), &sc->sc_hi[1]);
2360         err |= __put_user(mflo1(), &sc->sc_lo[1]);
2361         err |= __put_user(mfhi2(), &sc->sc_hi[2]);
2362         err |= __put_user(mflo2(), &sc->sc_lo[2]);
2363         err |= __put_user(mfhi3(), &sc->sc_hi[3]);
2364         err |= __put_user(mflo3(), &sc->sc_lo[3]);
2365         err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
2366     }
2367 #endif
2368 #endif
2369
2370 #if 0
2371     err |= __put_user(!!used_math(), &sc->sc_used_math);
2372
2373     if (!used_math())
2374         goto out;
2375
2376     /*
2377     * Save FPU state to signal context.  Signal handler will "inherit"
2378     * current FPU state.
2379     */
2380     preempt_disable();
2381
2382     if (!is_fpu_owner()) {
2383         own_fpu();
2384         restore_fp(current);
2385     }
2386     err |= save_fp_context(sc);
2387
2388     preempt_enable();
2389     out:
2390 #endif
2391     return err;
2392 }
2393
2394 static inline int
2395 restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
2396 {
2397     int err = 0;
2398
2399     err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
2400
2401     err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
2402     err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
2403
2404 #define restore_gp_reg(i) do {                                                          \
2405         err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);             \
2406     } while(0)
2407     restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
2408     restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
2409     restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
2410     restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
2411     restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
2412     restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
2413     restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
2414     restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
2415     restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
2416     restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
2417     restore_gp_reg(31);
2418 #undef restore_gp_reg
2419
2420 #if 0
2421     if (cpu_has_dsp) {
2422         err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
2423         err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
2424         err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
2425         err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
2426         err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
2427         err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
2428         err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2429     }
2430 #ifdef CONFIG_64BIT
2431     err |= __get_user(regs->hi, &sc->sc_hi[0]);
2432     err |= __get_user(regs->lo, &sc->sc_lo[0]);
2433     if (cpu_has_dsp) {
2434         err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
2435         err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
2436         err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
2437         err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
2438         err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
2439         err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
2440         err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
2441     }
2442 #endif
2443
2444     err |= __get_user(used_math, &sc->sc_used_math);
2445     conditional_used_math(used_math);
2446
2447     preempt_disable();
2448
2449     if (used_math()) {
2450         /* restore fpu context if we have used it before */
2451         own_fpu();
2452         err |= restore_fp_context(sc);
2453     } else {
2454         /* signal handler may have used FPU.  Give it up. */
2455         lose_fpu();
2456     }
2457
2458     preempt_enable();
2459 #endif
2460     return err;
2461 }
2462 /*
2463  * Determine which stack to use..
2464  */
2465 static inline abi_ulong
2466 get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t frame_size)
2467 {
2468     unsigned long sp;
2469
2470     /* Default to using normal stack */
2471     sp = regs->active_tc.gpr[29];
2472
2473     /*
2474      * FPU emulator may have it's own trampoline active just
2475      * above the user stack, 16-bytes before the next lowest
2476      * 16 byte boundary.  Try to avoid trashing it.
2477      */
2478     sp -= 32;
2479
2480     /* This is the X/Open sanctioned signal stack switching.  */
2481     if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
2482         sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2483     }
2484
2485     return (sp - frame_size) & ~7;
2486 }
2487
2488 /* compare linux/arch/mips/kernel/signal.c:setup_frame() */
2489 static void setup_frame(int sig, struct target_sigaction * ka,
2490                         target_sigset_t *set, CPUState *regs)
2491 {
2492     struct sigframe *frame;
2493     abi_ulong frame_addr;
2494     int i;
2495
2496     frame_addr = get_sigframe(ka, regs, sizeof(*frame));
2497     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2498         goto give_sigsegv;
2499
2500     install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
2501
2502     if(setup_sigcontext(regs, &frame->sf_sc))
2503         goto give_sigsegv;
2504
2505     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2506         if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))
2507             goto give_sigsegv;
2508     }
2509
2510     /*
2511     * Arguments to signal handler:
2512     *
2513     *   a0 = signal number
2514     *   a1 = 0 (should be cause)
2515     *   a2 = pointer to struct sigcontext
2516     *
2517     * $25 and PC point to the signal handler, $29 points to the
2518     * struct sigframe.
2519     */
2520     regs->active_tc.gpr[ 4] = sig;
2521     regs->active_tc.gpr[ 5] = 0;
2522     regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
2523     regs->active_tc.gpr[29] = frame_addr;
2524     regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);
2525     /* The original kernel code sets CP0_EPC to the handler
2526     * since it returns to userland using eret
2527     * we cannot do this here, and we must set PC directly */
2528     regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
2529     unlock_user_struct(frame, frame_addr, 1);
2530     return;
2531
2532 give_sigsegv:
2533     unlock_user_struct(frame, frame_addr, 1);
2534     force_sig(TARGET_SIGSEGV/*, current*/);
2535     return;
2536 }
2537
2538 long do_sigreturn(CPUState *regs)
2539 {
2540     struct sigframe *frame;
2541     abi_ulong frame_addr;
2542     sigset_t blocked;
2543     target_sigset_t target_set;
2544     int i;
2545
2546 #if defined(DEBUG_SIGNAL)
2547     fprintf(stderr, "do_sigreturn\n");
2548 #endif
2549     frame_addr = regs->active_tc.gpr[29];
2550     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2551         goto badframe;
2552
2553     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2554         if(__get_user(target_set.sig[i], &frame->sf_mask.sig[i]))
2555             goto badframe;
2556     }
2557
2558     target_to_host_sigset_internal(&blocked, &target_set);
2559     sigprocmask(SIG_SETMASK, &blocked, NULL);
2560
2561     if (restore_sigcontext(regs, &frame->sf_sc))
2562         goto badframe;
2563
2564 #if 0
2565     /*
2566      * Don't let your children do this ...
2567      */
2568     __asm__ __volatile__(
2569         "move\t$29, %0\n\t"
2570         "j\tsyscall_exit"
2571         :/* no outputs */
2572         :"r" (&regs));
2573     /* Unreached */
2574 #endif
2575
2576     regs->active_tc.PC = regs->CP0_EPC;
2577     /* I am not sure this is right, but it seems to work
2578     * maybe a problem with nested signals ? */
2579     regs->CP0_EPC = 0;
2580     return 0;
2581
2582 badframe:
2583     force_sig(TARGET_SIGSEGV/*, current*/);
2584     return 0;
2585 }
2586
2587 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2588                            target_siginfo_t *info,
2589                            target_sigset_t *set, CPUState *env)
2590 {
2591     fprintf(stderr, "setup_rt_frame: not implemented\n");
2592 }
2593
2594 long do_rt_sigreturn(CPUState *env)
2595 {
2596     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
2597     return -TARGET_ENOSYS;
2598 }
2599
2600 #elif defined(TARGET_SH4)
2601
2602 /*
2603  * code and data structures from linux kernel:
2604  * include/asm-sh/sigcontext.h
2605  * arch/sh/kernel/signal.c
2606  */
2607
2608 struct target_sigcontext {
2609     target_ulong  oldmask;
2610
2611     /* CPU registers */
2612     target_ulong  sc_gregs[16];
2613     target_ulong  sc_pc;
2614     target_ulong  sc_pr;
2615     target_ulong  sc_sr;
2616     target_ulong  sc_gbr;
2617     target_ulong  sc_mach;
2618     target_ulong  sc_macl;
2619
2620     /* FPU registers */
2621     target_ulong  sc_fpregs[16];
2622     target_ulong  sc_xfpregs[16];
2623     unsigned int sc_fpscr;
2624     unsigned int sc_fpul;
2625     unsigned int sc_ownedfp;
2626 };
2627
2628 struct target_sigframe
2629 {
2630     struct target_sigcontext sc;
2631     target_ulong extramask[TARGET_NSIG_WORDS-1];
2632     uint16_t retcode[3];
2633 };
2634
2635
2636 struct target_ucontext {
2637     target_ulong uc_flags;
2638     struct target_ucontext *uc_link;
2639     target_stack_t uc_stack;
2640     struct target_sigcontext uc_mcontext;
2641     target_sigset_t uc_sigmask; /* mask last for extensibility */
2642 };
2643
2644 struct target_rt_sigframe
2645 {
2646     struct target_siginfo info;
2647     struct target_ucontext uc;
2648     uint16_t retcode[3];
2649 };
2650
2651
2652 #define MOVW(n)  (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
2653 #define TRAP_NOARG 0xc310         /* Syscall w/no args (NR in R3) SH3/4 */
2654
2655 static abi_ulong get_sigframe(struct target_sigaction *ka,
2656                          unsigned long sp, size_t frame_size)
2657 {
2658     if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
2659         sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
2660     }
2661
2662     return (sp - frame_size) & -8ul;
2663 }
2664
2665 static int setup_sigcontext(struct target_sigcontext *sc,
2666                             CPUState *regs, unsigned long mask)
2667 {
2668     int err = 0;
2669
2670 #define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
2671     COPY(gregs[0]); COPY(gregs[1]);
2672     COPY(gregs[2]); COPY(gregs[3]);
2673     COPY(gregs[4]); COPY(gregs[5]);
2674     COPY(gregs[6]); COPY(gregs[7]);
2675     COPY(gregs[8]); COPY(gregs[9]);
2676     COPY(gregs[10]); COPY(gregs[11]);
2677     COPY(gregs[12]); COPY(gregs[13]);
2678     COPY(gregs[14]); COPY(gregs[15]);
2679     COPY(gbr); COPY(mach);
2680     COPY(macl); COPY(pr);
2681     COPY(sr); COPY(pc);
2682 #undef COPY
2683
2684     /* todo: save FPU registers here */
2685
2686     /* non-iBCS2 extensions.. */
2687     err |= __put_user(mask, &sc->oldmask);
2688
2689     return err;
2690 }
2691
2692 static int restore_sigcontext(struct CPUState *regs,
2693                               struct target_sigcontext *sc)
2694 {
2695     unsigned int err = 0;
2696
2697 #define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
2698     COPY(gregs[1]);
2699     COPY(gregs[2]); COPY(gregs[3]);
2700     COPY(gregs[4]); COPY(gregs[5]);
2701     COPY(gregs[6]); COPY(gregs[7]);
2702     COPY(gregs[8]); COPY(gregs[9]);
2703     COPY(gregs[10]); COPY(gregs[11]);
2704     COPY(gregs[12]); COPY(gregs[13]);
2705     COPY(gregs[14]); COPY(gregs[15]);
2706     COPY(gbr); COPY(mach);
2707     COPY(macl); COPY(pr);
2708     COPY(sr); COPY(pc);
2709 #undef COPY
2710
2711     /* todo: restore FPU registers here */
2712
2713     regs->tra = -1;         /* disable syscall checks */
2714     return err;
2715 }
2716
2717 static void setup_frame(int sig, struct target_sigaction *ka,
2718                         target_sigset_t *set, CPUState *regs)
2719 {
2720     struct target_sigframe *frame;
2721     abi_ulong frame_addr;
2722     int i;
2723     int err = 0;
2724     int signal;
2725
2726     frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2727     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2728         goto give_sigsegv;
2729
2730     signal = current_exec_domain_sig(sig);
2731
2732     err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
2733
2734     for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
2735         err |= __put_user(set->sig[i + 1], &frame->extramask[i]);
2736     }
2737
2738     /* Set up to return from userspace.  If provided, use a stub
2739        already in userspace.  */
2740     if (ka->sa_flags & TARGET_SA_RESTORER) {
2741         regs->pr = (unsigned long) ka->sa_restorer;
2742     } else {
2743         /* Generate return code (system call to sigreturn) */
2744         err |= __put_user(MOVW(2), &frame->retcode[0]);
2745         err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2746         err |= __put_user((TARGET_NR_sigreturn), &frame->retcode[2]);
2747         regs->pr = (unsigned long) frame->retcode;
2748     }
2749
2750     if (err)
2751         goto give_sigsegv;
2752
2753     /* Set up registers for signal handler */
2754     regs->gregs[15] = (unsigned long) frame;
2755     regs->gregs[4] = signal; /* Arg for signal handler */
2756     regs->gregs[5] = 0;
2757     regs->gregs[6] = (unsigned long) &frame->sc;
2758     regs->pc = (unsigned long) ka->_sa_handler;
2759
2760     unlock_user_struct(frame, frame_addr, 1);
2761     return;
2762
2763 give_sigsegv:
2764     unlock_user_struct(frame, frame_addr, 1);
2765     force_sig(SIGSEGV);
2766 }
2767
2768 static void setup_rt_frame(int sig, struct target_sigaction *ka,
2769                            target_siginfo_t *info,
2770                            target_sigset_t *set, CPUState *regs)
2771 {
2772     struct target_rt_sigframe *frame;
2773     abi_ulong frame_addr;
2774     int i;
2775     int err = 0;
2776     int signal;
2777
2778     frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame));
2779     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2780         goto give_sigsegv;
2781
2782     signal = current_exec_domain_sig(sig);
2783
2784     err |= copy_siginfo_to_user(&frame->info, info);
2785
2786     /* Create the ucontext.  */
2787     err |= __put_user(0, &frame->uc.uc_flags);
2788     err |= __put_user(0, (unsigned long *)&frame->uc.uc_link);
2789     err |= __put_user((unsigned long)target_sigaltstack_used.ss_sp,
2790                       &frame->uc.uc_stack.ss_sp);
2791     err |= __put_user(sas_ss_flags(regs->gregs[15]),
2792                       &frame->uc.uc_stack.ss_flags);
2793     err |= __put_user(target_sigaltstack_used.ss_size,
2794                       &frame->uc.uc_stack.ss_size);
2795     err |= setup_sigcontext(&frame->uc.uc_mcontext,
2796                             regs, set->sig[0]);
2797     for(i = 0; i < TARGET_NSIG_WORDS; i++) {
2798         err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
2799     }
2800
2801     /* Set up to return from userspace.  If provided, use a stub
2802        already in userspace.  */
2803     if (ka->sa_flags & TARGET_SA_RESTORER) {
2804         regs->pr = (unsigned long) ka->sa_restorer;
2805     } else {
2806         /* Generate return code (system call to sigreturn) */
2807         err |= __put_user(MOVW(2), &frame->retcode[0]);
2808         err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
2809         err |= __put_user((TARGET_NR_rt_sigreturn), &frame->retcode[2]);
2810         regs->pr = (unsigned long) frame->retcode;
2811     }
2812
2813     if (err)
2814         goto give_sigsegv;
2815
2816     /* Set up registers for signal handler */
2817     regs->gregs[15] = (unsigned long) frame;
2818     regs->gregs[4] = signal; /* Arg for signal handler */
2819     regs->gregs[5] = (unsigned long) &frame->info;
2820     regs->gregs[6] = (unsigned long) &frame->uc;
2821     regs->pc = (unsigned long) ka->_sa_handler;
2822
2823     unlock_user_struct(frame, frame_addr, 1);
2824     return;
2825
2826 give_sigsegv:
2827     unlock_user_struct(frame, frame_addr, 1);
2828     force_sig(SIGSEGV);
2829 }
2830
2831 long do_sigreturn(CPUState *regs)
2832 {
2833     struct target_sigframe *frame;
2834     abi_ulong frame_addr;
2835     sigset_t blocked;
2836     target_sigset_t target_set;
2837     int i;
2838     int err = 0;
2839
2840 #if defined(DEBUG_SIGNAL)
2841     fprintf(stderr, "do_sigreturn\n");
2842 #endif
2843     frame_addr = regs->gregs[15];
2844     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2845         goto badframe;
2846
2847     err |= __get_user(target_set.sig[0], &frame->sc.oldmask);
2848     for(i = 1; i < TARGET_NSIG_WORDS; i++) {
2849         err |= (__get_user(target_set.sig[i], &frame->extramask[i - 1]));
2850     }
2851
2852     if (err)
2853         goto badframe;
2854
2855     target_to_host_sigset_internal(&blocked, &target_set);
2856     sigprocmask(SIG_SETMASK, &blocked, NULL);
2857
2858     if (restore_sigcontext(regs, &frame->sc))
2859         goto badframe;
2860
2861     unlock_user_struct(frame, frame_addr, 0);
2862     return regs->gregs[0];
2863
2864 badframe:
2865     unlock_user_struct(frame, frame_addr, 0);
2866     force_sig(TARGET_SIGSEGV);
2867     return 0;
2868 }
2869
2870 long do_rt_sigreturn(CPUState *regs)
2871 {
2872     struct target_rt_sigframe *frame;
2873     abi_ulong frame_addr;
2874     sigset_t blocked;
2875
2876 #if defined(DEBUG_SIGNAL)
2877     fprintf(stderr, "do_rt_sigreturn\n");
2878 #endif
2879     frame_addr = regs->gregs[15];
2880     if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
2881         goto badframe;
2882
2883     target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
2884     sigprocmask(SIG_SETMASK, &blocked, NULL);
2885
2886     if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
2887         goto badframe;
2888
2889     if (do_sigaltstack(frame_addr +
2890                        offsetof(struct target_rt_sigframe, uc.uc_stack),
2891                        0, get_sp_from_cpustate(regs)) == -EFAULT)
2892         goto badframe;
2893
2894     unlock_user_struct(frame, frame_addr, 0);
2895     return regs->gregs[0];
2896
2897 badframe:
2898     unlock_user_struct(frame, frame_addr, 0);
2899     force_sig(TARGET_SIGSEGV);
2900     return 0;
2901 }
2902 #elif defined(TARGET_CRIS)
2903
2904 struct target_sigcontext {
2905         struct target_pt_regs regs;  /* needs to be first */
2906         uint32_t oldmask;
2907         uint32_t usp;    /* usp before stacking this gunk on it */
2908 };
2909
2910 /* Signal frames. */
2911 struct target_signal_frame {
2912         struct target_sigcontext sc;
2913         uint32_t extramask[TARGET_NSIG_WORDS - 1];
2914         uint8_t retcode[8];       /* Trampoline code. */
2915 };
2916
2917 struct rt_signal_frame {
2918         struct siginfo *pinfo;
2919         void *puc;
2920         struct siginfo info;
2921         struct ucontext uc;
2922         uint8_t retcode[8];       /* Trampoline code. */
2923 };
2924
2925 static void setup_sigcontext(struct target_sigcontext *sc, CPUState *env)
2926 {
2927         __put_user(env->regs[0], &sc->regs.r0);
2928         __put_user(env->regs[1], &sc->regs.r1);
2929         __put_user(env->regs[2], &sc->regs.r2);
2930         __put_user(env->regs[3], &sc->regs.r3);
2931         __put_user(env->regs[4], &sc->regs.r4);
2932         __put_user(env->regs[5], &sc->regs.r5);
2933         __put_user(env->regs[6], &sc->regs.r6);
2934         __put_user(env->regs[7], &sc->regs.r7);
2935         __put_user(env->regs[8], &sc->regs.r8);
2936         __put_user(env->regs[9], &sc->regs.r9);
2937         __put_user(env->regs[10], &sc->regs.r10);
2938         __put_user(env->regs[11], &sc->regs.r11);
2939         __put_user(env->regs[12], &sc->regs.r12);
2940         __put_user(env->regs[13], &sc->regs.r13);
2941         __put_user(env->regs[14], &sc->usp);
2942         __put_user(env->regs[15], &sc->regs.acr);
2943         __put_user(env->pregs[PR_MOF], &sc->regs.mof);
2944         __put_user(env->pregs[PR_SRP], &sc->regs.srp);
2945         __put_user(env->pc, &sc->regs.erp);
2946 }
2947
2948 static void restore_sigcontext(struct target_sigcontext *sc, CPUState *env)
2949 {
2950         __get_user(env->regs[0], &sc->regs.r0);
2951         __get_user(env->regs[1], &sc->regs.r1);
2952         __get_user(env->regs[2], &sc->regs.r2);
2953         __get_user(env->regs[3], &sc->regs.r3);
2954         __get_user(env->regs[4], &sc->regs.r4);
2955         __get_user(env->regs[5], &sc->regs.r5);
2956         __get_user(env->regs[6], &sc->regs.r6);
2957         __get_user(env->regs[7], &sc->regs.r7);
2958         __get_user(env->regs[8], &sc->regs.r8);
2959         __get_user(env->regs[9], &sc->regs.r9);
2960         __get_user(env->regs[10], &sc->regs.r10);
2961         __get_user(env->regs[11], &sc->regs.r11);
2962         __get_user(env->regs[12], &sc->regs.r12);
2963         __get_user(env->regs[13], &sc->regs.r13);
2964         __get_user(env->regs[14], &sc->usp);
2965         __get_user(env->regs[15], &sc->regs.acr);
2966         __get_user(env->pregs[PR_MOF], &sc->regs.mof);
2967         __get_user(env->pregs[PR_SRP], &sc->regs.srp);
2968         __get_user(env->pc, &sc->regs.erp);
2969 }
2970
2971 static abi_ulong get_sigframe(CPUState *env, int framesize)
2972 {
2973         abi_ulong sp;
2974         /* Align the stack downwards to 4.  */
2975         sp = (env->regs[R_SP] & ~3);
2976         return sp - framesize;
2977 }
2978
2979 static void setup_frame(int sig, struct target_sigaction *ka,
2980                         target_sigset_t *set, CPUState *env)
2981 {
2982         struct target_signal_frame *frame;
2983         abi_ulong frame_addr;
2984         int err = 0;
2985         int i;
2986
2987         frame_addr = get_sigframe(env, sizeof *frame);
2988         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
2989                 goto badframe;
2990
2991         /*
2992          * The CRIS signal return trampoline. A real linux/CRIS kernel doesn't
2993          * use this trampoline anymore but it sets it up for GDB.
2994          * In QEMU, using the trampoline simplifies things a bit so we use it.
2995          *
2996          * This is movu.w __NR_sigreturn, r9; break 13;
2997          */
2998         err |= __put_user(0x9c5f, frame->retcode+0);
2999         err |= __put_user(TARGET_NR_sigreturn, 
3000                           frame->retcode+2);
3001         err |= __put_user(0xe93d, frame->retcode+4);
3002
3003         /* Save the mask.  */
3004         err |= __put_user(set->sig[0], &frame->sc.oldmask);
3005         if (err)
3006                 goto badframe;
3007
3008         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3009                 if (__put_user(set->sig[i], &frame->extramask[i - 1]))
3010                         goto badframe;
3011         }
3012
3013         setup_sigcontext(&frame->sc, env);
3014
3015         /* Move the stack and setup the arguments for the handler.  */
3016         env->regs[R_SP] = (uint32_t) (unsigned long) frame;
3017         env->regs[10] = sig;
3018         env->pc = (unsigned long) ka->_sa_handler;
3019         /* Link SRP so the guest returns through the trampoline.  */
3020         env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
3021
3022         unlock_user_struct(frame, frame_addr, 1);
3023         return;
3024   badframe:
3025         unlock_user_struct(frame, frame_addr, 1);
3026         force_sig(TARGET_SIGSEGV);
3027 }
3028
3029 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3030                            target_siginfo_t *info,
3031                            target_sigset_t *set, CPUState *env)
3032 {
3033     fprintf(stderr, "CRIS setup_rt_frame: not implemented\n");
3034 }
3035
3036 long do_sigreturn(CPUState *env)
3037 {
3038         struct target_signal_frame *frame;
3039         abi_ulong frame_addr;
3040         target_sigset_t target_set;
3041         sigset_t set;
3042         int i;
3043
3044         frame_addr = env->regs[R_SP];
3045         /* Make sure the guest isn't playing games.  */
3046         if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
3047                 goto badframe;
3048
3049         /* Restore blocked signals */
3050         if (__get_user(target_set.sig[0], &frame->sc.oldmask))
3051                 goto badframe;
3052         for(i = 1; i < TARGET_NSIG_WORDS; i++) {
3053                 if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))
3054                         goto badframe;
3055         }
3056         target_to_host_sigset_internal(&set, &target_set);
3057         sigprocmask(SIG_SETMASK, &set, NULL);
3058
3059         restore_sigcontext(&frame->sc, env);
3060         unlock_user_struct(frame, frame_addr, 0);
3061         return env->regs[10];
3062   badframe:
3063         unlock_user_struct(frame, frame_addr, 0);
3064         force_sig(TARGET_SIGSEGV);
3065 }
3066
3067 long do_rt_sigreturn(CPUState *env)
3068 {
3069     fprintf(stderr, "CRIS do_rt_sigreturn: not implemented\n");
3070     return -TARGET_ENOSYS;
3071 }
3072
3073 #else
3074
3075 static void setup_frame(int sig, struct target_sigaction *ka,
3076                         target_sigset_t *set, CPUState *env)
3077 {
3078     fprintf(stderr, "setup_frame: not implemented\n");
3079 }
3080
3081 static void setup_rt_frame(int sig, struct target_sigaction *ka,
3082                            target_siginfo_t *info,
3083                            target_sigset_t *set, CPUState *env)
3084 {
3085     fprintf(stderr, "setup_rt_frame: not implemented\n");
3086 }
3087
3088 long do_sigreturn(CPUState *env)
3089 {
3090     fprintf(stderr, "do_sigreturn: not implemented\n");
3091     return -TARGET_ENOSYS;
3092 }
3093
3094 long do_rt_sigreturn(CPUState *env)
3095 {
3096     fprintf(stderr, "do_rt_sigreturn: not implemented\n");
3097     return -TARGET_ENOSYS;
3098 }
3099
3100 #endif
3101
3102 void process_pending_signals(CPUState *cpu_env)
3103 {
3104     int sig;
3105     abi_ulong handler;
3106     sigset_t set, old_set;
3107     target_sigset_t target_old_set;
3108     struct emulated_sigtable *k;
3109     struct target_sigaction *sa;
3110     struct sigqueue *q;
3111     TaskState *ts = cpu_env->opaque;
3112
3113     if (!ts->signal_pending)
3114         return;
3115
3116     /* FIXME: This is not threadsafe.  */
3117     k = ts->sigtab;
3118     for(sig = 1; sig <= TARGET_NSIG; sig++) {
3119         if (k->pending)
3120             goto handle_signal;
3121         k++;
3122     }
3123     /* if no signal is pending, just return */
3124     ts->signal_pending = 0;
3125     return;
3126
3127  handle_signal:
3128 #ifdef DEBUG_SIGNAL
3129     fprintf(stderr, "qemu: process signal %d\n", sig);
3130 #endif
3131     /* dequeue signal */
3132     q = k->first;
3133     k->first = q->next;
3134     if (!k->first)
3135         k->pending = 0;
3136
3137     sig = gdb_handlesig (cpu_env, sig);
3138     if (!sig) {
3139         sa = NULL;
3140         handler = TARGET_SIG_IGN;
3141     } else {
3142         sa = &sigact_table[sig - 1];
3143         handler = sa->_sa_handler;
3144     }
3145
3146     if (handler == TARGET_SIG_DFL) {
3147         /* default handler : ignore some signal. The other are job control or fatal */
3148         if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
3149             kill(getpid(),SIGSTOP);
3150         } else if (sig != TARGET_SIGCHLD &&
3151                    sig != TARGET_SIGURG &&
3152                    sig != TARGET_SIGWINCH &&
3153                    sig != TARGET_SIGCONT) {
3154             force_sig(sig);
3155         }
3156     } else if (handler == TARGET_SIG_IGN) {
3157         /* ignore sig */
3158     } else if (handler == TARGET_SIG_ERR) {
3159         force_sig(sig);
3160     } else {
3161         /* compute the blocked signals during the handler execution */
3162         target_to_host_sigset(&set, &sa->sa_mask);
3163         /* SA_NODEFER indicates that the current signal should not be
3164            blocked during the handler */
3165         if (!(sa->sa_flags & TARGET_SA_NODEFER))
3166             sigaddset(&set, target_to_host_signal(sig));
3167
3168         /* block signals in the handler using Linux */
3169         sigprocmask(SIG_BLOCK, &set, &old_set);
3170         /* save the previous blocked signal state to restore it at the
3171            end of the signal execution (see do_sigreturn) */
3172         host_to_target_sigset_internal(&target_old_set, &old_set);
3173
3174         /* if the CPU is in VM86 mode, we restore the 32 bit values */
3175 #if defined(TARGET_I386) && !defined(TARGET_X86_64)
3176         {
3177             CPUX86State *env = cpu_env;
3178             if (env->eflags & VM_MASK)
3179                 save_v86_state(env);
3180         }
3181 #endif
3182         /* prepare the stack frame of the virtual CPU */
3183         if (sa->sa_flags & TARGET_SA_SIGINFO)
3184             setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
3185         else
3186             setup_frame(sig, sa, &target_old_set, cpu_env);
3187         if (sa->sa_flags & TARGET_SA_RESETHAND)
3188             sa->_sa_handler = TARGET_SIG_DFL;
3189     }
3190     if (q != &k->info)
3191         free_sigqueue(cpu_env, q);
3192 }