Annotation of qemu/linux-user/signal.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.