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