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