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